aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-cs.c')
-rw-r--r--drivers/ide/ide-cs.c158
1 files changed, 30 insertions, 128 deletions
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c
index 2a4cb9c18f01..d2f3db3cf3ed 100644
--- a/drivers/ide/ide-cs.c
+++ b/drivers/ide/ide-cs.c
@@ -43,7 +43,6 @@
43#include <asm/io.h> 43#include <asm/io.h>
44#include <asm/system.h> 44#include <asm/system.h>
45 45
46#include <pcmcia/cs.h>
47#include <pcmcia/cistpl.h> 46#include <pcmcia/cistpl.h>
48#include <pcmcia/ds.h> 47#include <pcmcia/ds.h>
49#include <pcmcia/cisreg.h> 48#include <pcmcia/cisreg.h>
@@ -72,17 +71,6 @@ static int ide_config(struct pcmcia_device *);
72 71
73static void ide_detach(struct pcmcia_device *p_dev); 72static void ide_detach(struct pcmcia_device *p_dev);
74 73
75
76
77
78/*======================================================================
79
80 ide_attach() creates an "instance" of the driver, allocating
81 local data structures for one device. The device is registered
82 with Card Services.
83
84======================================================================*/
85
86static int ide_probe(struct pcmcia_device *link) 74static int ide_probe(struct pcmcia_device *link)
87{ 75{
88 ide_info_t *info; 76 ide_info_t *info;
@@ -97,23 +85,12 @@ static int ide_probe(struct pcmcia_device *link)
97 info->p_dev = link; 85 info->p_dev = link;
98 link->priv = info; 86 link->priv = info;
99 87
100 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; 88 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO |
101 link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; 89 CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
102 link->conf.Attributes = CONF_ENABLE_IRQ;
103 link->conf.IntType = INT_MEMORY_AND_IO;
104 90
105 return ide_config(link); 91 return ide_config(link);
106} /* ide_attach */ 92} /* ide_attach */
107 93
108/*======================================================================
109
110 This deletes a driver "instance". The device is de-registered
111 with Card Services. If it has been released, all local data
112 structures are freed. Otherwise, the structures will be freed
113 when the device is released.
114
115======================================================================*/
116
117static void ide_detach(struct pcmcia_device *link) 94static void ide_detach(struct pcmcia_device *link)
118{ 95{
119 ide_info_t *info = link->priv; 96 ide_info_t *info = link->priv;
@@ -187,79 +164,31 @@ out_release:
187 return NULL; 164 return NULL;
188} 165}
189 166
190/*====================================================================== 167static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data)
191
192 ide_config() is scheduled to run after a CARD_INSERTION event
193 is received, to configure the PCMCIA socket, and to make the
194 ide device available to the system.
195
196======================================================================*/
197
198struct pcmcia_config_check {
199 unsigned long ctl_base;
200 int skip_vcc;
201 int is_kme;
202};
203
204static int pcmcia_check_one_config(struct pcmcia_device *pdev,
205 cistpl_cftable_entry_t *cfg,
206 cistpl_cftable_entry_t *dflt,
207 unsigned int vcc,
208 void *priv_data)
209{ 168{
210 struct pcmcia_config_check *stk = priv_data; 169 int *is_kme = priv_data;
211
212 /* Check for matching Vcc, unless we're desperate */
213 if (!stk->skip_vcc) {
214 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
215 if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
216 return -ENODEV;
217 } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
218 if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
219 return -ENODEV;
220 }
221 }
222 170
223 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) 171 if (!(pdev->resource[0]->flags & IO_DATA_PATH_WIDTH_8)) {
224 pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; 172 pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
225 else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) 173 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
226 pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; 174 }
227 175 pdev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
228 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { 176 pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
229 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; 177
230 pdev->io_lines = io->flags & CISTPL_IO_LINES_MASK; 178 if (pdev->resource[1]->end) {
231 179 pdev->resource[0]->end = 8;
232 pdev->conf.ConfigIndex = cfg->index; 180 pdev->resource[1]->end = (*is_kme) ? 2 : 1;
233 pdev->resource[0]->start = io->win[0].base; 181 } else {
234 if (!(io->flags & CISTPL_IO_16BIT)) { 182 if (pdev->resource[0]->end < 16)
235 pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
236 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
237 }
238 if (io->nwin == 2) {
239 pdev->resource[0]->end = 8;
240 pdev->resource[1]->start = io->win[1].base;
241 pdev->resource[1]->end = (stk->is_kme) ? 2 : 1;
242 if (pcmcia_request_io(pdev) != 0)
243 return -ENODEV;
244 stk->ctl_base = pdev->resource[1]->start;
245 } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
246 pdev->resource[0]->end = io->win[0].len;
247 pdev->resource[1]->end = 0;
248 if (pcmcia_request_io(pdev) != 0)
249 return -ENODEV;
250 stk->ctl_base = pdev->resource[0]->start + 0x0e;
251 } else
252 return -ENODEV; 183 return -ENODEV;
253 /* If we've got this far, we're done */
254 return 0;
255 } 184 }
256 return -ENODEV; 185
186 return pcmcia_request_io(pdev);
257} 187}
258 188
259static int ide_config(struct pcmcia_device *link) 189static int ide_config(struct pcmcia_device *link)
260{ 190{
261 ide_info_t *info = link->priv; 191 ide_info_t *info = link->priv;
262 struct pcmcia_config_check *stk = NULL;
263 int ret = 0, is_kme = 0; 192 int ret = 0, is_kme = 0;
264 unsigned long io_base, ctl_base; 193 unsigned long io_base, ctl_base;
265 struct ide_host *host; 194 struct ide_host *host;
@@ -270,23 +199,21 @@ static int ide_config(struct pcmcia_device *link)
270 ((link->card_id == PRODID_KME_KXLC005_A) || 199 ((link->card_id == PRODID_KME_KXLC005_A) ||
271 (link->card_id == PRODID_KME_KXLC005_B))); 200 (link->card_id == PRODID_KME_KXLC005_B)));
272 201
273 stk = kzalloc(sizeof(*stk), GFP_KERNEL); 202 if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme)) {
274 if (!stk) 203 link->config_flags &= ~CONF_AUTO_CHECK_VCC;
275 goto err_mem; 204 if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme))
276 stk->is_kme = is_kme;
277 stk->skip_vcc = io_base = ctl_base = 0;
278
279 if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) {
280 stk->skip_vcc = 1;
281 if (pcmcia_loop_config(link, pcmcia_check_one_config, stk))
282 goto failed; /* No suitable config found */ 205 goto failed; /* No suitable config found */
283 } 206 }
284 io_base = link->resource[0]->start; 207 io_base = link->resource[0]->start;
285 ctl_base = stk->ctl_base; 208 if (link->resource[1]->end)
209 ctl_base = link->resource[1]->start;
210 else
211 ctl_base = link->resource[0]->start + 0x0e;
286 212
287 if (!link->irq) 213 if (!link->irq)
288 goto failed; 214 goto failed;
289 ret = pcmcia_request_configuration(link, &link->conf); 215
216 ret = pcmcia_enable_device(link);
290 if (ret) 217 if (ret)
291 goto failed; 218 goto failed;
292 219
@@ -311,29 +238,15 @@ static int ide_config(struct pcmcia_device *link)
311 info->host = host; 238 info->host = host;
312 dev_info(&link->dev, "ide-cs: hd%c: Vpp = %d.%d\n", 239 dev_info(&link->dev, "ide-cs: hd%c: Vpp = %d.%d\n",
313 'a' + host->ports[0]->index * 2, 240 'a' + host->ports[0]->index * 2,
314 link->conf.Vpp / 10, link->conf.Vpp % 10); 241 link->vpp / 10, link->vpp % 10);
315 242
316 kfree(stk);
317 return 0; 243 return 0;
318 244
319err_mem:
320 printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
321 goto failed;
322
323failed: 245failed:
324 kfree(stk);
325 ide_release(link); 246 ide_release(link);
326 return -ENODEV; 247 return -ENODEV;
327} /* ide_config */ 248} /* ide_config */
328 249
329/*======================================================================
330
331 After a card is removed, ide_release() will unregister the net
332 device, and release the PCMCIA configuration. If the device is
333 still open, this will be postponed until it is closed.
334
335======================================================================*/
336
337static void ide_release(struct pcmcia_device *link) 250static void ide_release(struct pcmcia_device *link)
338{ 251{
339 ide_info_t *info = link->priv; 252 ide_info_t *info = link->priv;
@@ -359,16 +272,7 @@ static void ide_release(struct pcmcia_device *link)
359} /* ide_release */ 272} /* ide_release */
360 273
361 274
362/*====================================================================== 275static const struct pcmcia_device_id ide_ids[] = {
363
364 The card status event handler. Mostly, this schedules other
365 stuff to run after an event is received. A CARD_REMOVAL event
366 also sets some flags to discourage the ide drivers from
367 talking to the ports.
368
369======================================================================*/
370
371static struct pcmcia_device_id ide_ids[] = {
372 PCMCIA_DEVICE_FUNC_ID(4), 276 PCMCIA_DEVICE_FUNC_ID(4),
373 PCMCIA_DEVICE_MANF_CARD(0x0000, 0x0000), /* Corsair */ 277 PCMCIA_DEVICE_MANF_CARD(0x0000, 0x0000), /* Corsair */
374 PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */ 278 PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */
@@ -440,9 +344,7 @@ MODULE_DEVICE_TABLE(pcmcia, ide_ids);
440 344
441static struct pcmcia_driver ide_cs_driver = { 345static struct pcmcia_driver ide_cs_driver = {
442 .owner = THIS_MODULE, 346 .owner = THIS_MODULE,
443 .drv = { 347 .name = "ide-cs",
444 .name = "ide-cs",
445 },
446 .probe = ide_probe, 348 .probe = ide_probe,
447 .remove = ide_detach, 349 .remove = ide_detach,
448 .id_table = ide_ids, 350 .id_table = ide_ids,