1 /*
2 * sound/sb_card.c
3 *
4 * Detection routine for the Sound Blaster cards.
5 *
6 *
7 * Copyright (C) by Hannu Savolainen 1993-1997
8 *
9 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10 * Version 2 (June 1991). See the "COPYING" file distributed with this software
11 * for more info.
12 *
13 * 26-11-1999 Patched to compile without ISA PnP support in the
14 * kernel - Daniel Stone (tamriel@ductape.net)
15 *
16 * 06-01-2000 Refined and bugfixed ISA PnP support, added
17 * CMI 8330 support - Alessandro Zummo <azummo@ita.flashnet.it>
18 *
19 * 18-01-2000 Separated sb_card and sb_common
20 * Jeff Garzik <jgarzik@pobox.com>
21 *
22 * 04-02-2000 Added Soundblaster AWE 64 PnP support, isapnpjump
23 * Alessandro Zummo <azummo@ita.flashnet.it>
24 *
25 * 11-02-2000 Added Soundblaster AWE 32 PnP support, refined PnP code
26 * Alessandro Zummo <azummo@ita.flashnet.it>
27 *
28 * 13-02-2000 Hopefully fixed awe/sb16 related bugs, code cleanup
29 * Alessandro Zummo <azummo@ita.flashnet.it>
30 *
31 * 13-03-2000 Added some more cards, thanks to Torsten Werner.
32 * Removed joystick and wavetable code, there are better places for them.
33 * Code cleanup plus some fixes.
34 * Alessandro Zummo <azummo@ita.flashnet.it>
35 *
36 * 26-03-2000 Fixed acer, esstype and sm_games module options.
37 * Alessandro Zummo <azummo@ita.flashnet.it>
38 *
39 * 12-04-2000 ISAPnP cleanup, reorg, fixes, and multiple card support.
40 * Thanks to Ga�l Qu�ri and Alessandro Zummo for testing and fixes.
41 * Paul E. Laufer <pelaufer@csupomona.edu>
42 *
43 * 06-05-2000 added another card. Daniel M. Newman <dmnewman@pobox.com>
44 *
45 * 25-05-2000 Added Creative SB AWE64 Gold (CTL00B2).
46 * P�l-Kristian Engstad <engstad@att.net>
47 *
48 * 12-08-2000 Added Creative SB32 PnP (CTL009F).
49 * Kasatenko Ivan Alex. <skywriter@rnc.ru>
50 *
51 * 21-09-2000 Got rid of attach_sbmpu
52 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
53 *
54 * 28-10-2000 Added pnplegacy support
55 * Daniel Church <dchurch@mbhs.edu>
56 *
57 * 01-10-2001 Added a new flavor of Creative SB AWE64 PnP (CTL00E9).
58 * Jerome Cornet <jcornet@free.fr>
59 */
60
61 #include <linux/config.h>
62 #include <linux/mca.h>
63 #include <linux/module.h>
64 #include <linux/init.h>
65 #include <linux/isapnp.h>
66
67 #include "sound_config.h"
68
69 #include "sb_mixer.h"
70 #include "sb.h"
71
72 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
73 #define SB_CARDS_MAX 5
74 #else
75 #define SB_CARDS_MAX 1
76 #endif
77
78 static int sbmpu[SB_CARDS_MAX] = {0};
79 static int sb_cards_num = 0;
80
81 extern void *smw_free;
82
83 /*
84 * Note DMA2 of -1 has the right meaning in the SB16 driver as well
85 * as here. It will cause either an error if it is needed or a fallback
86 * to the 8bit channel.
87 */
88
89 static int __initdata mpu_io = 0;
90 static int __initdata io = -1;
91 static int __initdata irq = -1;
92 static int __initdata dma = -1;
93 static int __initdata dma16 = -1; /* Set this for modules that need it */
94 static int __initdata type = 0; /* Can set this to a specific card type */
95 static int __initdata esstype = 0; /* ESS chip type */
96 static int __initdata acer = 0; /* Do acer notebook init? */
97 static int __initdata sm_games = 0; /* Logitech soundman games? */
98
attach_sb_card(struct address_info * hw_config)99 static void __init attach_sb_card(struct address_info *hw_config)
100 {
101 if(!sb_dsp_init(hw_config, THIS_MODULE))
102 hw_config->slots[0] = -1;
103 }
104
probe_sb(struct address_info * hw_config)105 static int __init probe_sb(struct address_info *hw_config)
106 {
107 struct sb_module_options sbmo;
108
109 if (hw_config->io_base == -1 || hw_config->dma == -1 || hw_config->irq == -1)
110 {
111 printk(KERN_ERR "sb: I/O, IRQ, and DMA are mandatory\n");
112 return -EINVAL;
113 }
114
115 #ifdef CONFIG_MCA
116 /* MCA code added by ZP Gu (zpg@castle.net) */
117 if (MCA_bus) { /* no multiple REPLY card probing */
118 int slot;
119 u8 pos2, pos3, pos4;
120
121 slot = mca_find_adapter( 0x5138, 0 );
122 if( slot == MCA_NOTFOUND )
123 {
124 slot = mca_find_adapter( 0x5137, 0 );
125
126 if (slot != MCA_NOTFOUND)
127 mca_set_adapter_name( slot, "REPLY SB16 & SCSI Adapter" );
128 }
129 else
130 {
131 mca_set_adapter_name( slot, "REPLY SB16 Adapter" );
132 }
133
134 if (slot != MCA_NOTFOUND)
135 {
136 mca_mark_as_used(slot);
137 pos2 = mca_read_stored_pos( slot, 2 );
138 pos3 = mca_read_stored_pos( slot, 3 );
139 pos4 = mca_read_stored_pos( slot, 4 );
140
141 if (pos2 & 0x4)
142 {
143 /* enabled? */
144 static unsigned short irq[] = { 0, 5, 7, 10 };
145 /*
146 static unsigned short midiaddr[] = {0, 0x330, 0, 0x300 };
147 */
148
149 hw_config->io_base = 0x220 + 0x20 * (pos2 >> 6);
150 hw_config->irq = irq[(pos4 >> 5) & 0x3];
151 hw_config->dma = pos3 & 0xf;
152 /* Reply ADF wrong on High DMA, pos[1] should start w/ 00 */
153 hw_config->dma2 = (pos3 >> 4) & 0x3;
154 if (hw_config->dma2 == 0)
155 hw_config->dma2 = hw_config->dma;
156 else
157 hw_config->dma2 += 4;
158 /*
159 hw_config->driver_use_2 = midiaddr[(pos2 >> 3) & 0x3];
160 */
161
162 printk(KERN_INFO "sb: Reply MCA SB at slot=%d \
163 iobase=0x%x irq=%d lo_dma=%d hi_dma=%d\n",
164 slot+1,
165 hw_config->io_base, hw_config->irq,
166 hw_config->dma, hw_config->dma2);
167 }
168 else
169 {
170 printk (KERN_INFO "sb: Reply SB Base I/O address disabled\n");
171 }
172 }
173 }
174 #endif
175
176 /* Setup extra module options */
177
178 sbmo.acer = acer;
179 sbmo.sm_games = sm_games;
180 sbmo.esstype = esstype;
181
182 return sb_dsp_detect(hw_config, 0, 0, &sbmo);
183 }
184
unload_sb(struct address_info * hw_config,int card)185 static void __exit unload_sb(struct address_info *hw_config, int card)
186 {
187 if(hw_config->slots[0]!=-1)
188 sb_dsp_unload(hw_config, sbmpu[card]);
189 }
190
191 static struct address_info cfg[SB_CARDS_MAX];
192 static struct address_info cfg_mpu[SB_CARDS_MAX];
193
194 struct pci_dev *sb_dev[SB_CARDS_MAX] = {NULL},
195 *mpu_dev[SB_CARDS_MAX] = {NULL},
196 *opl_dev[SB_CARDS_MAX] = {NULL};
197
198
199 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
200 static int isapnp = 1;
201 static int isapnpjump = 0;
202 static int multiple = 1;
203 static int pnplegacy = 0;
204 static int reverse = 0;
205 static int uart401 = 0;
206
207 static int audio_activated[SB_CARDS_MAX] = {0};
208 static int mpu_activated[SB_CARDS_MAX] = {0};
209 static int opl_activated[SB_CARDS_MAX] = {0};
210 #else
211 static int isapnp = 0;
212 static int multiple = 0;
213 static int pnplegacy = 0;
214 #endif
215
216 MODULE_DESCRIPTION("Soundblaster driver");
217 MODULE_LICENSE("GPL");
218
219 MODULE_PARM(io, "i");
220 MODULE_PARM(irq, "i");
221 MODULE_PARM(dma, "i");
222 MODULE_PARM(dma16, "i");
223 MODULE_PARM(mpu_io, "i");
224 MODULE_PARM(type, "i");
225 MODULE_PARM(sm_games, "i");
226 MODULE_PARM(esstype, "i");
227 MODULE_PARM(acer, "i");
228
229 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
230 MODULE_PARM(isapnp, "i");
231 MODULE_PARM(isapnpjump, "i");
232 MODULE_PARM(multiple, "i");
233 MODULE_PARM(pnplegacy, "i");
234 MODULE_PARM(reverse, "i");
235 MODULE_PARM(uart401, "i");
236 MODULE_PARM_DESC(isapnp, "When set to 0, Plug & Play support will be disabled");
237 MODULE_PARM_DESC(isapnpjump, "Jumps to a specific slot in the driver's PnP table. Use the source, Luke.");
238 MODULE_PARM_DESC(multiple, "When set to 0, will not search for multiple cards");
239 MODULE_PARM_DESC(pnplegacy, "When set to 1, will search for a legacy SB card along with any PnP cards.");
240 MODULE_PARM_DESC(reverse, "When set to 1, will reverse ISAPnP search order");
241 MODULE_PARM_DESC(uart401, "When set to 1, will attempt to detect and enable the mpu on some clones");
242 #endif
243
244 MODULE_PARM_DESC(io, "Soundblaster i/o base address (0x220,0x240,0x260,0x280)");
245 MODULE_PARM_DESC(irq, "IRQ (5,7,9,10)");
246 MODULE_PARM_DESC(dma, "8-bit DMA channel (0,1,3)");
247 MODULE_PARM_DESC(dma16, "16-bit DMA channel (5,6,7)");
248 MODULE_PARM_DESC(mpu_io, "Mpu base address");
249 MODULE_PARM_DESC(type, "You can set this to specific card type");
250 MODULE_PARM_DESC(sm_games, "Enable support for Logitech soundman games");
251 MODULE_PARM_DESC(esstype, "ESS chip type");
252 MODULE_PARM_DESC(acer, "Set this to detect cards in some ACER notebooks");
253
254 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
255
256 /* Please add new entries at the end of the table */
257 static struct {
258 char *name;
259 unsigned short card_vendor, card_device,
260 audio_vendor, audio_function,
261 mpu_vendor, mpu_function,
262 opl_vendor, opl_function;
263 short dma, dma2, mpu_io, mpu_irq; /* see sb_init() */
264 } sb_isapnp_list[] __initdata = {
265 {"Sound Blaster 16",
266 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0024),
267 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
268 0,0,0,0,
269 0,1,1,-1},
270 {"Sound Blaster 16",
271 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0025),
272 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
273 0,0,0,0,
274 0,1,1,-1},
275 {"Sound Blaster 16",
276 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0026),
277 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
278 0,0,0,0,
279 0,1,1,-1},
280 {"Sound Blaster 16",
281 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0027),
282 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
283 0,0,0,0,
284 0,1,1,-1},
285 {"Sound Blaster 16",
286 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0028),
287 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
288 0,0,0,0,
289 0,1,1,-1},
290 {"Sound Blaster 16",
291 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0029),
292 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
293 0,0,0,0,
294 0,1,1,-1},
295 {"Sound Blaster 16",
296 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002a),
297 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
298 0,0,0,0,
299 0,1,1,-1},
300 {"Sound Blaster 16",
301 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002b),
302 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
303 0,0,0,0,
304 0,1,1,-1},
305 {"Sound Blaster 16",
306 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002c),
307 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
308 0,0,0,0,
309 0,1,1,-1},
310 {"Sound Blaster 16",
311 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002c),
312 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
313 0,0,0,0,
314 0,1,1,-1},
315 {"Sound Blaster 16",
316 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00ed),
317 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
318 0,0,0,0,
319 0,1,1,-1},
320 {"Sound Blaster 16",
321 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0086),
322 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
323 0,0,0,0,
324 0,1,1,-1},
325 {"Sound Blaster 16",
326 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0086),
327 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
328 0,0,0,0,
329 0,1,1,-1},
330 {"Sound Blaster Vibra16S",
331 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0051),
332 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001),
333 0,0,0,0,
334 0,1,1,-1},
335 {"Sound Blaster Vibra16C",
336 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0070),
337 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001),
338 0,0,0,0,
339 0,1,1,-1},
340 {"Sound Blaster Vibra16CL",
341 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0080),
342 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
343 0,0,0,0,
344 0,1,1,-1},
345 {"Sound Blaster Vibra16X",
346 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00F0),
347 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0043),
348 0,0,0,0,
349 0,1,1,-1},
350 {"Sound Blaster AWE 32",
351 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0039),
352 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
353 0,0,0,0,
354 0,1,1,-1},
355 {"Sound Blaster AWE 32",
356 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0042),
357 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
358 0,0,0,0,
359 0,1,1,-1},
360 {"Sound Blaster AWE 32",
361 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0043),
362 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
363 0,0,0,0,
364 0,1,1,-1},
365 {"Sound Blaster AWE 32",
366 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0044),
367 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
368 0,0,0,0,
369 0,1,1,-1},
370 {"Sound Blaster AWE 32",
371 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0045),
372 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
373 0,0,0,0,
374 0,1,1,-1},
375 {"Sound Blaster AWE 32",
376 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0046),
377 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
378 0,0,0,0,
379 0,1,1,-1},
380 {"Sound Blaster AWE 32",
381 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0047),
382 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
383 0,0,0,0,
384 0,1,1,-1},
385 {"Sound Blaster AWE 32",
386 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0048),
387 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
388 0,0,0,0,
389 0,1,1,-1},
390 {"Sound Blaster AWE 32",
391 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0054),
392 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
393 0,0,0,0,
394 0,1,1,-1},
395 {"Sound Blaster AWE 32",
396 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009C),
397 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
398 0,0,0,0,
399 0,1,1,-1},
400 {"Creative SB32 PnP",
401 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009F),
402 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
403 0,0,0,0,
404 0,1,1,-1},
405 {"Sound Blaster AWE 64",
406 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009D),
407 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042),
408 0,0,0,0,
409 0,1,1,-1},
410 {"Sound Blaster AWE 64 Gold",
411 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009E),
412 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044),
413 0,0,0,0,
414 0,1,1,-1},
415 {"Sound Blaster AWE 64 Gold",
416 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00B2),
417 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044),
418 0,0,0,0,
419 0,1,1,-1},
420 {"Sound Blaster AWE 64",
421 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C1),
422 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042),
423 0,0,0,0,
424 0,1,1,-1},
425 {"Sound Blaster AWE 64",
426 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C3),
427 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
428 0,0,0,0,
429 0,1,1,-1},
430 {"Sound Blaster AWE 64",
431 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C5),
432 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
433 0,0,0,0,
434 0,1,1,-1},
435 {"Sound Blaster AWE 64",
436 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C7),
437 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
438 0,0,0,0,
439 0,1,1,-1},
440 {"Sound Blaster AWE 64",
441 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E4),
442 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
443 0,0,0,0,
444 0,1,1,-1},
445 {"Sound Blaster AWE 64",
446 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E9),
447 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
448 0,0,0,0,
449 0,1,1,-1},
450 {"ESS 1688",
451 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0968),
452 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x0968),
453 0,0,0,0,
454 0,1,2,-1},
455 {"ESS 1868",
456 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868),
457 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1868),
458 0,0,0,0,
459 0,1,2,-1},
460 {"ESS 1868",
461 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868),
462 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x8611),
463 0,0,0,0,
464 0,1,2,-1},
465 {"ESS 1869 PnP AudioDrive",
466 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0003),
467 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869),
468 0,0,0,0,
469 0,1,2,-1},
470 {"ESS 1869",
471 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1869),
472 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869),
473 0,0,0,0,
474 0,1,2,-1},
475 {"ESS 1878",
476 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1878),
477 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1878),
478 0,0,0,0,
479 0,1,2,-1},
480 {"ESS 1879",
481 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1879),
482 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1879),
483 0,0,0,0,
484 0,1,2,-1},
485 {"CMI 8330 SoundPRO",
486 ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
487 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
488 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
489 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
490 0,1,0,-1},
491 {"Diamond DT0197H",
492 ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688),
493 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
494 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
495 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
496 0,-1,0,0},
497 {"ALS007",
498 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007),
499 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
500 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
501 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
502 0,-1,0,0},
503 {"ALS100",
504 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001),
505 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
506 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
507 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
508 1,0,0,0},
509 {"ALS110",
510 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110),
511 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x1001),
512 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x1001),
513 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
514 1,0,0,0},
515 {"ALS120",
516 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120),
517 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001),
518 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001),
519 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
520 1,0,0,0},
521 {"ALS200",
522 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200),
523 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0020),
524 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0020),
525 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
526 1,0,0,0},
527 {"RTL3000",
528 ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000),
529 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001),
530 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001),
531 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
532 1,0,0,0},
533 {0}
534 };
535
536 static struct isapnp_device_id id_table[] __devinitdata = {
537 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0024),
538 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
539
540 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0025),
541 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
542
543 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0026),
544 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
545
546 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0027),
547 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
548
549 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0028),
550 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
551
552 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0029),
553 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
554
555 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002a),
556 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
557
558 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002b),
559 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
560
561 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002c),
562 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
563
564 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002c),
565 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
566
567 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00ed),
568 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
569
570 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0086),
571 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
572
573 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0086),
574 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
575
576 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0051),
577 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), 0 },
578
579 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0070),
580 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), 0 },
581
582 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0080),
583 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
584
585 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00F0),
586 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0043), 0 },
587
588 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0039),
589 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
590
591 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0042),
592 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
593
594 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0043),
595 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
596
597 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0044),
598 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
599
600 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0045),
601 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
602
603 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0048),
604 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
605
606 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0054),
607 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
608
609 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009C),
610 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
611
612 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009F),
613 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
614
615 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009D),
616 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042), 0 },
617
618 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009E),
619 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044), 0 },
620
621 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00B2),
622 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044), 0 },
623
624 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C1),
625 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042), 0 },
626
627 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C3),
628 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
629
630 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C5),
631 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
632
633 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C7),
634 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
635
636 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E4),
637 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
638
639 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E9),
640 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
641
642 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0968),
643 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x0968), 0 },
644
645 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868),
646 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1868), 0 },
647
648 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868),
649 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x8611), 0 },
650
651 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0003),
652 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869), 0 },
653
654 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1869),
655 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869), 0 },
656
657 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1878),
658 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1878), 0 },
659
660 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1879),
661 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1879), 0 },
662
663 { ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
664 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), 0 },
665
666 { ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
667 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
668
669 { ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
670 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
671
672 { ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688),
673 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
674
675 { ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688),
676 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), 0 },
677
678 { ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688),
679 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
680
681 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007),
682 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
683
684 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007),
685 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), 0 },
686
687 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007),
688 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
689
690 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001),
691 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
692
693 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001),
694 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), 0 },
695
696 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001),
697 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
698
699 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110),
700 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x1001), 0 },
701
702 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110),
703 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x1001), 0 },
704
705 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110),
706 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
707
708 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120),
709 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001), 0 },
710
711 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120),
712 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001), 0 },
713
714 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120),
715 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
716
717 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200),
718 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0020), 0 },
719
720 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200),
721 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0020), 0 },
722
723 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200),
724 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
725
726 { ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000),
727 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001), 0 },
728
729 { ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000),
730 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001), 0 },
731
732 { ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000),
733 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
734 {0}
735 };
736
737 MODULE_DEVICE_TABLE(isapnp, id_table);
738
activate_dev(char * devname,char * resname,struct pci_dev * dev)739 static struct pci_dev *activate_dev(char *devname, char *resname, struct pci_dev *dev)
740 {
741 int err;
742
743 /* Device already active? Let's use it */
744 if(dev->active)
745 return(dev);
746
747 if((err = dev->activate(dev)) < 0) {
748 printk(KERN_ERR "sb: %s %s config failed (out of resources?)[%d]\n", devname, resname, err);
749
750 dev->deactivate(dev);
751
752 return(NULL);
753 }
754 return(dev);
755 }
756
sb_init(struct pci_bus * bus,struct address_info * hw_config,struct address_info * mpu_config,int slot,int card)757 static struct pci_dev *sb_init(struct pci_bus *bus, struct address_info *hw_config, struct address_info *mpu_config, int slot, int card)
758 {
759
760 /* Configure Audio device */
761 if((sb_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].audio_vendor, sb_isapnp_list[slot].audio_function, NULL)))
762 {
763 int ret;
764 ret = sb_dev[card]->prepare(sb_dev[card]);
765 /* If device is active, assume configured with /proc/isapnp
766 * and use anyway. Some other way to check this? */
767 if(ret && ret != -EBUSY) {
768 printk(KERN_ERR "sb: ISAPnP found device that could not be autoconfigured.\n");
769 return(NULL);
770 }
771 if(ret == -EBUSY)
772 audio_activated[card] = 1;
773
774 if((sb_dev[card] = activate_dev(sb_isapnp_list[slot].name, "sb", sb_dev[card])))
775 {
776 hw_config->io_base = sb_dev[card]->resource[0].start;
777 hw_config->irq = sb_dev[card]->irq_resource[0].start;
778 hw_config->dma = sb_dev[card]->dma_resource[sb_isapnp_list[slot].dma].start;
779 if(sb_isapnp_list[slot].dma2 != -1)
780 hw_config->dma2 = sb_dev[card]->dma_resource[sb_isapnp_list[slot].dma2].start;
781 else
782 hw_config->dma2 = -1;
783 } else
784 return(NULL);
785 } else
786 return(NULL);
787
788 /* Cards with separate OPL3 device (ALS, CMI, etc.)
789 * This is just to activate the device so the OPL module can use it */
790 if(sb_isapnp_list[slot].opl_vendor || sb_isapnp_list[slot].opl_function) {
791 if((opl_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].opl_vendor, sb_isapnp_list[slot].opl_function, NULL))) {
792 int ret = opl_dev[card]->prepare(opl_dev[card]);
793 /* If device is active, assume configured with
794 * /proc/isapnp and use anyway */
795 if(ret && ret != -EBUSY) {
796 printk(KERN_ERR "sb: OPL device could not be autoconfigured.\n");
797 return(sb_dev[card]);
798 }
799 if(ret == -EBUSY)
800 opl_activated[card] = 1;
801
802 /* Some have irq and dma for opl. the opl3 driver wont
803 * use 'em so don't configure 'em and hope it works -PEL */
804 opl_dev[card]->irq_resource[0].flags = 0;
805 opl_dev[card]->dma_resource[0].flags = 0;
806
807 opl_dev[card] = activate_dev(sb_isapnp_list[slot].name, "opl3", opl_dev[card]);
808 } else
809 printk(KERN_ERR "sb: %s isapnp panic: opl3 device not found\n", sb_isapnp_list[slot].name);
810 }
811
812 /* Cards with MPU as part of Audio device (CTL and ESS) */
813 if(!sb_isapnp_list[slot].mpu_vendor) {
814 mpu_config->io_base = sb_dev[card]->resource[sb_isapnp_list[slot].mpu_io].start;
815 return(sb_dev[card]);
816 }
817
818 /* Cards with separate MPU device (ALS, CMI, etc.) */
819 if(!uart401)
820 return(sb_dev[card]);
821 if((mpu_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].mpu_vendor, sb_isapnp_list[slot].mpu_function, NULL)))
822 {
823 int ret = mpu_dev[card]->prepare(mpu_dev[card]);
824 /* If device is active, assume configured with /proc/isapnp
825 * and use anyway */
826 if(ret && ret != -EBUSY) {
827 printk(KERN_ERR "sb: MPU device could not be autoconfigured.\n");
828 return(sb_dev[card]);
829 }
830 if(ret == -EBUSY)
831 mpu_activated[card] = 1;
832
833 /* Some cards ask for irq but don't need them - azummo */
834 if(sb_isapnp_list[slot].mpu_irq == -1)
835 mpu_dev[card]->irq_resource[0].flags = 0;
836
837 if((mpu_dev[card] = activate_dev(sb_isapnp_list[slot].name, "mpu", mpu_dev[card]))) {
838 mpu_config->io_base = mpu_dev[card]->resource[sb_isapnp_list[slot].mpu_io].start;
839 if(sb_isapnp_list[slot].mpu_irq != -1)
840 mpu_config->irq = mpu_dev[card]->irq_resource[sb_isapnp_list[slot].mpu_irq].start;
841 }
842 }
843 else
844 printk(KERN_ERR "sb: %s isapnp panic: mpu not found\n", sb_isapnp_list[slot].name);
845
846 return(sb_dev[card]);
847 }
848
sb_isapnp_init(struct address_info * hw_config,struct address_info * mpu_config,struct pci_bus * bus,int slot,int card)849 static int __init sb_isapnp_init(struct address_info *hw_config, struct address_info *mpu_config, struct pci_bus *bus, int slot, int card)
850 {
851 char *busname = bus->name[0] ? bus->name : sb_isapnp_list[slot].name;
852
853 printk(KERN_INFO "sb: %s detected\n", busname);
854
855 /* Initialize this baby. */
856
857 if(sb_init(bus, hw_config, mpu_config, slot, card)) {
858 /* We got it. */
859
860 printk(KERN_NOTICE "sb: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
861 busname,
862 hw_config->io_base, hw_config->irq, hw_config->dma,
863 hw_config->dma2);
864 return 1;
865 }
866 else
867 printk(KERN_INFO "sb: Failed to initialize %s\n", busname);
868
869 return 0;
870 }
871
sb_isapnp_probe(struct address_info * hw_config,struct address_info * mpu_config,int card)872 static int __init sb_isapnp_probe(struct address_info *hw_config, struct address_info *mpu_config, int card)
873 {
874 static int first = 1;
875 int i;
876
877 /* Count entries in sb_isapnp_list */
878 for (i = 0; sb_isapnp_list[i].card_vendor != 0; i++);
879 i--;
880
881 /* Check and adjust isapnpjump */
882 if( isapnpjump < 0 || isapnpjump > i) {
883 isapnpjump = reverse ? i : 0;
884 printk(KERN_ERR "sb: Valid range for isapnpjump is 0-%d. Adjusted to %d.\n", i, isapnpjump);
885 }
886
887 if(!first || !reverse)
888 i = isapnpjump;
889 first = 0;
890 while(sb_isapnp_list[i].card_vendor != 0) {
891 static struct pci_bus *bus = NULL;
892
893 while ((bus = isapnp_find_card(
894 sb_isapnp_list[i].card_vendor,
895 sb_isapnp_list[i].card_device,
896 bus))) {
897
898 if(sb_isapnp_init(hw_config, mpu_config, bus, i, card)) {
899 isapnpjump = i; /* start next search from here */
900 return 0;
901 }
902 }
903 i += reverse ? -1 : 1;
904 }
905
906 return -ENODEV;
907 }
908 #endif
909
init_sb(void)910 static int __init init_sb(void)
911 {
912 int card, max = (multiple && isapnp) ? SB_CARDS_MAX : 1;
913
914 printk(KERN_INFO "Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
915
916 for(card = 0; card < max; card++, sb_cards_num++) {
917 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
918 /* Please remember that even with CONFIG_ISAPNP defined one
919 * should still be able to disable PNP support for this
920 * single driver! */
921 if((!pnplegacy||card>0) && isapnp && (sb_isapnp_probe(&cfg[card], &cfg_mpu[card], card) < 0) ) {
922 if(!sb_cards_num) {
923 /* Found no ISAPnP cards, so check for a non-pnp
924 * card and set the detection loop for 1 cycle
925 */
926 printk(KERN_NOTICE "sb: No ISAPnP cards found, trying standard ones...\n");
927 isapnp = 0;
928 max = 1;
929 } else
930 /* found all the ISAPnP cards so exit the
931 * detection loop. */
932 break;
933 }
934 #endif
935
936 if(!isapnp || (pnplegacy&&card==0)) {
937 cfg[card].io_base = io;
938 cfg[card].irq = irq;
939 cfg[card].dma = dma;
940 cfg[card].dma2 = dma16;
941 }
942
943 cfg[card].card_subtype = type;
944
945 if (!probe_sb(&cfg[card])) {
946 /* if one or more cards already registered, don't
947 * return an error but print a warning. Note, this
948 * should never really happen unless the hardware
949 * or ISAPnP screwed up. */
950 if (sb_cards_num) {
951 printk(KERN_WARNING "sb.c: There was a " \
952 "problem probing one of your SoundBlaster " \
953 "ISAPnP soundcards. Continuing.\n");
954 card--;
955 sb_cards_num--;
956 continue;
957 } else if(pnplegacy && isapnp) {
958 printk(KERN_NOTICE "sb: No legacy SoundBlaster cards " \
959 "found. Continuing with PnP detection.\n");
960 pnplegacy=0;
961 card--;
962 continue;
963 } else
964 return -ENODEV;
965 }
966 attach_sb_card(&cfg[card]);
967
968 if(cfg[card].slots[0]==-1) {
969 if(card==0 && pnplegacy && isapnp) {
970 printk(KERN_NOTICE "sb: No legacy SoundBlaster cards " \
971 "found. Continuing with PnP detection.\n");
972 pnplegacy=0;
973 card--;
974 continue;
975 } else
976 return -ENODEV;
977 }
978
979 if (!isapnp||(pnplegacy&&card==0))
980 cfg_mpu[card].io_base = mpu_io;
981 if (probe_sbmpu(&cfg_mpu[card], THIS_MODULE))
982 sbmpu[card] = 1;
983 }
984
985 if(isapnp)
986 printk(KERN_NOTICE "sb: %d Soundblaster PnP card(s) found.\n", sb_cards_num);
987
988 return 0;
989 }
990
cleanup_sb(void)991 static void __exit cleanup_sb(void)
992 {
993 int i;
994
995 if (smw_free) {
996 vfree(smw_free);
997 smw_free = NULL;
998 }
999
1000 for(i = 0; i < sb_cards_num; i++) {
1001 unload_sb(&cfg[i], i);
1002 if (sbmpu[i])
1003 unload_sbmpu(&cfg_mpu[i]);
1004
1005 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
1006 if(!audio_activated[i] && sb_dev[i])
1007 sb_dev[i]->deactivate(sb_dev[i]);
1008 if(!mpu_activated[i] && mpu_dev[i])
1009 mpu_dev[i]->deactivate(mpu_dev[i]);
1010 if(!opl_activated[i] && opl_dev[i])
1011 opl_dev[i]->deactivate(opl_dev[i]);
1012 #endif
1013 }
1014 }
1015
1016 module_init(init_sb);
1017 module_exit(cleanup_sb);
1018
1019 #ifndef MODULE
setup_sb(char * str)1020 static int __init setup_sb(char *str)
1021 {
1022 /* io, irq, dma, dma2 - just the basics */
1023 int ints[5];
1024
1025 str = get_options(str, ARRAY_SIZE(ints), ints);
1026
1027 io = ints[1];
1028 irq = ints[2];
1029 dma = ints[3];
1030 dma16 = ints[4];
1031
1032 return 1;
1033 }
1034 __setup("sb=", setup_sb);
1035 #endif
1036