aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_pcmcia.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/ata/pata_pcmcia.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/ata/pata_pcmcia.c')
-rw-r--r--drivers/ata/pata_pcmcia.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 4b8bd2021a9c..20982065a494 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
152struct pcmcia_config_check { 152struct 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
160static int pcmcia_check_one_config(struct pcmcia_device *pdev, 159static 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 }
206next_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 */