diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2006-01-05 18:27:16 -0500 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2006-01-05 18:27:16 -0500 |
commit | efe3cd105f2a19e72ce9280bb22c7c80752e4314 (patch) | |
tree | 3caa16ce9bb50ca15aeb757621be283abd389870 /sound/pcmcia | |
parent | f8cfa618dccbdc6dab5297f75779566a388a98fd (diff) |
[PATCH] pcmcia: fix sound drivers
Update the PCMCIA sound drivers to handle the recent changes to the PCMCIA
core. A part of this merge was done by Takashi Iwai <tiwai@suse.de>.
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'sound/pcmcia')
-rw-r--r-- | sound/pcmcia/pdaudiocf/pdaudiocf.c | 154 | ||||
-rw-r--r-- | sound/pcmcia/vx/vxpocket.c | 155 |
2 files changed, 115 insertions, 194 deletions
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index a7cd2d4df75..77caf43a310 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c | |||
@@ -52,16 +52,13 @@ MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard."); | |||
52 | /* | 52 | /* |
53 | */ | 53 | */ |
54 | 54 | ||
55 | static dev_info_t dev_info = "snd-pdaudiocf"; | ||
56 | static struct snd_card *card_list[SNDRV_CARDS]; | 55 | static struct snd_card *card_list[SNDRV_CARDS]; |
57 | static dev_link_t *dev_list; | ||
58 | 56 | ||
59 | /* | 57 | /* |
60 | * prototypes | 58 | * prototypes |
61 | */ | 59 | */ |
62 | static void pdacf_config(dev_link_t *link); | 60 | static void pdacf_config(dev_link_t *link); |
63 | static int pdacf_event(event_t event, int priority, event_callback_args_t *args); | 61 | static void snd_pdacf_detach(struct pcmcia_device *p_dev); |
64 | static void snd_pdacf_detach(dev_link_t *link); | ||
65 | 62 | ||
66 | static void pdacf_release(dev_link_t *link) | 63 | static void pdacf_release(dev_link_t *link) |
67 | { | 64 | { |
@@ -83,10 +80,6 @@ static int snd_pdacf_free(struct snd_pdacf *pdacf) | |||
83 | 80 | ||
84 | pdacf_release(link); | 81 | pdacf_release(link); |
85 | 82 | ||
86 | /* Break the link with Card Services */ | ||
87 | if (link->handle) | ||
88 | pcmcia_deregister_client(link->handle); | ||
89 | |||
90 | card_list[pdacf->index] = NULL; | 83 | card_list[pdacf->index] = NULL; |
91 | pdacf->card = NULL; | 84 | pdacf->card = NULL; |
92 | 85 | ||
@@ -103,11 +96,10 @@ static int snd_pdacf_dev_free(struct snd_device *device) | |||
103 | /* | 96 | /* |
104 | * snd_pdacf_attach - attach callback for cs | 97 | * snd_pdacf_attach - attach callback for cs |
105 | */ | 98 | */ |
106 | static dev_link_t *snd_pdacf_attach(void) | 99 | static int snd_pdacf_attach(struct pcmcia_device *p_dev) |
107 | { | 100 | { |
108 | client_reg_t client_reg; /* Register with cardmgr */ | 101 | int i; |
109 | dev_link_t *link; /* Info for cardmgr */ | 102 | dev_link_t *link; /* Info for cardmgr */ |
110 | int i, ret; | ||
111 | struct snd_pdacf *pdacf; | 103 | struct snd_pdacf *pdacf; |
112 | struct snd_card *card; | 104 | struct snd_card *card; |
113 | static struct snd_device_ops ops = { | 105 | static struct snd_device_ops ops = { |
@@ -122,26 +114,26 @@ static dev_link_t *snd_pdacf_attach(void) | |||
122 | } | 114 | } |
123 | if (i >= SNDRV_CARDS) { | 115 | if (i >= SNDRV_CARDS) { |
124 | snd_printk(KERN_ERR "pdacf: too many cards found\n"); | 116 | snd_printk(KERN_ERR "pdacf: too many cards found\n"); |
125 | return NULL; | 117 | return -EINVAL; |
126 | } | 118 | } |
127 | if (! enable[i]) | 119 | if (! enable[i]) |
128 | return NULL; /* disabled explicitly */ | 120 | return -ENODEV; /* disabled explicitly */ |
129 | 121 | ||
130 | /* ok, create a card instance */ | 122 | /* ok, create a card instance */ |
131 | card = snd_card_new(index[i], id[i], THIS_MODULE, 0); | 123 | card = snd_card_new(index[i], id[i], THIS_MODULE, 0); |
132 | if (card == NULL) { | 124 | if (card == NULL) { |
133 | snd_printk(KERN_ERR "pdacf: cannot create a card instance\n"); | 125 | snd_printk(KERN_ERR "pdacf: cannot create a card instance\n"); |
134 | return NULL; | 126 | return -ENOMEM; |
135 | } | 127 | } |
136 | 128 | ||
137 | pdacf = snd_pdacf_create(card); | 129 | pdacf = snd_pdacf_create(card); |
138 | if (! pdacf) | 130 | if (! pdacf) |
139 | return NULL; | 131 | return -EIO; |
140 | 132 | ||
141 | if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops) < 0) { | 133 | if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops) < 0) { |
142 | kfree(pdacf); | 134 | kfree(pdacf); |
143 | snd_card_free(card); | 135 | snd_card_free(card); |
144 | return NULL; | 136 | return -ENODEV; |
145 | } | 137 | } |
146 | 138 | ||
147 | pdacf->index = i; | 139 | pdacf->index = i; |
@@ -165,22 +157,12 @@ static dev_link_t *snd_pdacf_attach(void) | |||
165 | link->conf.Present = PRESENT_OPTION; | 157 | link->conf.Present = PRESENT_OPTION; |
166 | 158 | ||
167 | /* Chain drivers */ | 159 | /* Chain drivers */ |
168 | link->next = dev_list; | 160 | link->next = NULL; |
169 | dev_list = link; | ||
170 | |||
171 | /* Register with Card Services */ | ||
172 | client_reg.dev_info = &dev_info; | ||
173 | client_reg.Version = 0x0210; | ||
174 | client_reg.event_callback_args.client_data = link; | ||
175 | |||
176 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
177 | if (ret != CS_SUCCESS) { | ||
178 | cs_error(link->handle, RegisterClient, ret); | ||
179 | snd_pdacf_detach(link); | ||
180 | return NULL; | ||
181 | } | ||
182 | 161 | ||
183 | return link; | 162 | link->handle = p_dev; |
163 | pdacf_config(link); | ||
164 | |||
165 | return 0; | ||
184 | } | 166 | } |
185 | 167 | ||
186 | 168 | ||
@@ -227,21 +209,13 @@ static int snd_pdacf_assign_resources(struct snd_pdacf *pdacf, int port, int irq | |||
227 | /* | 209 | /* |
228 | * snd_pdacf_detach - detach callback for cs | 210 | * snd_pdacf_detach - detach callback for cs |
229 | */ | 211 | */ |
230 | static void snd_pdacf_detach(dev_link_t *link) | 212 | static void snd_pdacf_detach(struct pcmcia_device *p_dev) |
231 | { | 213 | { |
214 | dev_link_t *link = dev_to_instance(p_dev); | ||
232 | struct snd_pdacf *chip = link->priv; | 215 | struct snd_pdacf *chip = link->priv; |
233 | 216 | ||
234 | snd_printdd(KERN_DEBUG "pdacf_detach called\n"); | 217 | snd_printdd(KERN_DEBUG "pdacf_detach called\n"); |
235 | /* Remove the interface data from the linked list */ | 218 | |
236 | { | ||
237 | dev_link_t **linkp; | ||
238 | /* Locate device structure */ | ||
239 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
240 | if (*linkp == link) | ||
241 | break; | ||
242 | if (*linkp) | ||
243 | *linkp = link->next; | ||
244 | } | ||
245 | if (chip->chip_status & PDAUDIOCF_STAT_IS_CONFIGURED) | 219 | if (chip->chip_status & PDAUDIOCF_STAT_IS_CONFIGURED) |
246 | snd_pdacf_powerdown(chip); | 220 | snd_pdacf_powerdown(chip); |
247 | chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; /* to be sure */ | 221 | chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; /* to be sure */ |
@@ -310,62 +284,51 @@ failed: | |||
310 | pcmcia_release_irq(link->handle, &link->irq); | 284 | pcmcia_release_irq(link->handle, &link->irq); |
311 | } | 285 | } |
312 | 286 | ||
313 | /* | 287 | #ifdef CONFIG_PM |
314 | * event callback | 288 | |
315 | */ | 289 | static int pdacf_suspend(struct pcmcia_device *dev) |
316 | static int pdacf_event(event_t event, int priority, event_callback_args_t *args) | ||
317 | { | 290 | { |
318 | dev_link_t *link = args->client_data; | 291 | dev_link_t *link = dev_to_instance(dev); |
319 | struct snd_pdacf *chip = link->priv; | 292 | struct snd_pdacf *chip = link->priv; |
320 | 293 | ||
321 | switch (event) { | 294 | snd_printdd(KERN_DEBUG "SUSPEND\n"); |
322 | case CS_EVENT_CARD_REMOVAL: | 295 | link->state |= DEV_SUSPEND; |
323 | snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n"); | 296 | if (chip) { |
324 | link->state &= ~DEV_PRESENT; | 297 | snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n"); |
325 | if (link->state & DEV_CONFIG) { | 298 | snd_pdacf_suspend(chip, PMSG_SUSPEND); |
326 | chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; | 299 | } |
327 | } | 300 | |
328 | break; | 301 | snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); |
329 | case CS_EVENT_CARD_INSERTION: | 302 | if (link->state & DEV_CONFIG) |
330 | snd_printdd(KERN_DEBUG "CARD_INSERTION..\n"); | 303 | pcmcia_release_configuration(link->handle); |
331 | link->state |= DEV_PRESENT; | 304 | |
332 | pdacf_config(link); | 305 | return 0; |
333 | break; | 306 | } |
334 | #ifdef CONFIG_PM | 307 | |
335 | case CS_EVENT_PM_SUSPEND: | 308 | static int pdacf_resume(struct pcmcia_device *dev) |
336 | snd_printdd(KERN_DEBUG "SUSPEND\n"); | 309 | { |
337 | link->state |= DEV_SUSPEND; | 310 | dev_link_t *link = dev_to_instance(dev); |
311 | struct snd_pdacf *chip = link->priv; | ||
312 | |||
313 | snd_printdd(KERN_DEBUG "RESUME\n"); | ||
314 | link->state &= ~DEV_SUSPEND; | ||
315 | |||
316 | snd_printdd(KERN_DEBUG "CARD_RESET\n"); | ||
317 | if (DEV_OK(link)) { | ||
318 | snd_printdd(KERN_DEBUG "requestconfig...\n"); | ||
319 | pcmcia_request_configuration(link->handle, &link->conf); | ||
338 | if (chip) { | 320 | if (chip) { |
339 | snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n"); | 321 | snd_printdd(KERN_DEBUG "calling snd_pdacf_resume\n"); |
340 | snd_pdacf_suspend(chip, PMSG_SUSPEND); | 322 | snd_pdacf_resume(chip); |
341 | } | ||
342 | /* Fall through... */ | ||
343 | case CS_EVENT_RESET_PHYSICAL: | ||
344 | snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); | ||
345 | if (link->state & DEV_CONFIG) | ||
346 | pcmcia_release_configuration(link->handle); | ||
347 | break; | ||
348 | case CS_EVENT_PM_RESUME: | ||
349 | snd_printdd(KERN_DEBUG "RESUME\n"); | ||
350 | link->state &= ~DEV_SUSPEND; | ||
351 | /* Fall through... */ | ||
352 | case CS_EVENT_CARD_RESET: | ||
353 | snd_printdd(KERN_DEBUG "CARD_RESET\n"); | ||
354 | if (DEV_OK(link)) { | ||
355 | snd_printdd(KERN_DEBUG "requestconfig...\n"); | ||
356 | pcmcia_request_configuration(link->handle, &link->conf); | ||
357 | if (chip) { | ||
358 | snd_printdd(KERN_DEBUG "calling snd_pdacf_resume\n"); | ||
359 | snd_pdacf_resume(chip); | ||
360 | } | ||
361 | } | 323 | } |
362 | snd_printdd(KERN_DEBUG "resume done!\n"); | ||
363 | break; | ||
364 | #endif | ||
365 | } | 324 | } |
325 | snd_printdd(KERN_DEBUG "resume done!\n"); | ||
326 | |||
366 | return 0; | 327 | return 0; |
367 | } | 328 | } |
368 | 329 | ||
330 | #endif | ||
331 | |||
369 | /* | 332 | /* |
370 | * Module entry points | 333 | * Module entry points |
371 | */ | 334 | */ |
@@ -380,10 +343,14 @@ static struct pcmcia_driver pdacf_cs_driver = { | |||
380 | .drv = { | 343 | .drv = { |
381 | .name = "snd-pdaudiocf", | 344 | .name = "snd-pdaudiocf", |
382 | }, | 345 | }, |
383 | .attach = snd_pdacf_attach, | 346 | .probe = snd_pdacf_attach, |
384 | .event = pdacf_event, | 347 | .remove = snd_pdacf_detach, |
385 | .detach = snd_pdacf_detach, | ||
386 | .id_table = snd_pdacf_ids, | 348 | .id_table = snd_pdacf_ids, |
349 | #ifdef CONFIG_PM | ||
350 | .suspend = pdacf_suspend, | ||
351 | .resume = pdacf_resume, | ||
352 | #endif | ||
353 | |||
387 | }; | 354 | }; |
388 | 355 | ||
389 | static int __init init_pdacf(void) | 356 | static int __init init_pdacf(void) |
@@ -394,7 +361,6 @@ static int __init init_pdacf(void) | |||
394 | static void __exit exit_pdacf(void) | 361 | static void __exit exit_pdacf(void) |
395 | { | 362 | { |
396 | pcmcia_unregister_driver(&pdacf_cs_driver); | 363 | pcmcia_unregister_driver(&pdacf_cs_driver); |
397 | BUG_ON(dev_list != NULL); | ||
398 | } | 364 | } |
399 | 365 | ||
400 | module_init(init_pdacf); | 366 | module_init(init_pdacf); |
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 5bb079d1795..66900d20a42 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c | |||
@@ -55,11 +55,6 @@ MODULE_PARM_DESC(ibl, "Capture IBL size for VXPocket soundcard."); | |||
55 | */ | 55 | */ |
56 | 56 | ||
57 | static unsigned int card_alloc; | 57 | static unsigned int card_alloc; |
58 | static dev_link_t *dev_list; /* Linked list of devices */ | ||
59 | static dev_info_t dev_info = "snd-vxpocket"; | ||
60 | |||
61 | |||
62 | static int vxpocket_event(event_t event, int priority, event_callback_args_t *args); | ||
63 | 58 | ||
64 | 59 | ||
65 | /* | 60 | /* |
@@ -73,11 +68,6 @@ static void vxpocket_release(dev_link_t *link) | |||
73 | pcmcia_release_irq(link->handle, &link->irq); | 68 | pcmcia_release_irq(link->handle, &link->irq); |
74 | link->state &= ~DEV_CONFIG; | 69 | link->state &= ~DEV_CONFIG; |
75 | } | 70 | } |
76 | if (link->handle) { | ||
77 | /* Break the link with Card Services */ | ||
78 | pcmcia_deregister_client(link->handle); | ||
79 | link->handle = NULL; | ||
80 | } | ||
81 | } | 71 | } |
82 | 72 | ||
83 | /* | 73 | /* |
@@ -144,11 +134,9 @@ static struct snd_vx_hardware vxp440_hw = { | |||
144 | */ | 134 | */ |
145 | static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl) | 135 | static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl) |
146 | { | 136 | { |
147 | client_reg_t client_reg; /* Register with cardmgr */ | ||
148 | dev_link_t *link; /* Info for cardmgr */ | 137 | dev_link_t *link; /* Info for cardmgr */ |
149 | struct vx_core *chip; | 138 | struct vx_core *chip; |
150 | struct snd_vxpocket *vxp; | 139 | struct snd_vxpocket *vxp; |
151 | int ret; | ||
152 | static struct snd_device_ops ops = { | 140 | static struct snd_device_ops ops = { |
153 | .dev_free = snd_vxpocket_dev_free, | 141 | .dev_free = snd_vxpocket_dev_free, |
154 | }; | 142 | }; |
@@ -184,26 +172,6 @@ static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl) | |||
184 | link->conf.ConfigIndex = 1; | 172 | link->conf.ConfigIndex = 1; |
185 | link->conf.Present = PRESENT_OPTION; | 173 | link->conf.Present = PRESENT_OPTION; |
186 | 174 | ||
187 | /* Register with Card Services */ | ||
188 | memset(&client_reg, 0, sizeof(client_reg)); | ||
189 | client_reg.dev_info = &dev_info; | ||
190 | client_reg.EventMask = | ||
191 | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | ||
192 | #ifdef CONFIG_PM | ||
193 | | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | ||
194 | | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME | ||
195 | #endif | ||
196 | ; | ||
197 | client_reg.event_handler = &vxpocket_event; | ||
198 | client_reg.Version = 0x0210; | ||
199 | client_reg.event_callback_args.client_data = link; | ||
200 | |||
201 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
202 | if (ret != CS_SUCCESS) { | ||
203 | cs_error(link->handle, RegisterClient, ret); | ||
204 | return NULL; | ||
205 | } | ||
206 | |||
207 | return vxp; | 175 | return vxp; |
208 | } | 176 | } |
209 | 177 | ||
@@ -317,67 +285,55 @@ failed: | |||
317 | kfree(parse); | 285 | kfree(parse); |
318 | } | 286 | } |
319 | 287 | ||
288 | #ifdef CONFIG_PM | ||
320 | 289 | ||
321 | /* | 290 | static int vxp_suspend(struct pcmcia_device *dev) |
322 | * event callback | ||
323 | */ | ||
324 | static int vxpocket_event(event_t event, int priority, event_callback_args_t *args) | ||
325 | { | 291 | { |
326 | dev_link_t *link = args->client_data; | 292 | dev_link_t *link = dev_to_instance(dev); |
327 | struct vx_core *chip = link->priv; | 293 | struct vx_core *chip = link->priv; |
328 | 294 | ||
329 | switch (event) { | 295 | snd_printdd(KERN_DEBUG "SUSPEND\n"); |
330 | case CS_EVENT_CARD_REMOVAL: | 296 | link->state |= DEV_SUSPEND; |
331 | snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n"); | 297 | if (chip) { |
332 | link->state &= ~DEV_PRESENT; | 298 | snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); |
333 | if (link->state & DEV_CONFIG) | 299 | snd_vx_suspend(chip, PMSG_SUSPEND); |
334 | chip->chip_status |= VX_STAT_IS_STALE; | 300 | } |
335 | break; | 301 | snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); |
336 | case CS_EVENT_CARD_INSERTION: | 302 | if (link->state & DEV_CONFIG) |
337 | snd_printdd(KERN_DEBUG "CARD_INSERTION..\n"); | 303 | pcmcia_release_configuration(link->handle); |
338 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 304 | |
339 | vxpocket_config(link); | 305 | return 0; |
340 | break; | 306 | } |
341 | #ifdef CONFIG_PM | 307 | |
342 | case CS_EVENT_PM_SUSPEND: | 308 | static int vxp_resume(struct pcmcia_device *dev) |
343 | snd_printdd(KERN_DEBUG "SUSPEND\n"); | 309 | { |
344 | link->state |= DEV_SUSPEND; | 310 | dev_link_t *link = dev_to_instance(dev); |
311 | struct vx_core *chip = link->priv; | ||
312 | |||
313 | snd_printdd(KERN_DEBUG "RESUME\n"); | ||
314 | link->state &= ~DEV_SUSPEND; | ||
315 | |||
316 | snd_printdd(KERN_DEBUG "CARD_RESET\n"); | ||
317 | if (DEV_OK(link)) { | ||
318 | //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; | ||
319 | snd_printdd(KERN_DEBUG "requestconfig...\n"); | ||
320 | pcmcia_request_configuration(link->handle, &link->conf); | ||
345 | if (chip) { | 321 | if (chip) { |
346 | snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); | 322 | snd_printdd(KERN_DEBUG "calling snd_vx_resume\n"); |
347 | snd_vx_suspend(chip, PMSG_SUSPEND); | 323 | snd_vx_resume(chip); |
348 | } | 324 | } |
349 | /* Fall through... */ | ||
350 | case CS_EVENT_RESET_PHYSICAL: | ||
351 | snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); | ||
352 | if (link->state & DEV_CONFIG) | ||
353 | pcmcia_release_configuration(link->handle); | ||
354 | break; | ||
355 | case CS_EVENT_PM_RESUME: | ||
356 | snd_printdd(KERN_DEBUG "RESUME\n"); | ||
357 | link->state &= ~DEV_SUSPEND; | ||
358 | /* Fall through... */ | ||
359 | case CS_EVENT_CARD_RESET: | ||
360 | snd_printdd(KERN_DEBUG "CARD_RESET\n"); | ||
361 | if (DEV_OK(link)) { | ||
362 | //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; | ||
363 | snd_printdd(KERN_DEBUG "requestconfig...\n"); | ||
364 | pcmcia_request_configuration(link->handle, &link->conf); | ||
365 | if (chip) { | ||
366 | snd_printdd(KERN_DEBUG "calling snd_vx_resume\n"); | ||
367 | snd_vx_resume(chip); | ||
368 | } | ||
369 | } | ||
370 | snd_printdd(KERN_DEBUG "resume done!\n"); | ||
371 | break; | ||
372 | #endif | ||
373 | } | 325 | } |
326 | snd_printdd(KERN_DEBUG "resume done!\n"); | ||
327 | |||
374 | return 0; | 328 | return 0; |
375 | } | 329 | } |
376 | 330 | ||
331 | #endif | ||
332 | |||
377 | 333 | ||
378 | /* | 334 | /* |
379 | */ | 335 | */ |
380 | static dev_link_t *vxpocket_attach(void) | 336 | static int vxpocket_attach(struct pcmcia_device *p_dev) |
381 | { | 337 | { |
382 | struct snd_card *card; | 338 | struct snd_card *card; |
383 | struct snd_vxpocket *vxp; | 339 | struct snd_vxpocket *vxp; |
@@ -390,22 +346,22 @@ static dev_link_t *vxpocket_attach(void) | |||
390 | } | 346 | } |
391 | if (i >= SNDRV_CARDS) { | 347 | if (i >= SNDRV_CARDS) { |
392 | snd_printk(KERN_ERR "vxpocket: too many cards found\n"); | 348 | snd_printk(KERN_ERR "vxpocket: too many cards found\n"); |
393 | return NULL; | 349 | return -EINVAL; |
394 | } | 350 | } |
395 | if (! enable[i]) | 351 | if (! enable[i]) |
396 | return NULL; /* disabled explicitly */ | 352 | return -ENODEV; /* disabled explicitly */ |
397 | 353 | ||
398 | /* ok, create a card instance */ | 354 | /* ok, create a card instance */ |
399 | card = snd_card_new(index[i], id[i], THIS_MODULE, 0); | 355 | card = snd_card_new(index[i], id[i], THIS_MODULE, 0); |
400 | if (card == NULL) { | 356 | if (card == NULL) { |
401 | snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); | 357 | snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); |
402 | return NULL; | 358 | return -ENOMEM; |
403 | } | 359 | } |
404 | 360 | ||
405 | vxp = snd_vxpocket_new(card, ibl[i]); | 361 | vxp = snd_vxpocket_new(card, ibl[i]); |
406 | if (! vxp) { | 362 | if (! vxp) { |
407 | snd_card_free(card); | 363 | snd_card_free(card); |
408 | return NULL; | 364 | return -ENODEV; |
409 | } | 365 | } |
410 | card->private_data = vxp; | 366 | card->private_data = vxp; |
411 | 367 | ||
@@ -413,17 +369,21 @@ static dev_link_t *vxpocket_attach(void) | |||
413 | card_alloc |= 1 << i; | 369 | card_alloc |= 1 << i; |
414 | 370 | ||
415 | /* Chain drivers */ | 371 | /* Chain drivers */ |
416 | vxp->link.next = dev_list; | 372 | vxp->link.next = NULL; |
417 | dev_list = &vxp->link; | 373 | |
374 | vxp->link.handle = p_dev; | ||
375 | vxp->link.state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
376 | p_dev->instance = &vxp->link; | ||
377 | vxpocket_config(&vxp->link); | ||
418 | 378 | ||
419 | return &vxp->link; | 379 | return 0; |
420 | } | 380 | } |
421 | 381 | ||
422 | static void vxpocket_detach(dev_link_t *link) | 382 | static void vxpocket_detach(struct pcmcia_device *p_dev) |
423 | { | 383 | { |
384 | dev_link_t *link = dev_to_instance(p_dev); | ||
424 | struct snd_vxpocket *vxp; | 385 | struct snd_vxpocket *vxp; |
425 | struct vx_core *chip; | 386 | struct vx_core *chip; |
426 | dev_link_t **linkp; | ||
427 | 387 | ||
428 | if (! link) | 388 | if (! link) |
429 | return; | 389 | return; |
@@ -432,13 +392,6 @@ static void vxpocket_detach(dev_link_t *link) | |||
432 | chip = (struct vx_core *)vxp; | 392 | chip = (struct vx_core *)vxp; |
433 | card_alloc &= ~(1 << vxp->index); | 393 | card_alloc &= ~(1 << vxp->index); |
434 | 394 | ||
435 | /* Remove the interface data from the linked list */ | ||
436 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
437 | if (*linkp == link) { | ||
438 | *linkp = link->next; | ||
439 | break; | ||
440 | } | ||
441 | |||
442 | chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ | 395 | chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ |
443 | snd_card_disconnect(chip->card); | 396 | snd_card_disconnect(chip->card); |
444 | vxpocket_release(link); | 397 | vxpocket_release(link); |
@@ -460,10 +413,13 @@ static struct pcmcia_driver vxp_cs_driver = { | |||
460 | .drv = { | 413 | .drv = { |
461 | .name = "snd-vxpocket", | 414 | .name = "snd-vxpocket", |
462 | }, | 415 | }, |
463 | .attach = vxpocket_attach, | 416 | .probe = vxpocket_attach, |
464 | .detach = vxpocket_detach, | 417 | .remove = vxpocket_detach, |
465 | .event = vxpocket_event, | ||
466 | .id_table = vxp_ids, | 418 | .id_table = vxp_ids, |
419 | #ifdef CONFIG_PM | ||
420 | .suspend = vxp_suspend, | ||
421 | .resume = vxp_resume, | ||
422 | #endif | ||
467 | }; | 423 | }; |
468 | 424 | ||
469 | static int __init init_vxpocket(void) | 425 | static int __init init_vxpocket(void) |
@@ -474,7 +430,6 @@ static int __init init_vxpocket(void) | |||
474 | static void __exit exit_vxpocket(void) | 430 | static void __exit exit_vxpocket(void) |
475 | { | 431 | { |
476 | pcmcia_unregister_driver(&vxp_cs_driver); | 432 | pcmcia_unregister_driver(&vxp_cs_driver); |
477 | BUG_ON(dev_list != NULL); | ||
478 | } | 433 | } |
479 | 434 | ||
480 | module_init(init_vxpocket); | 435 | module_init(init_vxpocket); |