]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.50 2.3.50
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:32:33 +0000 (15:32 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:32:33 +0000 (15:32 -0500)
59 files changed:
Documentation/usb/usb-serial.txt
drivers/sound/Config.in
drivers/sound/Makefile
drivers/sound/ad1816.c
drivers/sound/ad1848.c
drivers/sound/ad1848.h [new file with mode: 0644]
drivers/sound/adlib_card.c
drivers/sound/cs4232.c
drivers/sound/cs4232.h [new file with mode: 0644]
drivers/sound/dev_table.c
drivers/sound/dev_table.h
drivers/sound/gus.h [new file with mode: 0644]
drivers/sound/gus_card.c
drivers/sound/gus_midi.c
drivers/sound/gus_vol.c
drivers/sound/gus_wave.c
drivers/sound/ics2101.c
drivers/sound/mad16.c
drivers/sound/maui.c
drivers/sound/mpu401.c
drivers/sound/mpu401.h [new file with mode: 0644]
drivers/sound/nm256_audio.c
drivers/sound/opl3.c
drivers/sound/opl3.h
drivers/sound/opl3_hw.h [new file with mode: 0644]
drivers/sound/opl3sa.c
drivers/sound/opl3sa2.c
drivers/sound/pas2.h [new file with mode: 0644]
drivers/sound/pas2_card.c
drivers/sound/pas2_midi.c
drivers/sound/pas2_mixer.c
drivers/sound/pas2_pcm.c
drivers/sound/pss.c
drivers/sound/sb.h
drivers/sound/sb_card.c
drivers/sound/sb_common.c
drivers/sound/sgalaxy.c
drivers/sound/softoss.c
drivers/sound/sound_calls.h
drivers/sound/sound_config.h
drivers/sound/sound_syms.c
drivers/sound/soundcard.c
drivers/sound/soundmodule.h
drivers/sound/sscape.c
drivers/sound/trix.c
drivers/sound/uart401.c
drivers/sound/uart6850.c
drivers/sound/v_midi.c
drivers/sound/via82cxxx_audio.c
drivers/sound/vidc.c
drivers/sound/waveartist.c
drivers/sound/wavfront.c
drivers/sound/wf_midi.c
drivers/usb/acm.c
drivers/usb/keyspan_pda_fw.h [new file with mode: 0644]
drivers/usb/usb-serial.c
drivers/usb/usb-serial.h
ipc/sem.c
kernel/ksyms.c

index 2a022f506227604b00ea34e64909c6bcb8d8ce1e..58f3cf108a439ae67d07235a8265443cbecad6e6 100644 (file)
@@ -67,6 +67,32 @@ Current status:
   http://usbvisor.sourceforge.net/
 
 
+Keyspan PDA Serial Adapter
+
+  Single port DB-9 serial adapter, pushed as a PDA adapter for iMacs (mostly
+  sold in Macintosh catalogs, comes in a translucent white/green dongle).
+  Fairly simple device. Firmware is homebrew.
+
+Current status:
+ Things that work:
+   basic input/output (tested with 'cu')
+   blocking write when serial line can't keep up
+   changing baud rates (up to 115200)
+   getting/setting modem control pins (TIOCM{GET,SET,BIS,BIC})
+   sending break (although duration looks suspect)
+ Things that don't:
+   device strings (as logged by kernel) have trailing binary garbage
+   device ID isn't right, might collide with other Keyspan products
+   changing baud rates ought to flush tx/rx to avoid mangled half characters
+ Big Things on the todo list:
+   parity, 7 vs 8 bits per char, 1 or 2 stop bits
+   HW flow control
+   not all of the standard USB descriptors are handled: Get_Status, Set_Feature
+   O_NONBLOCK, select()
+
+ The device usually appears at /dev/ttyUSB1 .
+
+
 Generic Serial driver
 
   If your device is not one of the above listed devices, compatible with
index c218ca69dc39468013edb9878c0214256a42afcb..30ffe5cc089a03426c57035125baf1bba6907f25 100644 (file)
@@ -81,79 +81,21 @@ fi
 dep_tristate '  OSS sound modules' CONFIG_SOUND_OSS $CONFIG_SOUND
 
 if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
-   if [ "$CONFIG_SOUND_OSS" = "y" ]; then
-      bool '    Persistent DMA buffers' CONFIG_SOUND_DMAP
-   fi
-
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
       dep_tristate '    AD1816(A) based cards (EXPERIMENTAL)' CONFIG_SOUND_AD1816 $CONFIG_SOUND
-      if [ "$CONFIG_SOUND_AD1816" = "y" ]; then
-        hex 'AD1816 audio I/O base 530, 604, E80 or F40' CONFIG_AD1816_BASE 530
-        int 'AD1816 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_AD1816_IRQ 7
-        int 'AD1816 audio DMA 0, 1 or 3' CONFIG_AD1816_DMA 0
-        int 'AD1816 second (duplex) DMA 0, 1 or 3' CONFIG_AD1816_DMA2 3
-        int 'AD1816 clock chip frequency' CONFIG_AD1816_CLOCK 33000
-      fi
    fi
 
    dep_tristate '    Aztech Sound Galaxy (non-PnP) cards' CONFIG_SOUND_SGALAXY $CONFIG_SOUND_OSS
-   if [ "$CONFIG_SOUND_SGALAXY" = "y" ]; then
-      hex 'SGALAXY audio I/O base 530, 604, E80 or F40' CONFIG_SGALAXY_BASE 530
-      int 'SGALAXY audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_SGALAXY_IRQ 11
-      int 'SGALAXY audio DMA 0, 1 or 3' CONFIG_SGALAXY_DMA 0
-      int 'SGALAXY second (duplex) DMA 0, 1 or 3' CONFIG_SGALAXY_DMA2 3
-      hex 'SGALAXY SB I/O base 220 or 240' CONFIG_SGALAXY_SGBASE 220
-   fi
-
    dep_tristate '    Crystal CS4232 based (PnP) cards' CONFIG_SOUND_CS4232 $CONFIG_SOUND_OSS
-   if [ "$CONFIG_SOUND_CS4232" = "y" ]; then
-      hex 'CS4232 audio I/O base (normally 530, 604, E80 or F40)' CONFIG_CS4232_BASE 530
-      int 'CS4232 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_IRQ 11
-      int 'CS4232 audio DMA 0, 1 or 3' CONFIG_CS4232_DMA 0
-      int 'CS4232 second (duplex) DMA 0, 1 or 3' CONFIG_CS4232_DMA2 3
-      hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_CS4232_MPU_BASE 330
-      int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_MPU_IRQ 9
-   fi
-
    dep_tristate '    Ensoniq SoundScape support' CONFIG_SOUND_SSCAPE $CONFIG_SOUND_OSS
-   if [ "$CONFIG_SOUND_SSCAPE" = "y" ]; then
-      hex 'SoundScape MIDI I/O base 320, 330, 340 or 350' CONFIG_SSCAPE_BASE 330
-      int 'SoundScape MIDI IRQ ' CONFIG_SSCAPE_IRQ 9
-      int 'SoundScape initialization DMA 0, 1 or 3' CONFIG_SSCAPE_DMA 3
-      hex 'SoundScape audio I/O base 534, 608, E84 or F44' CONFIG_SSCAPE_MSS_BASE 534
-      int 'SoundScape audio IRQ 7, 9, 10 or 11' CONFIG_SSCAPE_MSS_IRQ 11
-   fi
-
    dep_tristate '    Gravis Ultrasound support' CONFIG_SOUND_GUS $CONFIG_SOUND_OSS
-   if [ "$CONFIG_SOUND_GUS" = "y" -o "$CONFIG_SOUND_GUS" = "m" ]; then
-      bool '      16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16 
-      bool '      GUS MAX support' CONFIG_GUSMAX
+   if [ "$CONFIG_SOUND_GUS" != "n" ]; then
+      bool '      16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_SOUND_GUS16 
+      bool '      GUS MAX support' CONFIG_SOUND_GUSMAX
    fi
-   if [ "$CONFIG_SOUND_GUS" = "y" ]; then
-      hex 'I/O base for GUS 210, 220, 230, 240, 250 or 260' CONFIG_GUS_BASE 220
-      int 'GUS IRQ 3, 5, 7, 9, 11, 12 or 15' CONFIG_GUS_IRQ 15
-      int 'GUS DMA 1, 3, 5, 6 or 7' CONFIG_GUS_DMA 6
-      int 'Second DMA channel for GUS 1, 3, 5, 6 or 7' CONFIG_GUS_DMA2 -1
-      if [ "$CONFIG_GUS16" = "y" ]; then
-        hex 'I/O base for the 16 bit daughtercard of GUS 530, 604, E80 or F40' CONFIG_GUS16_BASE 530
-        int 'GUS 16 bit daughtercard IRQ 3, 4, 5, 7, or 9' CONFIG_GUS16_IRQ 7
-        int 'GUS DMA 0, 1 or 3' CONFIG_GUS16_DMA 3
-      fi
-   fi
-
    dep_tristate '    Loopback MIDI device support' CONFIG_SOUND_VMIDI $CONFIG_SOUND_OSS
-
    dep_tristate '    MediaTrix AudioTrix Pro support' CONFIG_SOUND_TRIX $CONFIG_SOUND_OSS
    if [ "$CONFIG_SOUND_TRIX" = "y" ]; then
-      hex 'TRIX audio I/O base 530, 604, E80 or F40' CONFIG_TRIX_BASE 530
-      int 'TRIX audio IRQ 7, 9, 10 or 11' CONFIG_TRIX_IRQ 11
-      int 'TRIX audio DMA 0, 1 or 3' CONFIG_TRIX_DMA 0
-      int 'TRIX second (duplex) DMA 0, 1 or 3' CONFIG_TRIX_DMA2 3
-      hex 'TRIX MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_TRIX_MPU_BASE 330
-      int 'TRIX MIDI IRQ 3, 4, 5, 7 or 9' CONFIG_TRIX_MPU_IRQ 9
-      hex 'TRIX SB I/O base 220, 210, 230, 240, 250, 260 or 270' CONFIG_TRIX_SB_BASE 220
-      int 'TRIX SB IRQ 3, 4, 5 or 7' CONFIG_TRIX_SB_IRQ 7
-      int 'TRIX SB DMA 1 or 3' CONFIG_TRIX_SB_DMA 1
       bool '      Have TRXPRO.HEX firmware file' CONFIG_TRIX_HAVE_BOOT
       if [ "$CONFIG_TRIX_HAVE_BOOT" = "y" ]; then
        string '  Full pathname of TRXPRO.HEX firmware file' CONFIG_TRIX_BOOT_FILE /etc/sound/trxpro.hex
@@ -161,58 +103,23 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
    fi
   
    dep_tristate '    Microsoft Sound System support' CONFIG_SOUND_MSS $CONFIG_SOUND_OSS
-   if [ "$CONFIG_SOUND_MSS" = "y" ]; then
-      bool '      Enable support for the SoundPro mixer' CONFIG_SOUND_SPRO
-      hex 'MSS/WSS I/O base 530, 604, E80 or F40' CONFIG_MSS_BASE 530
-      int 'MSS/WSS IRQ 7, 9, 10 or 11' CONFIG_MSS_IRQ 11
-      int 'MSS/WSS DMA 0, 1 or 3' CONFIG_MSS_DMA 3
-      int 'MSS/WSS second DMA (if possible) 0, 1 or 3' CONFIG_MSS_DMA2 -1
-   fi
-
    dep_tristate '    MPU-401 support (NOT for SB16)' CONFIG_SOUND_MPU401 $CONFIG_SOUND_OSS
-   if [ "$CONFIG_SOUND_MPU401" = "y" ]; then
-      hex 'I/O base for MPU401 Check from manual of the card' CONFIG_MPU_BASE 330
-      int 'MPU401 IRQ Check from manual of the card' CONFIG_MPU_IRQ 9
-   fi
-
    dep_tristate '    NM256AV/NM256ZX audio support' CONFIG_SOUND_NM256 $CONFIG_SOUND_OSS
-
    dep_tristate '    OPTi MAD16 and/or Mozart based cards' CONFIG_SOUND_MAD16 $CONFIG_SOUND_OSS
    if [ "$CONFIG_SOUND_MAD16" = "y" -o "$CONFIG_SOUND_MAD16" = "m" ]; then
      bool '      Support MIDI in older MAD16 based cards (requires SB)' CONFIG_MAD16_OLDCARD
    fi
-   if [ "$CONFIG_SOUND_MAD16" = "y" ]; then
-      hex 'MAD16 audio I/O base 530, 604, E80 or F40' CONFIG_MAD16_BASE 530
-      int 'MAD16 audio IRQ 7, 9, 10 or 11' CONFIG_MAD16_IRQ 11
-      int 'MAD16 audio DMA 0, 1 or 3' CONFIG_MAD16_DMA 3
-      int 'MAD16 second (duplex) DMA 0, 1 or 3' CONFIG_MAD16_DMA2 0
-      hex 'MAD16 MIDI I/O base 300, 310, 320 or 330 (0 disables)' CONFIG_MAD16_MPU_BASE 330
-      int 'MAD16 MIDI IRQ 5, 7, 9 or 10' CONFIG_MAD16_MPU_IRQ 9
-   fi
-
    dep_tristate '    ProAudioSpectrum 16 support' CONFIG_SOUND_PAS $CONFIG_SOUND_OSS
-   if [ "$CONFIG_SOUND_PAS" = "y" ]; then
-      int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' CONFIG_PAS_IRQ 10
-      int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' CONFIG_PAS_DMA 3
-      bool '      Enable PAS16 joystick port' CONFIG_PAS_JOYSTICK
-   fi
+   dep_bool '      Enable PAS16 joystick port' CONFIG_PAS_JOYSTICK $CONFIG_SOUND_PAS
 
    dep_tristate '    PSS (AD1848, ADSP-2115, ESC614) support' CONFIG_SOUND_PSS $CONFIG_SOUND_OSS
-   if [ "$CONFIG_SOUND_PSS" = "y" ]; then
-      hex 'PSS I/O base 220 or 240' CONFIG_PSS_BASE 220
-      hex 'PSS audio I/O base 530, 604, E80 or F40' CONFIG_PSS_MSS_BASE 530
-      int 'PSS audio IRQ 7, 9, 10 or 11' CONFIG_PSS_MSS_IRQ 11
-      int 'PSS audio DMA 0, 1 or 3' CONFIG_PSS_MSS_DMA 3
-      hex 'PSS MIDI I/O base ' CONFIG_PSS_MPU_BASE 330
-      int 'PSS MIDI IRQ 3, 4, 5, 7, 9, 10, 11, 12' CONFIG_PSS_MPU_IRQ 9
-      bool '      Have DSPxxx.LD firmware file' CONFIG_PSS_HAVE_BOOT
-      if [ "$CONFIG_PSS_HAVE_BOOT" = "y" ]; then
-         string '  Full pathname of DSPxxx.LD firmware file' CONFIG_PSS_BOOT_FILE /etc/sound/dsp001.ld
-      fi
-   fi
    if [ "$CONFIG_SOUND_PSS" = "y" -o "$CONFIG_SOUND_PSS" = "m" ]; then
       bool '      Enable PSS mixer (Beethoven ADSP-16 and other compatibile)' CONFIG_PSS_MIXER
    fi
+   bool '      Have DSPxxx.LD firmware file' CONFIG_PSS_HAVE_BOOT
+   if [ "$CONFIG_PSS_HAVE_BOOT" = "y" ]; then
+      string '  Full pathname of DSPxxx.LD firmware file' CONFIG_PSS_BOOT_FILE /etc/sound/dsp001.ld
+   fi
 
    dep_tristate '    SoftOSS software wave table engine' CONFIG_SOUND_SOFTOSS $CONFIG_SOUND_OSS
    if [ "$CONFIG_SOUND_SOFTOSS" = "y" ]; then
@@ -221,27 +128,9 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
    fi
   
    dep_tristate '    100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SOUND_SB $CONFIG_SOUND_OSS
-   if [ "$CONFIG_SOUND_SB" = "y" ]; then
-      hex 'I/O base for SB Check from manual of the card' CONFIG_SB_BASE 220
-      int 'Sound Blaster IRQ Check from manual of the card' CONFIG_SB_IRQ 7
-      int 'Sound Blaster DMA 0, 1 or 3' CONFIG_SB_DMA 1
-      int 'Sound Blaster 16 bit DMA (SB16, Jazz16, SMW) 5, 6 or 7 (use 1 for 8 bit cards)' CONFIG_SB_DMA2 5
-      hex 'MPU401 I/O base of SB16, Jazz16 and ES1688 Check from manual of the card' CONFIG_SB_MPU_BASE 330
-      comment 'MPU401 IRQ is only required with Jazz16, SM Wave and ESS1688.'
-      comment 'Enter -1 to the following question if you have something else such as SB16/32.'
-      int 'SB MPU401 IRQ (Jazz16, SM Wave and ES1688) Check from manual of the card' CONFIG_SB_MPU_IRQ -1
-   fi
-  
    dep_tristate '    Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards' CONFIG_SOUND_WAVEFRONT $CONFIG_SOUND_OSS m
-   if [ "$CONFIG_SOUND_WAVEFRONT" = "y" ]; then
-      hex 'I/O base for WaveFront 210, 230, 260, 290, 300, 320, 338 or 330' CONFIG_WAVEFRONT_BASE 330
-      int 'WaveFront IRQ 5, 9, 12 or 15' CONFIG_WAVEFRONT_IRQ 9
-   fi
-
    dep_tristate '    Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_SOUND_MAUI $CONFIG_SOUND_OSS
    if [ "$CONFIG_SOUND_MAUI" = "y" ]; then
-      hex 'I/O base for Maui 210, 230, 260, 290, 300, 320, 338 or 330' CONFIG_MAUI_BASE 330
-      int 'Maui IRQ 5, 9, 12 or 15' CONFIG_MAUI_IRQ 9
       bool '      Have OSWF.MOT firmware file' CONFIG_MAUI_HAVE_BOOT
       if [ "$CONFIG_MAUI_HAVE_BOOT" = "y" ]; then
         string '  Full pathname of OSWF.MOT firmware file' CONFIG_MAUI_BOOT_FILE /etc/sound/oswf.mot
@@ -249,47 +138,14 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
    fi
 
    dep_tristate '    VIA 82C686 Audio Codec' CONFIG_SOUND_VIA82CXXX $CONFIG_SOUND_OSS
-
    dep_tristate '    Yamaha FM synthesizer (YM3812/OPL-3) support' CONFIG_SOUND_YM3812 $CONFIG_SOUND_OSS
    dep_tristate '    Yamaha OPL3-SA1 audio controller' CONFIG_SOUND_OPL3SA1 $CONFIG_SOUND_OSS
-   if [ "$CONFIG_SOUND_OPL3SA1" = "y" ]; then
-      hex 'OPL3-SA1 audio I/O base 530, 604, E80 or F40' CONFIG_OPL3SA1_BASE 530
-      int 'OPL3-SA1 audio IRQ 7, 9, 10 or 11' CONFIG_OPL3SA1_IRQ 11
-      int 'OPL3-SA1 audio DMA 0, 1 or 3' CONFIG_OPL3SA1_DMA 0
-      int 'OPL3-SA1 second (duplex) DMA 0, 1 or 3' CONFIG_OPL3SA1_DMA2 3
-      hex 'OPL3-SA1 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_OPL3SA1_MPU_BASE 330
-      int 'OPL3-SA1 MIDI IRQ 3, 4, 5, 7 or 9' CONFIG_OPL3SA1_MPU_IRQ 9
-   fi
-  
    dep_tristate '    Yamaha OPL3-SA2, SA3, and SAx based PnP cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS
-   if [ "$CONFIG_SOUND_OPL3SA2" = "y" ]; then
-      int 'Chipset (-1 for autoprobe, 2, or 3)' CONFIG_OPL3SA2_CHIPSET -1
-      hex 'OPL3SA2 audio I/O base (530 - F48 valid)' CONFIG_OPL3SA2_BASE 530
-      int 'OPL3SA2 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_IRQ 9
-      int 'OPL3SA2 audio DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA 0
-      int 'OPL3SA2 second (duplex) DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA2 1
-      hex 'OPL3SA2 control I/O base (100 - FFE valid)' CONFIG_OPL3SA2_CTRL_BASE 370
-      hex 'OPL3SA2 MIDI I/O base (300 - 334 valid)' CONFIG_OPL3SA2_MPU_BASE 330
-      int 'OPL3SA2 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_MPU_IRQ 9
-   fi
-  
-  
    dep_tristate '    6850 UART support' CONFIG_SOUND_UART6850 $CONFIG_SOUND_OSS
-   if [ "$CONFIG_SOUND_UART6850" = "y" ]; then
-      hex 'I/O base for UART 6850 MIDI port (Unknown)' CONFIG_U6850_BASE 0
-      int 'UART6850 IRQ (Unknown)' CONFIG_U6850_IRQ -1
-   fi
   
    if [ "$CONFIG_ARM" = "y" ]; then
       dep_tristate '    VIDC 16-bit sound' CONFIG_SOUND_VIDC $CONFIG_SOUND_OSS
       dep_tristate '    Netwinder WaveArtist' CONFIG_SOUND_WAVEARTIST $CONFIG_SOUND_OSS
-      if [ "$CONFIG_SOUND_WAVEARTIST" != "n" ]; then
-        hex '    WaveArtist I/O base' CONFIG_WAVEARTIST_BASE 250
-        int '  WaveArtist IRQ' CONFIG_WAVEARTIST_IRQ 12
-        int '  WaveArtist DMA' CONFIG_WAVEARTIST_DMA 3
-        int '  WaveArtist second DMA' CONFIG_WAVEARTIST_DMA2 7
-      fi
    fi
   
   
index 41b55ea4c1881f1cb684f80c3dad13aa2c6d9fcb..2c5df3f1477e96c66c944eb5a3644ce7f398d2b0 100644 (file)
@@ -23,7 +23,7 @@ endif
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
 
 export-objs    :=  ad1848.o audio_syms.o midi_syms.o mpu401.o \
-                   msnd.o opl3.o sb_card.o sequencer_syms.o \
+                   msnd.o opl3.o sb_common.o sequencer_syms.o \
                    sound_core.o sound_syms.o uart401.o ad1816.o \
                    nm256_audio.o ac97.o ac97_codec.o
 
@@ -45,39 +45,36 @@ obj-$(CONFIG_DMASOUND)              += dmasound.o
 obj-$(CONFIG_SOUND_OSS)                += sound.o
 obj-$(CONFIG_SOUND_CS4232)     += cs4232.o ad1848.o 
 
-# In theory, there's probably no reason to include the uart401 code
-# to support a WaveFront card's CS4232 module. However, it makes
-# reconfiguring things require a recompile, so just leave this
-# here and try not to worry about the extra uart401 module.
+# Please leave it as is, cause the link order is significant !
 
-obj-$(CONFIG_SOUND_CS4232)     += uart401.o
+obj-$(CONFIG_SOUND_PSS)                += pss.o ad1848.o mpu401.o
+obj-$(CONFIG_SOUND_TRIX)       += trix.o ad1848.o sb_lib.o uart401.o
+obj-$(CONFIG_SOUND_OPL3SA1)     += opl3sa.o ad1848.o uart401.o
+obj-$(CONFIG_SOUND_SOFTOSS)     += softoss2.o
+obj-$(CONFIG_SOUND_SSCAPE)      += sscape.o ad1848.o mpu401.o
+obj-$(CONFIG_SOUND_MAD16)       += mad16.o ad1848.o sb_lib.o uart401.o
+obj-$(CONFIG_SOUND_CS4232)     += cs4232.o uart401.o
+obj-$(CONFIG_SOUND_OPL3SA2)     += opl3sa2.o ad1848.o uart401.o mpu401.o
+obj-$(CONFIG_SOUND_MSS)         += ad1848.o
+obj-$(CONFIG_SOUND_PAS)         += pas2.o sb_lib.o uart401.o
+obj-$(CONFIG_SOUND_SB)          += sb.o sb_lib.o uart401.o
+obj-$(CONFIG_SOUND_WAVEFRONT)   += wavefront.o
+obj-$(CONFIG_SOUND_MAUI)        += maui.o mpu401.o
+obj-$(CONFIG_SOUND_MPU401)      += mpu401.o
+obj-$(CONFIG_SOUND_UART6850)    += uart6850.o
 obj-$(CONFIG_SOUND_GUS)                += gus.o ad1848.o
-obj-$(CONFIG_SOUND_MAD16)      += mad16.o ad1848.o sb.o uart401.o
-obj-$(CONFIG_SOUND_VIA82CXXX)  += via82cxxx_audio.o sb.o uart401.o ac97.o
-obj-$(CONFIG_SOUND_MAUI)       += maui.o mpu401.o
-obj-$(CONFIG_SOUND_MPU401)     += mpu401.o
+obj-$(CONFIG_SOUND_YM3812)      += adlib_card.o opl3.o
+obj-$(CONFIG_SOUND_VMIDI)       += v_midi.o
+obj-$(CONFIG_SOUND_VIDC)        += vidc_mod.o
+obj-$(CONFIG_SOUND_WAVEARTIST)  += waveartist.o
+obj-$(CONFIG_SOUND_SGALAXY)     += sgalaxy.o ad1848.o
+obj-$(CONFIG_SOUND_AD1816)      += ad1816.o
+
+obj-$(CONFIG_SOUND_VIA82CXXX)  += via82cxxx_audio.o sb_lib.o uart401.o ac97.o
 obj-$(CONFIG_SOUND_MSNDCLAS)   += msnd.o msnd_classic.o
 obj-$(CONFIG_SOUND_MSNDPIN)    += msnd.o msnd_pinnacle.o
-obj-$(CONFIG_SOUND_MSS)                += ad1848.o
-obj-$(CONFIG_SOUND_OPL3SA1)    += opl3sa.o ad1848.o uart401.o
-obj-$(CONFIG_SOUND_OPL3SA2)    += opl3sa2.o ad1848.o uart401.o mpu401.o
-obj-$(CONFIG_SOUND_PAS)                += pas2.o sb.o uart401.o
-obj-$(CONFIG_SOUND_PSS)                += pss.o ad1848.o mpu401.o
-obj-$(CONFIG_SOUND_SB)         += sb.o uart401.o
-obj-$(CONFIG_SOUND_SOFTOSS)    += softoss2.o
-obj-$(CONFIG_SOUND_SGALAXY)    += sgalaxy.o ad1848.o
-obj-$(CONFIG_SOUND_AD1816)     += ad1816.o
-obj-$(CONFIG_SOUND_SSCAPE)     += sscape.o ad1848.o mpu401.o
-obj-$(CONFIG_SOUND_TRIX)       += trix.o ad1848.o sb.o uart401.o
-obj-$(CONFIG_SOUND_UART6850)   += uart6850.o
-obj-$(CONFIG_SOUND_VMIDI)      += v_midi.o
-obj-$(CONFIG_SOUND_YM3812)     += adlib_card.o opl3.o
-obj-$(CONFIG_SOUND_VIDC)       += vidc_mod.o
 obj-$(CONFIG_SOUND_VWSND)      += vwsnd.o
-obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o
-obj-$(CONFIG_SOUND_WAVEFRONT)   += wavefront.o
-obj-$(CONFIG_SOUND_NM256)      += nm256.o
-
+obj-$(CONFIG_SOUND_NM256)      += nm256_audio.o ac97.o
 obj-$(CONFIG_SOUND_SONICVIBES) += sonicvibes.o
 obj-$(CONFIG_SOUND_CMPCI)      += cmpci.o
 obj-$(CONFIG_SOUND_ES1370)     += es1370.o
@@ -89,7 +86,7 @@ obj-$(CONFIG_SOUND_TRIDENT)   += trident.o ac97_codec.o
 # Declare multi-part drivers.
 
 list-multi     := sound.o gus.o pas2.o sb.o softoss2.o vidc_mod.o \
-    soundcore.o wavefront.o nm256.o
+    soundcore.o wavefront.o
 
 sound-objs     :=                                                      \
     dev_table.o soundcard.o sound_syms.o               \
@@ -101,12 +98,11 @@ soundcore-objs     := sound_core.o sound_firmware.o
 
 gus-objs       := gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o
 pas2-objs      := pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
-sb-objs                := sb_audio.o sb_card.o sb_common.o sb_midi.o sb_mixer.o        \
-                          sb_ess.o
+sb-objs                := sb_card.o
+sb_lib-objs    := sb_common.o sb_audio.o sb_midi.o sb_mixer.o sb_ess.o
 softoss2-objs  := softoss.o softoss_rs.o
 vidc_mod-objs  := vidc.o vidc_fill.o
 wavefront-objs  := wavfront.o wf_midi.o yss225.o
-nm256-objs     := nm256_audio.o ac97.o
 
 
 # Extract lists of the multi-part drivers.
@@ -125,20 +121,6 @@ obj-m              := $(filter-out $(obj-y), $(obj-m))
 int-m          := $(filter-out $(int-y), $(int-m))
 
 
-
-# Set flags for secondary drivers.
-# I have to do this before I reduce obj-y to components.
-
-EXTRA_CFLAGS   := $(sort                                       \
-    $(patsubst ad1848.o,  -DCONFIG_SOUND_AD1848,               \
-    $(patsubst mpu401.o,  -DCONFIG_SOUND_MPU_EMU,              \
-    $(patsubst sb.o,      -DCONFIG_SOUND_SBDSP,                        \
-    $(patsubst uart401.o, -DCONFIG_SOUND_UART401,              \
-       $(filter ad1848.o mpu401.o sb.o uart401.o, $(obj-y))    \
-    )))))
-
-
-
 # Take multi-part drivers out of obj-y and put components in.
 
 obj-y          := $(filter-out $(list-multi), $(obj-y)) $(int-y)
@@ -155,8 +137,8 @@ O_OBJS              := $(filter-out $(export-objs), $(obj-y))
 OX_OBJS                := $(filter     $(export-objs), $(obj-y))
 M_OBJS         := $(sort $(filter-out $(export-objs), $(obj-m)))
 MX_OBJS                := $(sort $(filter     $(export-objs), $(obj-m)))
-MI_OBJS                := $(sort $(filter-out $(export-objs), $(int-m)))
-MIX_OBJS       := $(sort $(filter     $(export-objs), $(int-m)))
+#MI_OBJS               := $(sort $(filter-out $(export-objs), $(int-m)))
+#MIX_OBJS      := $(sort $(filter     $(export-objs), $(int-m)))
 
 ifeq ($(CONFIG_LOWLEVEL_SOUND),y)
     O_OBJS     += lowlevel/lowlevel.o
@@ -183,6 +165,9 @@ pas2.o: $(pas2-objs)
 sb.o: $(sb-objs)
        $(LD) -r -o $@ $(sb-objs)
 
+sb_lib.o: $(sb_lib-objs)
+       $(LD) -r -o $@ $(sb_lib-objs)
+
 softoss2.o: $(softoss2-objs)
        $(LD) -r -o $@ $(softoss2-objs)
 
@@ -192,9 +177,6 @@ vidc_mod.o: $(vidc_mod-objs)
 wavefront.o: $(wavefront-objs)
        $(LD) -r -o $@ $(wavefront-objs)
 
-nm256.o: $(nm256-objs)
-       $(LD) -r -o $@ $(nm256-objs)
-
 # Firmware files that need translation
 #
 # The translated files are protected by a file that keeps track
index 8813d519e2676728501003ee683f2ad10626af0f..d44cf1389d49afa6a7e2896e6c4e3bd14f650eb1 100644 (file)
@@ -1,59 +1,43 @@
 /*
-
-AD1816 lowlevel sound driver for Linux 2.2.0 and above
-
-Copyright (C) 1998 by Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de>
-Based on the CS4232/AD1848 driver Copyright (C) by Hannu Savolainen 1993-1996
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
--------------------------------------------------------------------------------
-NOTE!   NOTE!   NOTE!   NOTE!   NOTE!   NOTE!   NOTE!   NOTE!   NOTE!
-
-This software is still under development. New versions of the driver 
-are available from:
-  http://www.student.informatik.tu-darmstadt.de/~tek/projects/linux.html
-or
-  http://www.tu-darmstadt.de/~tek01/projects/linux.html
-
-Please report any bugs to: tek@rbg.informatik.tu-darmstadt.de
-
--------------------------------------------------------------------------------
-
-version: 1.3
-cvs: $Header: /home/tek/CVSROOT/sound22/ad1816.c,v 1.3 1999/04/18 16:41:41 tek Exp $
-status: experimental
-date: 1999/4/18
-
-Changes:
-       Oleg Drokin: Some cleanup of load/unload functions.    1998/11/24
-       
-       Thorsten Knabe: attach and unload rewritten, 
-       some argument checks added                             1998/11/30
-
-       Thorsten Knabe: Buggy isa bridge workaround added      1999/01/16
-       
-       David Moews/Thorsten Knabe: Introduced options 
-       parameter. Added slightly modified patch from 
-       David Moews to disable dsp audio sources by setting 
-       bit 0 of options parameter. This seems to be
-       required by some Aztech/Newcom SC-16 cards.            1999/04/18
-       
-*/
+ *
+ * AD1816 lowlevel sound driver for Linux 2.2.0 and above
+ *
+ * Copyright (C) 1998 by Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de>
+ *
+ * Based on the CS4232/AD1848 driver Copyright (C) by Hannu Savolainen 1993-1996
+ *
+ * This software is still under development. New versions of the driver 
+ * are available from:
+ * http://www.student.informatik.tu-darmstadt.de/~tek/projects/linux.html
+ * or http://www.tu-darmstadt.de/~tek01/projects/linux.html
+ * 
+ * Please report any bugs to: tek@rbg.informatik.tu-darmstadt.de
+ *
+ *
+ * version: 1.3
+ * cvs: $Header: /home/tek/CVSROOT/sound22/ad1816.c,v 1.3 1999/04/18 16:41:41 tek Exp $
+ * status: experimental
+ * date: 1999/4/18
+ *
+ * Changes:
+ *     Oleg Drokin: Some cleanup of load/unload functions.     1998/11/24
+ *     
+ *     Thorsten Knabe: attach and unload rewritten, 
+ *     some argument checks added                              1998/11/30
+ *
+ *     Thorsten Knabe: Buggy isa bridge workaround added       1999/01/16
+ *     
+ *     David Moews/Thorsten Knabe: Introduced options 
+ *     parameter. Added slightly modified patch from 
+ *     David Moews to disable dsp audio sources by setting 
+ *     bit 0 of options parameter. This seems to be
+ *     required by some Aztech/Newcom SC-16 cards.             1999/04/18
+ *
+ *     Christoph Hellwig: Adapted to module_init/module_exit.  2000/03/03
+ */
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/stddef.h>
 #include "soundmodule.h"
 #include "sound_config.h"
@@ -96,14 +80,10 @@ typedef struct
        int            irq_ok;
        int            *osp;
   
-}
-
-ad1816_info;
-
-static int  nr_ad1816_devs = 0;
-
-static int  ad1816_clockfreq=33000;
+} ad1816_info;
 
+static int nr_ad1816_devs = 0;
+static int ad1816_clockfreq=33000;
 static int options=0;
 
 /* for backward mapping of irq to sound device */
@@ -617,7 +597,8 @@ static struct audio_driver ad1816_audio_driver =
 
 /* Interrupt handler */
 
-void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
+
+static void ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
 {
        unsigned char   status;
        ad1816_info    *devc;
@@ -1089,7 +1070,7 @@ static struct mixer_operations ad1816_mixer_operations =
 
 
 /* replace with probe routine */
-int probe_ad1816 ( struct address_info *hw_config )
+static int __init probe_ad1816 ( struct address_info *hw_config )
 {
        ad1816_info    *devc = &dev_info[nr_ad1816_devs];
        int io_base=hw_config->io_base;
@@ -1097,7 +1078,6 @@ int probe_ad1816 ( struct address_info *hw_config )
        int tmp;
        
        printk("ad1816: AD1816 sounddriver Copyright (C) 1998 by Thorsten Knabe\n");
-       printk("ad1816: $Header: /home/tek/CVSROOT/sound22/ad1816.c,v 1.3 1999/04/18 16:41:41 tek Exp $\n");
        printk("ad1816: io=0x%x, irq=%d, dma=%d, dma2=%d, clockfreq=%d, options=%d isadmabug=%d\n",
               hw_config->io_base,
               hw_config->irq,
@@ -1183,7 +1163,7 @@ int probe_ad1816 ( struct address_info *hw_config )
   
  */
 
-void attach_ad1816 (struct address_info *hw_config)
+static void __init attach_ad1816 (struct address_info *hw_config)
 {
        int             my_dev;
        char            dev_name[100];
@@ -1309,7 +1289,7 @@ void attach_ad1816 (struct address_info *hw_config)
        }
 }
 
-void unload_card(ad1816_info *devc)
+static void __exit unload_card(ad1816_info *devc)
 {
        int  mixer, dev = 0;
        
@@ -1343,51 +1323,12 @@ void unload_card(ad1816_info *devc)
        }
 }
 
-void unload_ad1816 (struct address_info *hw_config)
-{
-       int          i;
-       ad1816_info  *devc = NULL;
-  
-       /* remove any soundcard */
-       if (hw_config==NULL) {
-               for (i = 0;  i < nr_ad1816_devs; i++) {
-                       devc = &dev_info[i];
-                       unload_card(devc);
-               }     
-               nr_ad1816_devs=0;
-       } else { 
-               /* remove specified soundcard */
-               for (i = 0; i < nr_ad1816_devs; i++) {
-                       int j;
-                       
-                       if (dev_info[i].base == hw_config->io_base) {
-                               devc = &dev_info[i];
-                               unload_card(devc);
-                               nr_ad1816_devs--;
-                               for ( j=i; j < nr_ad1816_devs ; j++) {
-                                       dev_info[j] = dev_info[j+1];
-                               }
-                               i--;
-                       }
-               }
-       }
-}
-
-
-/* ----------------------------- 2.1.xxx module stuff ----------------- */
-
-EXPORT_SYMBOL(ad1816_interrupt);
-EXPORT_SYMBOL(probe_ad1816);
-EXPORT_SYMBOL(attach_ad1816);
-EXPORT_SYMBOL(unload_ad1816);
+static struct address_info cfg;
 
-
-#ifdef MODULE
-
-int             io = -1;
-int             irq = -1;
-int             dma = -1;
-int             dma2 = -1;
+static int __initdata io = -1;
+static int __initdata irq = -1;
+static int __initdata dma = -1;
+static int __initdata dma2 = -1;
 
 MODULE_PARM(io,"i");
 MODULE_PARM(irq,"i");
@@ -1396,33 +1337,59 @@ MODULE_PARM(dma2,"i");
 MODULE_PARM(ad1816_clockfreq,"i");
 MODULE_PARM(options,"i");
 
-struct address_info cfg;
+static int __init init_ad1816(void)
+{
+       cfg.io_base     = io;
+       cfg.irq         = irq;
+       cfg.dma         = dma;
+       cfg.dma2        = dma2;
+
+       if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.dma2 == -1) {
+               printk(KERN_INFO "ad1816: dma, dma2, irq and io must be set.\n");
+               return -EINVAL;
+       }
 
+       if (probe_ad1816(&cfg) == 0) {
+               return -ENODEV;
+       }
+       
+       attach_ad1816(&cfg);
+       SOUND_LOCK;
+}
 
-int init_module(void)
+static void __exit cleanup_ad1816 (void)
 {
-        if (io == -1 || irq == -1 || dma == -1 || dma2 == -1) {
-               printk("ad1816: dma, dma2, irq and io must be set.\n");
-                return -EINVAL;
-        }
-        cfg.io_base = io;
-        cfg.irq = irq;
-        cfg.dma = dma;
-        cfg.dma2 = dma2;
-       
-        if (probe_ad1816(&cfg) == 0) {
-                return -ENODEV;
-       }
-        attach_ad1816(&cfg);
-        SOUND_LOCK;
-        return 0;
+       int          i;
+       ad1816_info  *devc = NULL;
+  
+       /* remove any soundcard */
+       for (i = 0;  i < nr_ad1816_devs; i++) {
+               devc = &dev_info[i];
+               unload_card(devc);
+       }     
+       nr_ad1816_devs=0;
+
+       SOUND_LOCK_END;
 }
 
+module_init(init_ad1816);
+module_exit(cleanup_ad1816);
 
-void cleanup_module(void)
+#ifndef MODULE
+static int __init setup_ad1816(char *str)
 {
-        unload_ad1816(NULL);
-        SOUND_LOCK_END;
+       /* io, irq, dma, dma2 */
+       int ints[5];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io      = ints[1];
+       irq     = ints[2];
+       dma     = ints[3];
+       dma16   = ints[4];
+
+       return 1;
 }
 
-#endif /* MODULE */
+__setup("ad1816=", setup_ad1816);
+#endif
index b7d93fdb4f3ac5e9127092c41e24c7f951d47635..b7ad6f75c8744b1cb65c19a385443f6747f985fa 100644 (file)
  * for more info.
  *
  *
- * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
- *                  general sleep/wakeup clean up.
- * Alan Cox       : reformatted. Fixed SMP bugs. Moved to kernel alloc/free
- *                  of irqs. Use dev_id.
+ * Thomas Sailer       : ioctl code reworked (vmalloc/vfree removed)
+ *                       general sleep/wakeup clean up.
+ * Alan Cox            : reformatted. Fixed SMP bugs. Moved to kernel alloc/free
+ *                       of irqs. Use dev_id.
+ * Christoph Hellwig   : adapted to module_init/module_exit
  *
  * Status:
  *             Tested. Believed fully functional.
  */
 
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/stddef.h>
 
@@ -40,6 +42,8 @@
 #define DEB(x)
 #define DEB1(x)
 #include "sound_config.h"
+
+#include "ad1848.h"
 #include "ad1848_mixer.h"
 
 typedef struct
@@ -99,23 +103,19 @@ ad1848_port_info;
 static int nr_ad1848_devs = 0;
 int deskpro_xl = 0;
 int deskpro_m = 0;
-#ifdef CONFIG_SOUND_SPRO
-int soundpro = 1;
-#else
 int soundpro = 0;
-#endif
 
 static volatile signed char irq2dev[17] = {
        -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1
 };
 
-#ifdef MODULE
-
+#ifndef EXCLUDE_TIMERS
 static int timer_installed = -1;
-
 #endif
 
+static int loaded = 0;
+
 static int ad_format_mask[10 /*devc->model */ ] =
 {
        0,
@@ -2502,6 +2502,11 @@ void attach_ms_sound(struct address_info *hw_config)
        int dma = hw_config->dma;
        int dma2 = hw_config->dma2;
 
+       if(hw_config->io_base != -1 || hw_config->irq == -1 || hw_config->dma == -1) {
+               printk(KERN_WARNING "ad1848: must give I/O , IRQ and DMA.\n");
+               return;
+       }
+
        if (hw_config->card_subtype == 1)       /* Has no IRQ/DMA registers */
        {
                hw_config->slots[0] = ad1848_init("MS Sound System", hw_config->io_base + 4,
@@ -2568,6 +2573,9 @@ void attach_ms_sound(struct address_info *hw_config)
                                          dma2, 0,
                                          hw_config->osp);
        request_region(hw_config->io_base, 4, "WSS config");
+
+       SOUND_LOCK;
+       loaded = 1;
 }
 
 void unload_ms_sound(struct address_info *hw_config)
@@ -2702,8 +2710,6 @@ EXPORT_SYMBOL(probe_ms_sound);
 EXPORT_SYMBOL(attach_ms_sound);
 EXPORT_SYMBOL(unload_ms_sound);
 
-#ifdef MODULE
-
 MODULE_PARM(io, "i");                  /* I/O for a raw AD1848 card */
 MODULE_PARM(irq, "i");                 /* IRQ to use */
 MODULE_PARM(dma, "i");                 /* First DMA channel */
@@ -2713,45 +2719,57 @@ MODULE_PARM(deskpro_xl, "i");           /* Special magic for Deskpro XL boxen */
 MODULE_PARM(deskpro_m, "i");           /* Special magic for Deskpro M box */
 MODULE_PARM(soundpro, "i");            /* More special magic for SoundPro chips */
 
-int io = -1;
-int irq = -1;
-int dma = -1;
-int dma2 = -1;
-int type = 0;
+static int __initdata io = -1;
+static int __initdata irq = -1;
+static int __initdata dma = -1;
+static int __initdata dma2 = -1;
+static int __initdata type = 0;
 
-static int loaded = 0;
-
-struct address_info hw_config;
+static struct address_info cfg;
 
-int init_module(void)
+static int __init init_ad1848(void)
 {
        printk(KERN_INFO "ad1848/cs4248 codec driver Copyright (C) by Hannu Savolainen 1993-1996\n");
-       if(io != -1)
-       {
-               if(irq == -1 || dma == -1)
-               {
-                       printk(KERN_WARNING "ad1848: must give I/O , IRQ and DMA.\n");
-                       return -EINVAL;
-               }
-               hw_config.irq = irq;
-               hw_config.io_base = io;
-               hw_config.dma = dma;
-               hw_config.dma2 = dma2;
-               hw_config.card_subtype = type;
-               if(!probe_ms_sound(&hw_config))
-                       return -ENODEV;
-               attach_ms_sound(&hw_config);
-               loaded=1;
-       }
-       SOUND_LOCK;
-       return 0;
+
+       cfg.irq = irq;
+       cfg.io_base = io;
+       cfg.dma = dma;
+       cfg.dma2 = dma2;
+       cfg.card_subtype = type;
+
+       if(probe_ms_sound(&cfg)) {
+               attach_ms_sound(&cfg);
+               return 0;
+       } else
+               return -ENODEV;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_ad1848(void)
 {
        SOUND_LOCK_END;
        if(loaded)
-               unload_ms_sound(&hw_config);
+               unload_ms_sound(&cfg);
 }
 
-#endif /* MODULE */
+module_init(init_ad1848);
+module_exit(cleanup_ad1848);
+
+#ifndef MODULE
+static int __init setup_ad1848(char *str)
+{
+        /* io, irq, dma, dma2, type */
+       int ints[6];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io      = ints[1];
+       irq     = ints[2];
+       dma     = ints[3];
+       dma2    = ints[4];
+       type    = ints[5];
+
+       return 1;
+}
+
+__setup("ad1848=", setup_ad1848);      
+#endif
diff --git a/drivers/sound/ad1848.h b/drivers/sound/ad1848.h
new file mode 100644 (file)
index 0000000..2f22255
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * ad1848.c
+ *
+ * Copyright:  Christoph Hellwig <chhellwig@gmx.net>
+ */
+
+#define AD_F_CS4231     0x0001  /* Returned if a CS4232 (or compatible) detected */
+#define AD_F_CS4248     0x0001  /* Returned if a CS4248 (or compatible) detected */
+
+#define         AD1848_SET_XTAL         1
+#define         AD1848_MIXER_REROUTE    2
+
+#define AD1848_REROUTE(oldctl, newctl) \
+                ad1848_control(AD1848_MIXER_REROUTE, ((oldctl)<<8)|(newctl))
+               
+
+int ad1848_init(char *name, int io_base, int irq, int dma_playback,
+       int dma_capture, int share_dma, int *osp);
+void ad1848_unload (int io_base, int irq, int dma_playback, int dma_capture, int share_dma);
+
+int ad1848_detect (int io_base, int *flags, int *osp);
+int ad1848_control(int cmd, int arg);
+
+void adintr(int irq, void *dev_id, struct pt_regs * dummy);
+void attach_ms_sound(struct address_info * hw_config);
+
+int probe_ms_sound(struct address_info *hw_config);
+void unload_ms_sound(struct address_info *hw_info);
index 087c57b68a069c393bc2a2d9dd24aef18682bd04..95974d444342070f095e9549d21daa9f9dc4a8ad 100644 (file)
  */
 
 #include <linux/module.h>
+#include <linux/init.h>
+
 #include "sound_config.h"
 #include "soundmodule.h"
 
-void attach_adlib_card(struct address_info *hw_config)
+#include "opl3.h"
+
+static void __init attach_adlib_card(struct address_info *hw_config)
 {
        hw_config->slots[0] = opl3_init(hw_config->io_base, hw_config->osp);
        request_region(hw_config->io_base, 4, "OPL3/OPL2");
 }
 
-int probe_adlib(struct address_info *hw_config)
+static int __init probe_adlib(struct address_info *hw_config)
 {
-       if (check_region(hw_config->io_base, 4)) 
-       {
+       if (check_region(hw_config->io_base, 4)) {
                DDB(printk("opl3.c: I/O port %x already in use\n", hw_config->io_base));
                return 0;
        }
        return opl3_detect(hw_config->io_base, hw_config->osp);
 }
 
-void unload_adlib(struct address_info *hw_config)
-{
-       release_region(hw_config->io_base, 4);
-       sound_unload_synthdev(hw_config->slots[0]);
-}
+static struct address_info cfg;
 
-#ifdef MODULE
+static int __initdata io = -1;
 
-int io = -1;
 MODULE_PARM(io, "i");
 
-EXPORT_NO_SYMBOLS;
-
-struct address_info cfg;
-
-int init_module(void)
+static int __init init_adlib(void)
 {
-       if (io == -1) {
+       cfg.io_base = io;
+
+       if (cfg.io_base == -1) {
                printk(KERN_ERR "adlib: must specify I/O address.\n");
                return -EINVAL;
        }
-       cfg.io_base = io;
        if (probe_adlib(&cfg) == 0)
                return -ENODEV;
        attach_adlib_card(&cfg);
@@ -59,10 +54,27 @@ int init_module(void)
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_adlib(void)
 {
-       unload_adlib(&cfg);
+       release_region(cfg.io_base, 4);
+       sound_unload_synthdev(cfg.slots[0]);
+       
        SOUND_LOCK_END;
 }
 
-#endif /* MODULE */
+module_init(init_adlib);
+module_exit(cleanup_adlib);
+
+#ifndef MODULE
+static int __init setup_adlib(char *str)
+{
+        /* io */
+       int ints[2];
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io = ints[1];
+
+       return 1;
+}
+__setup("adlib=", setup_adlib);
+#endif
index 0778273f9cfaaa3ef5c0a086b9938ba857eee1dd..2098c85a8b12cce708509ec91eab697090984c75 100644 (file)
@@ -1,5 +1,7 @@
 /*
- * sound/cs4232.c
+ * Copyright (C) by Hannu Savolainen 1993-1997
+ *
+ *     cs4232.c
  *
  * The low level driver for Crystal CS4232 based cards. The CS4232 is
  * a PnP compatible chip which contains a CS4231A codec, SB emulation,
  *     Alan Cox                Modularisation, Basic cleanups.
  *      Paul Barton-Davis      Separated MPU configuration, added
  *                                       Tropez+ (WaveFront) support
- */
-
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
+ *     Christoph Hellwig       Adapted to module_init/module_exit,
+ *                                     simple cleanups
  */
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/init.h>
 
 #include "sound_config.h"
 #include "soundmodule.h"
 
+#include "cs4232.h"
+#include "ad1848.h"
+#include "mpu401.h"
+
 #define KEY_PORT       0x279   /* Same as LPT1 status port */
 #define CSN_NUM                0x99    /* Just a random number */
 
@@ -78,11 +79,6 @@ int probe_cs4232_mpu(struct address_info *hw_config)
        return 1;
 }
 
-void attach_cs4232_mpu(struct address_info *hw_config)
-{
-       /* Nothing needs doing */
-}
-
 static unsigned char crystal_key[] =   /* A 32 byte magic key sequence */
 {
        0x96, 0x35, 0x9a, 0xcd, 0xe6, 0xf3, 0x79, 0xbc,
@@ -215,8 +211,15 @@ int probe_cs4232(struct address_info *hw_config)
 
 void attach_cs4232(struct address_info *hw_config)
 {
-       int base = hw_config->io_base, irq = hw_config->irq;
-       int dma1 = hw_config->dma, dma2 = hw_config->dma2;
+       int base = hw_config->io_base,
+               irq = hw_config->irq,
+               dma1 = hw_config->dma,
+               dma2 = hw_config->dma2;
+
+       if (base == -1 || irq == -1 || dma1 == -1) {
+               printk(KERN_ERR "cs4232: dma, irq and io must be set.\n");
+               return;
+       }
 
        if (dma2 == -1)
                dma2 = dma1;
@@ -263,6 +266,7 @@ void attach_cs4232(struct address_info *hw_config)
                }
                hw_config->slots[1] = hw_config2.slots[1];
        }
+       SOUND_LOCK;
 }
 
 void unload_cs4232(struct address_info *hw_config)
@@ -302,19 +306,18 @@ void unload_cs4232(struct address_info *hw_config)
        }
 }
 
-void unload_cs4232_mpu(struct address_info *hw_config)
-{
-       /* Not required. Handled by cs4232_unload */
-}
+static struct address_info cfg;
+static struct address_info cfg_mpu;
 
-#ifdef MODULE
+static int __initdata io       = -1;
+static int __initdata irq      = -1;
+static int __initdata dma      = -1;
+static int __initdata dma2     = -1;
+static int __initdata mpuio    = -1;
+static int __initdata mpuirq   = -1;
+static int __initdata synthio  = -1;
+static int __initdata synthirq = -1;
 
-int             io = -1;
-int             irq = -1;
-int             dma = -1;
-int             dma2 = -1;
-int             mpuio = -1;
-int             mpuirq = -1;
 
 MODULE_PARM(io,"i");
 MODULE_PARM(irq,"i");
@@ -322,34 +325,20 @@ MODULE_PARM(dma,"i");
 MODULE_PARM(dma2,"i");
 MODULE_PARM(mpuio,"i");
 MODULE_PARM(mpuirq,"i");
-
-int             synthio = -1;
-int             synthirq = -1;
 MODULE_PARM(synthio,"i");
 MODULE_PARM(synthirq,"i");
 
-EXPORT_NO_SYMBOLS;
-
-struct address_info cfg;
-struct address_info mpu_cfg;
-
 /*
  *     Install a CS4232 based card. Need to have ad1848 and mpu401
  *     loaded ready.
  */
 
-int init_module(void)
+static int __init init_cs4232(void)
 {
-       if (io == -1 || irq == -1 || dma == -1 || dma2 == -1)
-       {
-               printk(KERN_ERR "cs4232: dma, dma2, irq and io must be set.\n");
-               return -EINVAL;
-       }
 #ifdef CONFIG_SOUND_WAVEFRONT_MODULE
        if(synthio == -1)
                printk(KERN_WARNING "cs4232: set synthio and synthirq to use the wavefront facilities.\n");
-       else
-       {
+       else {
                synth_base = synthio;
                synth_irq =  synthirq;  
        }
@@ -363,32 +352,48 @@ int init_module(void)
        cfg.dma = dma;
        cfg.dma2 = dma2;
 
-       mpu_cfg.io_base = -1;
-       mpu_cfg.irq = -1;
+       cfg_mpu.io_base = -1;
+       cfg_mpu.irq = -1;
 
        if (mpuio != -1 && mpuirq != -1) {
-               mpu_cfg.io_base = mpuio;
-               mpu_cfg.irq = mpuirq;
-               probe_cs4232_mpu(&mpu_cfg); /* Bug always returns 0 not OK -- AC */
+               cfg_mpu.io_base = mpuio;
+               cfg_mpu.irq = mpuirq;
+               probe_cs4232_mpu(&cfg_mpu); /* Bug always returns 0 not OK -- AC */
        }
 
        if (probe_cs4232(&cfg) == 0)
                return -ENODEV;
-
        attach_cs4232(&cfg);
-
-       if (mpuio != -1 && mpuirq != -1) {
-               attach_cs4232_mpu(&mpu_cfg);
-       }
-
-       SOUND_LOCK;
+       
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_cs4232(void)
 {
         unload_cs4232(&cfg); /* unloads MPU as well, if needed */
        SOUND_LOCK_END;
 }
 
-#endif /* MODULE */
+module_init(init_cs4232);
+module_exit(cleanup_cs4232);
+
+#ifndef MODULE
+static int __init setup_cs4232(char *str)
+{
+       /* io, irq, dma, dma2 mpuio, mpuirq*/
+       int ints[7];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io      = ints[1];
+       irq     = ints[2];
+       dma     = ints[3];
+       dma2    = ints[4];
+       mpuio   = ints[5];
+       mpuirq  = ints[6];
+
+       return 1;
+}
+
+__setup("cs4232=", setup_cs4232);
+#endif
diff --git a/drivers/sound/cs4232.h b/drivers/sound/cs4232.h
new file mode 100644 (file)
index 0000000..7b57821
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ *     cs4232.h
+ *
+ * Copyright: Christoph Hellwig <chhellwig@gmx.net>
+ *
+ */
+
+int probe_cs4232 (struct address_info *hw_config);
+void attach_cs4232 (struct address_info *hw_config);
+int probe_cs4232_mpu (struct address_info *hw_config);
+void attach_cs4232_mpu (struct address_info *hw_config);
index 5e9657c8a2f824a9b0cd6345b2644709bd09e257..5be9a1eefd7e232a5a690d68cdb3e3d81a20ed5b 100644 (file)
@@ -2,9 +2,8 @@
  * sound/dev_table.c
  *
  * Device call tables.
- */
-
-/*
+ *
+ *
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -15,7 +14,6 @@
 #include <linux/config.h>
 #include <linux/init.h>
 
-
 #define _DEV_TABLE_C_
 #include "sound_config.h"
 
@@ -23,387 +21,6 @@ int softoss_dev = 0;
 int sound_started = 0;
 int sndtable_get_cardcount(void);
 
-int snd_find_driver(int type)
-{
-       int i, n = num_sound_drivers;
-
-       for (i = 0; i < n; i++)
-               if (sound_drivers[i].card_type == type)
-                       return i;
-
-       return -1;
-}
-
-static void start_services(void)
-{
-#ifdef FIXME
-       int soundcards_installed;
-
-       if (!(soundcards_installed = sndtable_get_cardcount()))
-               return;         /* No cards detected */
-#endif
-
-       if (num_audiodevs)      /* Audio devices present */
-       {
-               int             dev;
-               for (dev = 0; dev < num_audiodevs; dev++)
-               {
-               }
-               audio_init_devices();
-         }
-
-       return;
-}
-
-static void
-start_cards(void)
-{
-       int i, n = num_sound_cards;
-       int drv;
-
-       sound_started = 1;
-       if (trace_init)
-               printk(KERN_DEBUG "Sound initialization started\n");
-
-#ifdef CONFIG_LOWLEVEL_SOUND
-       {
-               extern void sound_preinit_lowlevel_drivers(void);
-               sound_preinit_lowlevel_drivers();
-       }
-#endif
-
-/*
- * Check the number of cards actually defined in the table
- */
-
-       for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
-               num_sound_cards = i + 1;
-
-       for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
-       {
-               if (snd_installed_cards[i].enabled)
-               {
-                       snd_installed_cards[i].for_driver_use = NULL;
-
-                       if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) == -1)
-                       {
-                               snd_installed_cards[i].enabled = 0;     /*
-                                                                        * Mark as not detected
-                                                                        */
-                               continue;
-                       }
-                       snd_installed_cards[i].config.card_subtype =
-                                       sound_drivers[drv].card_subtype;
-
-                       if (sound_drivers[drv].probe(&snd_installed_cards[i].config))
-                               sound_drivers[drv].attach(&snd_installed_cards[i].config);
-                       else
-                               snd_installed_cards[i].enabled = 0;     /*
-                                                                        * Mark as not detected
-                                                                        */
-               }
-       }
-#ifdef CONFIG_LOWLEVEL_SOUND
-       {
-               extern void     sound_init_lowlevel_drivers(void);
-               sound_init_lowlevel_drivers();
-       }
-#endif
-       if (trace_init)
-               printk(KERN_DEBUG "Sound initialization complete\n");
-}
-
-void sndtable_init(void)
-{
-       start_cards();
-}
-
-
-void sound_unload_drivers(void)
-{
-       int i, n = num_sound_cards;
-       int drv;
-
-       if (!sound_started)
-               return;
-
-       if (trace_init)
-               printk(KERN_DEBUG "Sound unload started\n");
-
-
-       for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
-       {
-               if (snd_installed_cards[i].enabled)
-               {
-                       if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) != -1)
-                       {
-                               if (sound_drivers[drv].unload)
-                               {
-                                       sound_drivers[drv].unload(&snd_installed_cards[i].config);
-                                       snd_installed_cards[i].enabled = 0;
-                               }
-                       }
-               }
-       }
-
-        for (i=0;i<num_audiodevs;i++)
-               DMAbuf_deinit(i);
-
-       if (trace_init)
-               printk(KERN_DEBUG "Sound unload complete\n");
-}
-
-void sound_unload_driver(int type)
-{
-       int i, drv = -1, n = num_sound_cards;
-
-
-       DEB(printk("unload driver %d: ", type));
-
-       for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
-       {
-               if (snd_installed_cards[i].card_type == type)
-               {
-                       if (snd_installed_cards[i].enabled)
-                       {
-                               if ((drv = snd_find_driver(type)) != -1)
-                               {
-                                       DEB(printk(" card %d", i));
-                                       if (sound_drivers[drv].unload)
-                                       {
-                                               sound_drivers[drv].unload(&snd_installed_cards[i].config);
-                                               snd_installed_cards[i].enabled = 0;
-                                       }
-                               }
-                       }
-               }
-       }
-       DEB(printk("\n"));
-}
-
-
-int sndtable_probe(int unit, struct address_info *hw_config)
-{
-       int             sel = -1;
-
-       DEB(printk(KERN_DEBUG "sndtable_probe(%d)\n", unit));
-
-       if (!unit)
-               return 1;
-
-
-       if (sel == -1 && num_sound_cards < max_sound_cards)
-       {
-               int i;
-               i = sel = (num_sound_cards++);
-               snd_installed_cards[sel].card_type = unit;
-               snd_installed_cards[sel].enabled = 1;
-       }
-       if (sel != -1)
-       {
-               int             drv;
-
-               snd_installed_cards[sel].for_driver_use = NULL;
-               snd_installed_cards[sel].config.io_base = hw_config->io_base;
-               snd_installed_cards[sel].config.irq = hw_config->irq;
-               snd_installed_cards[sel].config.dma = hw_config->dma;
-               snd_installed_cards[sel].config.dma2 = hw_config->dma2;
-               snd_installed_cards[sel].config.name = hw_config->name;
-               snd_installed_cards[sel].config.always_detect = hw_config->always_detect;
-               snd_installed_cards[sel].config.driver_use_1 = hw_config->driver_use_1;
-               snd_installed_cards[sel].config.driver_use_2 = hw_config->driver_use_2;
-               snd_installed_cards[sel].config.card_subtype = hw_config->card_subtype;
-
-               if ((drv = snd_find_driver(snd_installed_cards[sel].card_type)) == -1)
-               {
-                       snd_installed_cards[sel].enabled = 0;
-                       DEB(printk(KERN_DEBUG "Failed to find driver\n"));
-                       return 0;
-               }
-               DEB(printk(KERN_DEBUG "Driver name '%s'\n", sound_drivers[drv].name));
-
-               hw_config->card_subtype = snd_installed_cards[sel].config.card_subtype = sound_drivers[drv].card_subtype;
-
-               if (sound_drivers[drv].probe(hw_config))
-               {
-                       DEB(printk(KERN_DEBUG "Hardware probed OK\n"));
-                       return 1;
-               }
-               DEB(printk("Failed to find hardware\n"));
-               snd_installed_cards[sel].enabled = 0;           /*
-                                                                * Mark as not detected
-                                                                */
-               return 0;
-       }
-       return 0;
-}
-
-
-int sndtable_init_card(int unit, struct address_info *hw_config)
-{
-       int i, n = num_sound_cards;
-
-       DEB(printk("sndtable_init_card(%d) entered\n", unit));
-
-       if (!unit)
-       {
-               sndtable_init();
-               return 1;
-       }
-       for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
-       {
-               if (snd_installed_cards[i].card_type == unit)
-               {
-                       int drv;
-
-                       snd_installed_cards[i].config.io_base = hw_config->io_base;
-                       snd_installed_cards[i].config.irq = hw_config->irq;
-                       snd_installed_cards[i].config.dma = hw_config->dma;
-                       snd_installed_cards[i].config.dma2 = hw_config->dma2;
-                       snd_installed_cards[i].config.name = hw_config->name;
-                       snd_installed_cards[i].config.always_detect = hw_config->always_detect;
-                       snd_installed_cards[i].config.driver_use_1 = hw_config->driver_use_1;
-                       snd_installed_cards[i].config.driver_use_2 = hw_config->driver_use_2;
-                       snd_installed_cards[i].config.card_subtype = hw_config->card_subtype;
-
-                       if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) == -1)
-                               snd_installed_cards[i].enabled = 0;     /*
-                                                                        * Mark as not detected
-                                                                        */
-                       else
-                       {
-                               DEB(printk(KERN_DEBUG "Located card - calling attach routine\n"));
-                               sound_drivers[drv].attach(hw_config);
-
-                               DEB(printk("attach routine finished\n"));
-                       }
-                       start_services();
-                       return 1;
-               }
-       }
-       DEB(printk("sndtable_init_card: No card defined with type=%d, num cards: %d\n", unit, num_sound_cards));
-       return 0;
-}
-
-int sndtable_get_cardcount(void)
-{
-       return num_audiodevs + num_mixers + num_synths + num_midis;
-}
-
-int sndtable_identify_card(char *name)
-{
-       int i, n = num_sound_drivers;
-
-       if (name == NULL)
-               return 0;
-
-       for (i = 0; i < n; i++)
-       {
-               if (sound_drivers[i].driver_id != NULL)
-               {
-                       char *id = sound_drivers[i].driver_id;
-                       int j;
-
-                       for (j = 0; j < 80 && name[j] == id[j]; j++)
-                               if (id[j] == 0 && name[j] == 0) /* Match */
-                                       return sound_drivers[i].card_type;
-               }
-       }
-       return 0;
-}
-
-static int __init sound_setup(char *str)
-{
-       int i, n = num_sound_cards;
-       int ints[32];
-
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-
-       /*
-        *      First disable all drivers
-        */
-
-       for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
-               snd_installed_cards[i].enabled = 0;
-
-       if (ints[0] == 0 || ints[1] == 0)
-               return 1;
-       /*
-        *      Then enable them one by time
-        */
-
-       for (i = 1; i <= ints[0]; i++)
-       {
-               int card_type, ioaddr, irq, dma, dma2, ptr, j;
-               unsigned int val;
-
-               val = (unsigned int) ints[i];
-               card_type = (val & 0x0ff00000) >> 20;
-
-               if (card_type > 127)
-               {
-                       /*
-                        * Add any future extensions here
-                        */
-                       return 1;
-               }
-               ioaddr = (val & 0x000fff00) >> 8;
-               irq = (val & 0x000000f0) >> 4;
-               dma = (val & 0x0000000f);
-               dma2 = (val & 0xf0000000) >> 28;
-
-               ptr = -1;
-               for (j = 0; j < n && ptr == -1; j++)
-               {
-                       if (snd_installed_cards[j].card_type == card_type &&
-                               !snd_installed_cards[j].enabled)/*
-                                                                * Not already found
-                                                                */
-                               ptr = j;
-               }
-
-               if (ptr == -1)
-                       printk(KERN_ERR "Sound: Invalid setup parameter 0x%08x\n", val);
-               else
-               {
-                       snd_installed_cards[ptr].enabled = 1;
-                       snd_installed_cards[ptr].config.io_base = ioaddr;
-                       snd_installed_cards[ptr].config.irq = irq;
-                       snd_installed_cards[ptr].config.dma = dma;
-                       snd_installed_cards[ptr].config.dma2 = dma2;
-                       snd_installed_cards[ptr].config.name = NULL;
-                       snd_installed_cards[ptr].config.always_detect = 0;
-                       snd_installed_cards[ptr].config.driver_use_1 = 0;
-                       snd_installed_cards[ptr].config.driver_use_2 = 0;
-                       snd_installed_cards[ptr].config.card_subtype = 0;
-               }
-       }
-       
-       return 1;
-}
-
-__setup("sound=", sound_setup);
-
-
-struct address_info * sound_getconf(int card_type)
-{
-       int j, ptr;
-       int n = num_sound_cards;
-
-       ptr = -1;
-       for (j = 0; j < n && ptr == -1 && snd_installed_cards[j].card_type; j++)
-       {
-               if (snd_installed_cards[j].card_type == card_type)
-                       ptr = j;
-       }
-       if (ptr == -1)
-               return (struct address_info *) NULL;
-
-       return &snd_installed_cards[ptr].config;
-}
-
-
-
 int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
                        int driver_size, int flags, unsigned int format_mask,
                        void *devc, int dma1, int dma2)
@@ -619,4 +236,3 @@ void sound_unload_timerdev(int dev)
        if (dev != -1)
                sound_timer_devs[dev] = NULL;
 }
-
index 5c0cf1d0fedd9c4d36cf3a47558b5a5bf21675c7..b15fd505c2f2c63518f57b153bfb1b25815299ca 100644 (file)
@@ -370,318 +370,6 @@ struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] = {
 int num_sound_timers = 0;
 #endif
 
-/*
- * List of low level drivers compiled into the kernel.
- */
-
-struct driver_info sound_drivers[] = 
-{
-#ifdef CONFIG_SOUND_PSS
-       {"PSS", 0, SNDCARD_PSS, "Echo Personal Sound System PSS (ESC614)", attach_pss, probe_pss, unload_pss},
-       {"PSSMPU", 0, SNDCARD_PSS_MPU, "PSS-MPU", attach_pss_mpu, probe_pss_mpu, unload_pss_mpu},
-       {"PSSMSS", 0, SNDCARD_PSS_MSS, "PSS-MSS", attach_pss_mss, probe_pss_mss, unload_pss_mss},
-#endif
-
-#ifdef CONFIG_SOUND_GUS
-#ifdef CONFIG_GUS16
-       {"GUS16", 0, SNDCARD_GUS16,     "Ultrasound 16-bit opt.",       attach_gus_db16, probe_gus_db16, unload_gus_db16},
-#endif
-       {"GUS", 0, SNDCARD_GUS, "Gravis Ultrasound",    attach_gus_card, probe_gus, unload_gus},
-       {"GUSPNP", 1, SNDCARD_GUSPNP,   "GUS PnP",      attach_gus_card, probe_gus, unload_gus},
-#endif
-
-#ifdef CONFIG_SOUND_MSS
-       {"MSS", 0, SNDCARD_MSS, "MS Sound System",      attach_ms_sound, probe_ms_sound, unload_ms_sound},
-       /* Compaq Deskpro XL */
-       {"DESKPROXL", 2, SNDCARD_DESKPROXL,     "Compaq Deskpro XL",    attach_ms_sound, probe_ms_sound, unload_ms_sound},
-#endif
-
-#ifdef CONFIG_SOUND_MAD16
-       {"MAD16", 0, SNDCARD_MAD16,     "MAD16/Mozart (MSS)",           attach_mad16, probe_mad16, unload_mad16},
-       {"MAD16MPU", 0, SNDCARD_MAD16_MPU,      "MAD16/Mozart (MPU)",           attach_mad16_mpu, probe_mad16_mpu, unload_mad16_mpu},
-#endif
-
-#ifdef CONFIG_SOUND_CS4232
-       {"CS4232", 0, SNDCARD_CS4232,   "CS4232",               attach_cs4232, probe_cs4232, unload_cs4232},
-#endif
-#ifdef CONFIG_CS4232_MPU_BASE
-       {"CS4232MPU", 0, SNDCARD_CS4232_MPU,    "CS4232 MIDI",          attach_cs4232_mpu, probe_cs4232_mpu, unload_cs4232_mpu},
-#endif
-
-#ifdef CONFIG_SOUND_OPL3SA2
-       {"OPL3SA2", 0, SNDCARD_OPL3SA2, "OPL3SA2",              attach_opl3sa2, probe_opl3sa2, unload_opl3sa2},
-       {"OPL3SA2MSS", 1, SNDCARD_OPL3SA2_MSS,  "OPL3SA2 MSS",          attach_opl3sa2_mss, probe_opl3sa2_mss, unload_opl3sa2_mss},
-       {"OPL3SA2MPU", 0, SNDCARD_OPL3SA2_MPU,  "OPL3SA2 MIDI",         attach_opl3sa2_mpu, probe_opl3sa2_mpu, unload_opl3sa2_mpu},
-#endif
-
-#ifdef CONFIG_SGALAXY
-       {"SGALAXY", 0, SNDCARD_SGALAXY, "Sound Galaxy WSS",             attach_sgalaxy, probe_sgalaxy, unload_sgalaxy},
-#endif
-
-#ifdef CONFIG_SOUND_AD1816
-        {"AD1816", 0, SNDCARD_AD1816,   "AD1816",               attach_ad1816, 
-probe_ad1816, unload_ad1816},
-#endif
-
-#ifdef CONFIG_SOUND_YM3812
-       {"OPL3", 0, SNDCARD_ADLIB,      "OPL-2/OPL-3 FM",               attach_adlib_card, probe_adlib, unload_adlib},
-#endif
-
-#ifdef CONFIG_SOUND_PAS
-       {"PAS16", 0, SNDCARD_PAS,       "ProAudioSpectrum",     attach_pas_card, probe_pas, unload_pas},
-#endif
-
-#if (defined(CONFIG_SOUND_MPU401) || defined(CONFIG_SOUND_MPU_EMU))
-       {"MPU401", 0, SNDCARD_MPU401,"Roland MPU-401",  attach_mpu401, probe_mpu401, unload_mpu401},
-#endif
-
-#if defined(CONFIG_SOUND_UART401)
-       {"UART401", 0, SNDCARD_UART401,"MPU-401 (UART)", 
-               attach_uart401, probe_uart401, unload_uart401},
-#endif
-
-#if defined(CONFIG_SOUND_WAVEFRONT)
-       {"WAVEFRONT", 0, SNDCARD_WAVEFRONT,"TB WaveFront", attach_wavefront, probe_wavefront, unload_wavefront},
-#endif
-
-#if defined(CONFIG_SOUND_MAUI)
-       {"MAUI", 0, SNDCARD_MAUI,"TB Maui",     attach_maui, probe_maui, unload_maui},
-#endif
-
-#if defined(CONFIG_SOUND_UART6850)
-       {"MIDI6850", 0, SNDCARD_UART6850,"6860 UART Midi",      attach_uart6850, probe_uart6850, unload_uart6850},
-#endif
-
-
-
-
-#ifdef CONFIG_SOUND_SBDSP
-       {"SBLAST", 0, SNDCARD_SB,       "Sound Blaster",                attach_sb_card, probe_sb, unload_sb},
-       {"SBPNP", 6, SNDCARD_SBPNP,     "Sound Blaster PnP",            attach_sb_card, probe_sb, unload_sb},
-
-       {"SBMPU", 0, SNDCARD_SB16MIDI,"SB MPU-401",     attach_sbmpu, probe_sbmpu, unload_sbmpu},
-#endif
-
-#ifdef CONFIG_SOUND_SSCAPE
-       {"SSCAPE", 0, SNDCARD_SSCAPE, "Ensoniq SoundScape",     attach_sscape, probe_sscape, unload_sscape},
-       {"SSCAPEMSS", 0, SNDCARD_SSCAPE_MSS,    "MS Sound System (SoundScape)", attach_ss_ms_sound, probe_ss_ms_sound, unload_ss_ms_sound},
-#endif
-
-#ifdef CONFIG_SOUND_OPL3SA1
-       {"OPL3SA", 0, SNDCARD_OPL3SA1, "Yamaha OPL3-SA",        attach_opl3sa_wss, probe_opl3sa_wss, unload_opl3sa_wss}, 
-/*     {"OPL3SASB", 0, SNDCARD_OPL3SA1_SB, "OPL3-SA (SB mode)",        attach_opl3sa_sb, probe_opl3sa_sb, unload_opl3sa_sb}, */
-       {"OPL3SAMPU", 0, SNDCARD_OPL3SA1_MPU, "OPL3-SA MIDI",   attach_opl3sa_mpu, probe_opl3sa_mpu, unload_opl3sa_mpu},
-#endif
-
-#ifdef CONFIG_SOUND_TRIX
-       {"TRXPRO", 0, SNDCARD_TRXPRO, "MediaTrix AudioTrix Pro",        attach_trix_wss, probe_trix_wss, unload_trix_wss},
-       {"TRXPROSB", 0, SNDCARD_TRXPRO_SB, "AudioTrix (SB mode)",       attach_trix_sb, probe_trix_sb, unload_trix_sb},
-       {"TRXPROMPU", 0, SNDCARD_TRXPRO_MPU, "AudioTrix MIDI",  attach_trix_mpu, probe_trix_mpu, unload_trix_mpu},
-#endif
-
-#ifdef CONFIG_SOUND_SOFTOSS
-       {"SOFTSYN", 0, SNDCARD_SOFTOSS, "SoftOSS Virtual Wave Table", 
-               attach_softsyn_card, probe_softsyn, unload_softsyn},
-#endif
-
-#ifdef CONFIG_SOUND_VMIDI
-       {"VMIDI", 0, SNDCARD_VMIDI,"Loopback MIDI Device",      attach_v_midi, probe_v_midi, unload_v_midi},
-#endif
-#ifdef CONFIG_SOUND_VIDC
-       {"VIDC", 0, SNDCARD_VIDC, "ARM VIDC 16-bit D/A", attach_vidc, probe_vidc, unload_vidc },
-#endif
-#ifdef CONFIG_SOUND_WAVEARTIST
-       {"WaveArtist", 0, SNDCARD_WAVEARTIST, "NetWinder WaveArtist", attach_waveartist, probe_waveartist, unload_waveartist },
-#endif
-       {NULL, 0, 0,            "*?*",                  NULL, NULL, NULL}
-};
-
-int num_sound_drivers = sizeof(sound_drivers) / sizeof (struct driver_info);
-
-
-/*
- *     List of devices actually configured in the system.
- *
- *     Note! The detection order is significant. Don't change it.
- */
-
-struct card_info snd_installed_cards[] = 
-{
-#ifdef CONFIG_SOUND_PSS
-       {SNDCARD_PSS, {CONFIG_PSS_BASE, 0, -1, -1}, SND_DEFAULT_ENABLE},
-#ifdef CONFIG_PSS_MPU_BASE
-       {SNDCARD_PSS_MPU, {CONFIG_PSS_MPU_BASE, CONFIG_PSS_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-#ifdef CONFIG_PSS_MSS_BASE
-       {SNDCARD_PSS_MSS, {CONFIG_PSS_MSS_BASE, CONFIG_PSS_MSS_IRQ, CONFIG_PSS_MSS_DMA, -1}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#ifdef CONFIG_SOUND_TRIX
-#ifndef CONFIG_TRIX_DMA2
-#define CONFIG_TRIX_DMA2 CONFIG_TRIX_DMA
-#endif
-       {SNDCARD_TRXPRO, {CONFIG_TRIX_BASE, CONFIG_TRIX_IRQ, CONFIG_TRIX_DMA, CONFIG_TRIX_DMA2}, SND_DEFAULT_ENABLE},
-#ifdef CONFIG_TRIX_SB_BASE
-       {SNDCARD_TRXPRO_SB, {CONFIG_TRIX_SB_BASE, CONFIG_TRIX_SB_IRQ, CONFIG_TRIX_SB_DMA, -1}, SND_DEFAULT_ENABLE},
-#endif
-#ifdef CONFIG_TRIX_MPU_BASE
-       {SNDCARD_TRXPRO_MPU, {CONFIG_TRIX_MPU_BASE, CONFIG_TRIX_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#ifdef CONFIG_SOUND_OPL3SA1
-       {SNDCARD_OPL3SA1, {CONFIG_OPL3SA1_BASE, CONFIG_OPL3SA1_IRQ, CONFIG_OPL3SA1_DMA, CONFIG_OPL3SA1_DMA2}, SND_DEFAULT_ENABLE},
-#ifdef CONFIG_OPL3SA1_MPU_BASE
-       {SNDCARD_OPL3SA1_MPU, {CONFIG_OPL3SA1_MPU_BASE, CONFIG_OPL3SA1_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#ifdef CONFIG_SOUND_SOFTOSS
-       {SNDCARD_SOFTOSS, {0, 0, -1, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_SSCAPE
-       {SNDCARD_SSCAPE, {CONFIG_SSCAPE_BASE, CONFIG_SSCAPE_IRQ, CONFIG_SSCAPE_DMA, -1}, SND_DEFAULT_ENABLE},
-       {SNDCARD_SSCAPE_MSS, {CONFIG_SSCAPE_MSS_BASE, CONFIG_SSCAPE_MSS_IRQ, CONFIG_SSCAPE_DMA, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_MAD16
-#ifndef CONFIG_MAD16_DMA2
-#define CONFIG_MAD16_DMA2 CONFIG_MAD16_DMA
-#endif
-       {SNDCARD_MAD16, {CONFIG_MAD16_BASE, CONFIG_MAD16_IRQ, CONFIG_MAD16_DMA, CONFIG_MAD16_DMA2}, SND_DEFAULT_ENABLE},
-#ifdef CONFIG_MAD16_MPU_BASE
-       {SNDCARD_MAD16_MPU, {CONFIG_MAD16_MPU_BASE, CONFIG_MAD16_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#ifdef CONFIG_SOUND_CS4232
-#ifndef CONFIG_CS4232_DMA2
-#define CONFIG_CS4232_DMA2 CONFIG_CS4232_DMA
-#endif
-#ifdef CONFIG_CS4232_MPU_BASE
-       {SNDCARD_CS4232_MPU, {CONFIG_CS4232_MPU_BASE, CONFIG_CS4232_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-       {SNDCARD_CS4232, {CONFIG_CS4232_BASE, CONFIG_CS4232_IRQ, CONFIG_CS4232_DMA, CONFIG_CS4232_DMA2}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_OPL3SA2
-#ifndef CONFIG_OPL3SA2_DMA2
-#define CONFIG_OPL3SA2_DMA2 CONFIG_OPL3SA2_DMA
-#endif
-       {SNDCARD_OPL3SA2, {CONFIG_OPL3SA2_CTRL_BASE, CONFIG_OPL3SA2_IRQ, CONFIG_OPL3SA2_DMA, CONFIG_OPL3SA2_DMA2}, SND_DEFAULT_ENABLE},
-       {SNDCARD_OPL3SA2_MSS, {CONFIG_OPL3SA2_BASE, CONFIG_OPL3SA2_IRQ, CONFIG_OPL3SA2_DMA, CONFIG_OPL3SA2_DMA2}, SND_DEFAULT_ENABLE},
-#ifdef CONFIG_OPL3SA2_MPU_BASE
-       {SNDCARD_OPL3SA2_MPU, {CONFIG_OPL3SA2_MPU_BASE, CONFIG_OPL3SA2_MPU_IRQ, CONFIG_OPL3SA2_DMA, -1}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#ifdef CONFIG_SGALAXY
-#ifndef CONFIG_SGALAXY_DMA2
-#define CONFIG_SGALAXY_DMA2 CONFIG_SGALAXY_DMA
-#endif
-       {SNDCARD_SGALAXY, {CONFIG_SGALAXY_BASE, CONFIG_SGALAXY_IRQ, CONFIG_SGALAXY_DMA, CONFIG_SGALAXY_DMA2, 0, NULL, CONFIG_SGALAXY_SGBASE}, SND_DEFAULT_ENABLE},
-#endif
-
-
-#ifdef CONFIG_SOUND_MSS
-#ifndef CONFIG_MSS_DMA2
-#define CONFIG_MSS_DMA2 -1
-#endif
-
-#ifdef DESKPROXL
-       {SNDCARD_DESKPROXL, {CONFIG_MSS_BASE, CONFIG_MSS_IRQ, CONFIG_MSS_DMA, CONFIG_MSS_DMA2}, SND_DEFAULT_ENABLE},
-#else
-       {SNDCARD_MSS, {CONFIG_MSS_BASE, CONFIG_MSS_IRQ, CONFIG_MSS_DMA, CONFIG_MSS_DMA2}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef MSS2_BASE
-       {SNDCARD_MSS, {MSS2_BASE, MSS2_IRQ, MSS2_DMA, MSS2_DMA2}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#ifdef CONFIG_SOUND_PAS
-       {SNDCARD_PAS, {CONFIG_PAS_BASE, CONFIG_PAS_IRQ, CONFIG_PAS_DMA, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_SB
-#ifndef CONFIG_SB_DMA
-#define CONFIG_SB_DMA          1
-#endif
-#ifndef CONFIG_SB_DMA2
-#define CONFIG_SB_DMA2         -1
-#endif
-       {SNDCARD_SB, {CONFIG_SB_BASE, CONFIG_SB_IRQ, CONFIG_SB_DMA, CONFIG_SB_DMA2}, SND_DEFAULT_ENABLE},
-#ifdef SB2_BASE
-       {SNDCARD_SB, {SB2_BASE, SB2_IRQ, SB2_DMA, SB2_DMA2}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#if defined(CONFIG_WAVEFRONT) 
-       {SNDCARD_WAVEFRONT, {WAVEFRONT_BASE, WAVEFRONT_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_MAUI
-       {SNDCARD_MAUI, {CONFIG_MAUI_BASE, CONFIG_MAUI_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_MPU401
-       {SNDCARD_MPU401, {CONFIG_MPU_BASE, CONFIG_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#ifdef MPU2_BASE
-       {SNDCARD_MPU401, {MPU2_BASE, MPU2_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-#ifdef MPU3_BASE
-       {SNDCARD_MPU401, {MPU3_BASE, MPU3_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#ifdef CONFIG_SOUND_UART6850
-       {SNDCARD_UART6850, {CONFIG_U6850_BASE, CONFIG_U6850_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_SB
-#ifdef CONFIG_SB_MPU_BASE
-       {SNDCARD_SB16MIDI,{CONFIG_SB_MPU_BASE, CONFIG_SB_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#ifdef CONFIG_SOUND_GUS
-#ifndef CONFIG_GUS_DMA2
-#define CONFIG_GUS_DMA2 CONFIG_GUS_DMA
-#endif
-#ifdef CONFIG_GUS16
-       {SNDCARD_GUS16, {CONFIG_GUS16_BASE, CONFIG_GUS16_IRQ, CONFIG_GUS16_DMA, -1}, SND_DEFAULT_ENABLE},
-#endif
-       {SNDCARD_GUS, {CONFIG_GUS_BASE, CONFIG_GUS_IRQ, CONFIG_GUS_DMA, CONFIG_GUS_DMA2}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_YM3812
-       {SNDCARD_ADLIB, {FM_MONO, 0, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_VMIDI
-       {SNDCARD_VMIDI, {0, 0, 0, -1}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifdef CONFIG_SOUND_VIDC
-       { SNDCARD_VIDC, {0, 0, 0, 0}, SND_DEFAULT_ENABLE },
-#endif
-
-#ifdef CONFIG_SOUND_WAVEARTIST
-       { SNDCARD_WAVEARTIST, { CONFIG_WAVEARTIST_BASE, CONFIG_WAVEARTIST_IRQ, CONFIG_WAVEARTIST_DMA, CONFIG_WAVEARTIST_DMA2 }, SND_DEFAULT_ENABLE },
-#endif
-       {0, {0}, 0}
-};
-
-int num_sound_cards = sizeof(snd_installed_cards) / sizeof (struct card_info);
-static int max_sound_cards =  sizeof(snd_installed_cards) / sizeof (struct card_info);
-
-#if defined(MODULE)
-int trace_init = 0;
-#else
-int trace_init = 1;
-#endif
 
 #else
 extern struct audio_operations * audio_devs[MAX_AUDIO_DEV]; extern int num_audiodevs;
@@ -689,30 +377,16 @@ extern struct mixer_operations * mixer_devs[MAX_MIXER_DEV]; extern int num_mixer
 extern struct synth_operations * synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV]; extern int num_synths;
 extern struct midi_operations * midi_devs[MAX_MIDI_DEV]; extern int num_midis;
 extern struct sound_timer_operations * sound_timer_devs[MAX_TIMER_DEV]; extern int num_sound_timers;
-
-extern struct driver_info sound_drivers[];
-extern int num_sound_drivers;
-extern struct card_info snd_installed_cards[];
-extern int num_sound_cards;
-
-extern int trace_init;
 #endif /* _DEV_TABLE_C_ */
-void sndtable_init(void);
+void setup_cards(void);
 int sndtable_get_cardcount (void);
-struct address_info *sound_getconf(int card_type);
 void sound_chconf(int card_type, int ioaddr, int irq, int dma);
 int snd_find_driver(int type);
-void sound_unload_drivers(void);
 void sound_unload_driver(int type);
 int sndtable_identify_card(char *name);
 
-#if FIXED_FOR_2_4_0
-void sound_setup (char *str, int *ints);
-#endif
-
 extern int sound_map_buffer (int dev, struct dma_buffparms *dmap, buffmem_desc *info);
 int sndtable_probe (int unit, struct address_info *hw_config);
-int sndtable_init_card (int unit, struct address_info *hw_config);
 int sndtable_start_card (int unit, struct address_info *hw_config);
 void sound_timer_init (struct sound_lowlev_timer *t, char *name);
 void sound_dma_intr (int dev, struct dma_buffparms *dmap, int chan);
diff --git a/drivers/sound/gus.h b/drivers/sound/gus.h
new file mode 100644 (file)
index 0000000..fe795ec
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * gus.h
+ *
+ * Copyright:  Christoph Hellwig <chhellwig@gmx.net>
+ *
+ */
+
+#include "ad1848.h"
+
+/*     From gus_card.c */
+int gus_set_midi_irq(int num);
+void gusintr(int irq, void *dev_id, struct pt_regs * dummy);
+
+/*     From gus_wave.c */
+int gus_wave_detect(int baseaddr);
+void gus_wave_init(struct address_info *hw_config);
+void gus_wave_unload (struct address_info *hw_config);
+void gus_voice_irq(void);
+void gus_write8(int reg, unsigned int data);
+void guswave_dma_irq(void);
+void gus_delay(void);
+int gus_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg);
+void gus_timer_command (unsigned int addr, unsigned int val);
+
+/*     From gus_midi.c */
+void gus_midi_init(struct address_info *hw_config);
+void gus_midi_interrupt(int dummy);
+
+/*     From ics2101.c */
+int ics2101_mixer_init(void);
index 6a42c4ce508eaaf9ca21e11b948af231d66e3e43..1029f179aa071549bcbe518d56f84764893aa226 100644 (file)
@@ -2,18 +2,13 @@
  * sound/gus_card.c
  *
  * Detection routine for the Gravis Ultrasound.
- */
-/*
+ *
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-/*
+ *
  * Frank van de Pol : Fixed GUS MAX interrupt handling, enabled simultanious
  *                    usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
+ * Christoph Hellwig: Adapted to module_init/module_exit, simple cleanups.
  *
  * Status:
  *              Tested... 
       
  
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/module.h>
 
 #include "sound_config.h"
 #include "soundmodule.h"
 
+#include "gus.h"
 #include "gus_hw.h"
 
 void            gusintr(int irq, void *dev_id, struct pt_regs *dummy);
@@ -36,13 +33,12 @@ extern int      gus_wave_volume;
 extern int      gus_pcm_volume;
 extern int      have_gus_max;
 int             gus_pnp_flag = 0;
-#ifdef CONFIG_GUS16
+#ifdef CONFIG_SOUND_GUS16
 static int      db16 = 0;      /* Has a Gus16 AD1848 on it */
 #endif
 
-void attach_gus_card(struct address_info *hw_config)
+static void __init attach_gus(struct address_info *hw_config)
 {
-
        gus_wave_init(hw_config);
 
        request_region(hw_config->io_base, 16, "GUS");
@@ -57,9 +53,10 @@ void attach_gus_card(struct address_info *hw_config)
        if(request_irq(hw_config->irq, gusintr, 0,  "Gravis Ultrasound", hw_config)<0)
                printk(KERN_ERR "gus_card.c: Unable to allocate IRQ %d\n", hw_config->irq);
 
+       return;
 }
 
-int probe_gus(struct address_info *hw_config)
+static int __init probe_gus(struct address_info *hw_config)
 {
        int             irq;
        int             io_addr;
@@ -102,10 +99,11 @@ int probe_gus(struct address_info *hw_config)
                                          }
 #endif
 
+       printk("NO GUS card found !\n");
        return 0;
 }
 
-void unload_gus(struct address_info *hw_config)
+static void __exit unload_gus(struct address_info *hw_config)
 {
        DDB(printk("unload_gus(%x)\n", hw_config->io_base));
 
@@ -128,13 +126,13 @@ void gusintr(int irq, void *dev_id, struct pt_regs *dummy)
 
        sti();
 
-#ifdef CONFIG_GUSMAX
+#ifdef CONFIG_SOUND_GUSMAX
        if (have_gus_max) {
                struct address_info *hw_config = dev_id;
                adintr(irq, (void *)hw_config->slots[1], NULL);
        }
 #endif
-#ifdef CONFIG_GUS16
+#ifdef CONFIG_SOUND_GUS16
        if (db16) {
                struct address_info *hw_config = dev_id;
                adintr(irq, (void *)hw_config->slots[3], NULL);
@@ -170,14 +168,14 @@ void gusintr(int irq, void *dev_id, struct pt_regs *dummy)
  *     Some extra code for the 16 bit sampling option
  */
 
-#ifdef CONFIG_GUS16
+#ifdef CONFIG_SOUND_GUS16
 
-int probe_gus_db16(struct address_info *hw_config)
+static int __init probe_gus_db16(struct address_info *hw_config)
 {
        return ad1848_detect(hw_config->io_base, NULL, hw_config->osp);
 }
 
-void attach_gus_db16(struct address_info *hw_config)
+static void __init attach_gus_db16(struct address_info *hw_config)
 {
        gus_pcm_volume = 100;
        gus_wave_volume = 90;
@@ -189,7 +187,7 @@ void attach_gus_db16(struct address_info *hw_config)
                                          hw_config->osp);
 }
 
-void unload_gus_db16(struct address_info *hw_config)
+static void __exit unload_gus_db16(struct address_info *hw_config)
 {
 
        ad1848_unload(hw_config->io_base,
@@ -200,27 +198,25 @@ void unload_gus_db16(struct address_info *hw_config)
 }
 #endif
 
+static int gus16 = 0;
+#ifdef CONFIG_SOUND_GUSMAX
+static int no_wave_dma = 0;/* Set if no dma is to be used for the
+                                   wave table (GF1 chip) */
+#endif
 
 
-#ifdef MODULE
-
-static struct address_info config;
-
 /*
  *    Note DMA2 of -1 has the right meaning in the GUS driver as well
  *      as here. 
  */
 
-int             io = -1;
-int             irq = -1;
-int             dma = -1;
-int             dma16 = -1;    /* Set this for modules that need it */
-int             type = 0;      /* 1 for PnP */
-int             gus16 = 0;
-#ifdef CONFIG_GUSMAX
-static int      no_wave_dma = 0;/* Set if no dma is to be used for the 
-                                  wave table (GF1 chip) */
-#endif
+static struct address_info cfg;
+
+static int __initdata io = -1;
+static int __initdata irq = -1;
+static int __initdata dma = -1;
+static int __initdata dma16 = -1;      /* Set this for modules that need it */
+static int __initdata type = 0;                /* 1 for PnP */
 
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
@@ -228,54 +224,73 @@ MODULE_PARM(dma, "i");
 MODULE_PARM(dma16, "i");
 MODULE_PARM(type, "i");
 MODULE_PARM(gus16, "i");
-#ifdef CONFIG_GUSMAX
+#ifdef CONFIG_SOUND_GUSMAX
 MODULE_PARM(no_wave_dma, "i");
 #endif
-#ifdef CONFIG_GUS16
+#ifdef CONFIG_SOUND_GUS16
 MODULE_PARM(db16, "i");
 #endif
 
-int init_module(void)
+static int __init init_gus(void)
 {
        printk(KERN_INFO "Gravis Ultrasound audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
 
-       if (io == -1 || dma == -1 || irq == -1)
-       {
+       cfg.io_base = io;
+       cfg.irq = irq;
+       cfg.dma = dma;
+       cfg.dma2 = dma16;
+       cfg.card_subtype = type;
+#ifdef CONFIG_SOUND_GUSMAX
+       gus_no_wave_dma = no_wave_dma;
+#endif
+
+       if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
                printk(KERN_ERR "I/O, IRQ, and DMA are mandatory\n");
                return -EINVAL;
        }
-       config.io_base = io;
-       config.irq = irq;
-       config.dma = dma;
-       config.dma2 = dma16;
-       config.card_subtype = type;
-       
-#ifdef CONFIG_GUSMAX
-       gus_no_wave_dma = no_wave_dma;
-#endif
 
-#if defined(CONFIG_GUS16)
-       if (probe_gus_db16(&config) && gus16)
-       {
-               attach_gus_db16(&config);
+#ifdef CONFIG_SOUND_GUS16
+       if (probe_gus_db16(&cfg) && gus16) {
+               /* FIXME: This can't work, can it ? -- Christoph */
+               attach_gus_db16(&cfg);
                db16 = 1;
        }       
 #endif
-       if (probe_gus(&config) == 0)
+       if (!probe_gus(&cfg))
                return -ENODEV;
-       attach_gus_card(&config);
+       attach_gus(&cfg);
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_gus(void)
 {
-#if defined(CONFIG_GUS16)
+#ifdef CONFIG_SOUND_GUS16
        if (db16)
-               unload_gus_db16(&config);
+               unload_gus_db16(&cfg);
 #endif
-       unload_gus(&config);
+       unload_gus(&cfg);
        SOUND_LOCK_END;
 }
 
-#endif /* MODULE */
+module_init(init_gus);
+module_exit(cleanup_gus);
+
+#ifndef MODULE
+static int __init setup_gus(char *str)
+{
+       /* io, irq, dma, dma2 */
+       int ints[5];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io      = ints[1];
+       irq     = ints[2];
+       dma     = ints[3];
+       dma16   = ints[4];
+
+       return 1;
+}
+
+__setup("gus=", setup_gus);
+#endif
index 92987f46d9d2ea99dd3d26d931c1041a4118ac39..1594afb1a01186f7753ef04e5df229a292ab5c30 100644 (file)
@@ -2,8 +2,8 @@
  * sound/gus2_midi.c
  *
  * The low level driver for the GUS Midi Interface.
- */
-/*
+ *
+ *
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -11,6 +11,8 @@
  * for more info.
  */
 #include "sound_config.h"
+
+#include "gus.h"
 #include "gus_hw.h"
 
 static int      midi_busy = 0, input_opened = 0;
index 8951cbfc35aff585f9ebb9bd49cb87e5368a17d1..6ae6924e16475d1eb2c4f2003aa7ba1bd3f771f3 100644 (file)
@@ -1,8 +1,8 @@
 
 /*
  * gus_vol.c - Compute volume for GUS.
- */
-/*
+ *
+ *
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -10,6 +10,8 @@
  * for more info.
  */
 #include "sound_config.h"
+
+#include "gus.h"
 #include "gus_linearvol.h"
 
 #define GUS_VOLUME     gus_wave_volume
index 16eac57694c4869178ab1c53e5bd7652afdbd370..30ba0ede38577476a6e45b0dd4af94155a9c63a6 100644 (file)
@@ -2,15 +2,15 @@
  * sound/gus_wave.c
  *
  * Driver for the Gravis UltraSound wave table synth.
- */
-/*
+ *
+ *
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  * Version 2 (June 1991). See the "COPYING" file distributed with this software
  * for more info.
- */
-/*
+ *
+ *
  * Thomas Sailer    : ioctl code reworked (vmalloc/vfree removed)
  * Frank van de Pol : Fixed GUS MAX interrupt handling. Enabled simultanious
  *                    usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
@@ -23,6 +23,8 @@
 
 #include "sound_config.h"
 #include <linux/ultrasound.h>
+
+#include "gus.h"
 #include "gus_hw.h"
 
 #define GUS_BANK_SIZE (((iw_mode) ? 256*1024*1024 : 256*1024))
@@ -3012,7 +3014,7 @@ void gus_wave_init(struct address_info *hw_config)
                        model_num = "MAX";
                        gus_type = 0x40;
                        mixer_type = CS4231;
-#ifdef CONFIG_GUSMAX
+#ifdef CONFIG_SOUND_GUSMAX
                        {
                                unsigned char   max_config = 0x40;      /* Codec enable */
 
@@ -3164,7 +3166,7 @@ void gus_wave_init(struct address_info *hw_config)
 
 void gus_wave_unload(struct address_info *hw_config)
 {
-#ifdef CONFIG_GUSMAX
+#ifdef CONFIG_SOUND_GUSMAX
        if (have_gus_max)
        {
                ad1848_unload(gus_base + 0x10c,
index a6b6fb4cccabdcd7a59196d6850c37bfee3d985a..3b97a157b637aeb906741418eb829d004bc7cafb 100644 (file)
@@ -2,20 +2,22 @@
  * sound/ics2101.c
  *
  * Driver for the ICS2101 mixer of GUS v3.7.
- */
-/*
+ *
+ *
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  * Version 2 (June 1991). See the "COPYING" file distributed with this software
  * for more info.
- */
-/*
+ *
+ *
  * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
  */
 #include "sound_config.h"
 
 #include <linux/ultrasound.h>
+
+#include "gus.h"
 #include "gus_hw.h"
 
 #define MIX_DEVS       (SOUND_MASK_MIC|SOUND_MASK_LINE| \
index dedf7c843e96b45ab53be36df59bc8ab269f7f6f..06b98aec25b5080ef53a13debb40954893f26bf5 100644 (file)
@@ -1,14 +1,7 @@
 /*
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-#include <linux/config.h>
-#include <linux/module.h>
-/*
- * sound/mad16.c
+ * mad16.c
  *
  * Initialization code for OPTi MAD16 compatible audio chips. Including
  *
  *
  *     Paul Grayson            Added support for Midi on later Mozart cards.
  *                                                             25-Nov-1999
+ *     Christoph Hellwig       Adapted to module_init/module_exit.
  */
 
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
 #include "sound_config.h"
 #include "soundmodule.h"
 
-#ifdef MODULE
-#define MAD16_CDSEL   mad16_cdsel
-#define MAD16_CONF    mad16_conf
+#include "ad1848.h"
+#include "sb.h"
+#include "mpu401.h"
 
 static int      mad16_conf;
 static int      mad16_cdsel;
 
-#endif
-
-#include "sb.h"
-
 static int      already_initialized = 0;
 
 #define C928   1
@@ -222,7 +216,7 @@ static void mad_write(int port, int value)
        restore_flags(flags);
 }
 
-static int detect_c930(void)
+static int __init detect_c930(void)
 {
        unsigned char   tmp = mad_read(MC1_PORT);
 
@@ -295,7 +289,7 @@ static int detect_c930(void)
        return 1;
 }
 
-static int detect_mad16(void)
+static int __init detect_mad16(void)
 {
        unsigned char tmp, tmp2, bit;
        int i, port;
@@ -346,7 +340,7 @@ static int detect_mad16(void)
        return 1;               /* Bingo */
 }
 
-static int wss_init(struct address_info *hw_config)
+static int __init wss_init(struct address_info *hw_config)
 {
        int ad_flags = 0;
 
@@ -397,7 +391,7 @@ static int wss_init(struct address_info *hw_config)
        return 1;
 }
 
-static int init_c930(struct address_info *hw_config)
+static int __init init_c930(struct address_info *hw_config)
 {
        unsigned char cfg = 0;
 
@@ -457,7 +451,7 @@ static int init_c930(struct address_info *hw_config)
        return wss_init(hw_config);
 }
 
-static int chip_detect(void)
+static int __init chip_detect(void)
 {
        int i;
 
@@ -536,7 +530,7 @@ static int chip_detect(void)
        return 1;
 }
 
-int probe_mad16(struct address_info *hw_config)
+static int __init probe_mad16(struct address_info *hw_config)
 {
        int i;
        static int valid_ports[] = 
@@ -646,7 +640,7 @@ int probe_mad16(struct address_info *hw_config)
        return 1;
 }
 
-void attach_mad16(struct address_info *hw_config)
+static void __init attach_mad16(struct address_info *hw_config)
 {
 
        static char     interrupt_bits[12] = {
@@ -720,7 +714,7 @@ void attach_mad16(struct address_info *hw_config)
        request_region(hw_config->io_base, 4, "MAD16 WSS config");
 }
 
-void attach_mad16_mpu(struct address_info *hw_config)
+static void __init attach_mad16_mpu(struct address_info *hw_config)
 {
 #ifdef CONFIG_MAD16_OLDCARD
 
@@ -742,7 +736,7 @@ void attach_mad16_mpu(struct address_info *hw_config)
        attach_uart401(hw_config);
 }
 
-int probe_mad16_mpu(struct address_info *hw_config)
+static int __init probe_mad16_mpu(struct address_info *hw_config)
 {
        static int mpu_attached = 0;
        static int valid_ports[] = {
@@ -898,7 +892,7 @@ int probe_mad16_mpu(struct address_info *hw_config)
        return probe_uart401(hw_config);
 }
 
-void unload_mad16(struct address_info *hw_config)
+static void __exit unload_mad16(struct address_info *hw_config)
 {
        ad1848_unload(hw_config->io_base + 4,
                        hw_config->irq,
@@ -908,8 +902,7 @@ void unload_mad16(struct address_info *hw_config)
        sound_unload_audiodev(hw_config->slots[0]);
 }
 
-void
-unload_mad16_mpu(struct address_info *hw_config)
+static void __exit unload_mad16_mpu(struct address_info *hw_config)
 {
 #ifdef CONFIG_MAD16_OLDCARD
        if (board_type < C929)  /* Early chip. No MPU support. Just SB MIDI */
@@ -922,21 +915,23 @@ unload_mad16_mpu(struct address_info *hw_config)
        unload_uart401(hw_config);
 }
 
-#ifdef MODULE
+static struct address_info cfg;
+static struct address_info cfg_mpu;
 
-int            mpu_io = 0;
-int            mpu_irq = 0;
-int             io = -1;
-int             dma = -1;
-int             dma16 = -1;    /* Set this for modules that need it */
-int             irq = -1;
+static int found_mpu;
 
-int             cdtype = 0;
-int             cdirq = 0;
-int             cdport = 0x340;
-int             cddma = -1;
-int             opl4 = 0;
-int             joystick = 0;
+static int __initdata mpu_io = 0;
+static int __initdata mpu_irq = 0;
+static int __initdata io = -1;
+static int __initdata dma = -1;
+static int __initdata dma16 = -1; /* Set this for modules that need it */
+static int __initdata irq = -1;
+static int __initdata cdtype = 0;
+static int __initdata cdirq = 0;
+static int __initdata cdport = 0x340;
+static int __initdata cddma = -1;
+static int __initdata opl4 = 0;
+static int __initdata joystick = 0;
 
 MODULE_PARM(mpu_io, "i");
 MODULE_PARM(mpu_irq, "i");
@@ -952,18 +947,13 @@ MODULE_PARM(opl4,"i");
 MODULE_PARM(joystick,"i");
 MODULE_PARM(debug,"i");
 
-EXPORT_NO_SYMBOLS;
-
-static int found_mpu;
-
-
-static int dma_map[2][8] =
+static int __initdata dma_map[2][8] =
 {
        {0x03, -1, -1, -1, -1, 0x00, 0x01, 0x02},
        {0x03, -1, 0x01, 0x00, -1, -1, -1, -1}
 };
 
-static int irq_map[16] =
+static int __initdata irq_map[16] =
 {
        0x00, -1, -1, 0x0A,
        -1, 0x04, -1, 0x08,
@@ -971,20 +961,12 @@ static int irq_map[16] =
        -1, -1, -1, -1
 };
 
-struct address_info config;
-struct address_info config_mpu;
-
-int init_module(void)
+static int __init init_mad16(void)
 {
        int dmatype = 0;
 
        printk(KERN_INFO "MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
 
-       if (io == -1 || dma == -1 || irq == -1)
-       {
-               printk(KERN_ERR "I/O, DMA and irq are mandatory\n");
-               return -EINVAL;
-       }
        printk(KERN_INFO "CDROM ");
        switch (cdtype)
        {
@@ -1089,33 +1071,61 @@ int init_module(void)
                 printk("disabled.\n");
         }
 
-       config.io_base = io;
-       config.irq = irq;
-       config.dma = dma;
-       config.dma2 = dma16;
+       cfg.io_base = io;
+       cfg.irq = irq;
+       cfg.dma = dma;
+       cfg.dma2 = dma16;
 
-       if (!probe_mad16(&config))
+       if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
+               printk(KERN_ERR "I/O, DMA and irq are mandatory\n");
+               return -EINVAL;
+       }
+       
+       if (!probe_mad16(&cfg))
                return -ENODEV;
 
-       config_mpu.io_base = mpu_io;
-       config_mpu.irq = mpu_irq;
-       attach_mad16(&config);
+       cfg_mpu.io_base = mpu_io;
+       cfg_mpu.irq = mpu_irq;
+
+       attach_mad16(&cfg);
 
-       found_mpu = probe_mad16_mpu(&config_mpu);
+       found_mpu = probe_mad16_mpu(&cfg_mpu);
 
        if (found_mpu)
-               attach_mad16_mpu(&config_mpu);
+               attach_mad16_mpu(&cfg_mpu);
 
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_mad16(void)
 {
        if (found_mpu)
-               unload_mad16_mpu(&config_mpu);
-       unload_mad16(&config);
+               unload_mad16_mpu(&cfg_mpu);
+       unload_mad16(&cfg);
        SOUND_LOCK_END;
 }
 
-#endif /* MODULE */
+module_init(init_mad16);
+module_exit(exit_mad16);
+
+#ifndef MODULE
+static int __init setup_mad16(char *str)
+{
+        /* io, irq */
+       int ints[7];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+
+       io      = ints[1];
+       irq     = ints[2];
+       dma     = ints[3];
+       dma16   = ints[4];
+       mpu_io  = ints[5];
+       mpu_irq = ints[6];
+
+       return 1;
+}
+
+__setup("mad16=", setup_mad16);
+#endif
index 532e7573b7dcefa56c2e0f3719eba3affd0323ef..797150997a2ad095c6efcaba2b8d60fd729a0119 100644 (file)
@@ -2,8 +2,8 @@
  * sound/maui.c
  *
  * The low level driver for Turtle Beach Maui and Tropez.
- */
-/*
+ *
+ *
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
@@ -13,6 +13,7 @@
  *     Changes:
  *             Alan Cox                General clean up, use kernel IRQ 
  *                                     system
+ *             Christoph Hellwig       Adapted to module_init/module_exit
  *
  *     Status:
  *             Andrew J. Kroll         Tested 06/01/1999 with:
@@ -32,6 +33,8 @@
 #include "soundmodule.h"
 #include "sound_firmware.h"
 
+#include "mpu401.h"
+
 static int      maui_base = 0x330;
 
 static volatile int irq_ok = 0;
@@ -62,19 +65,14 @@ static int maui_wait(int mask)
         */
 
        for (i = 0; i < 100; i++)
-       {
                if (inb(HOST_STAT_PORT) & mask)
-               {
                        return 1;
-               }
-       }
 
        /*
         * Wait up to 15 seconds with sleeping
         */
 
-       for (i = 0; i < 150; i++)
-       {
+       for (i = 0; i < 150; i++) {
                if (inb(HOST_STAT_PORT) & mask)
                        return 1;
                current->state = TASK_INTERRUPTIBLE;
@@ -94,8 +92,7 @@ static int maui_read(void)
 
 static int maui_write(unsigned char data)
 {
-       if (maui_wait(STAT_TX_AVAIL))
-       {
+       if (maui_wait(STAT_TX_AVAIL)) {
                outb((data), HOST_DATA_PORT);
                return 1;
        }
@@ -116,56 +113,45 @@ static int download_code(void)
 
        printk(KERN_INFO "Code download (%d bytes): ", maui_osLen);
 
-       for (i = 0; i < maui_osLen; i++)
-       {
-               if (maui_os[i] != '\r')
-               {
-                       if (!skip || (maui_os[i] == 'S' && (i == 0 || maui_os[i - 1] == '\n')))
-                       {
+       for (i = 0; i < maui_osLen; i++) {
+               if (maui_os[i] != '\r') {
+                       if (!skip || (maui_os[i] == 'S' && (i == 0 || maui_os[i - 1] == '\n'))) {
                                skip = 0;
 
                                if (maui_os[i] == '\n')
                                        eol_seen = skip = 1;
-                               else if (maui_os[i] == 'S')
-                               {
+                               else if (maui_os[i] == 'S') {
                                        if (maui_os[i + 1] == '8')
                                                done = 1;
                                        if (!maui_write(0xF1))
                                                goto failure;
                                        if (!maui_write('S'))
                                                goto failure;
-                               }
-                               else
-                               {
+                               } else {
                                        if (!maui_write(maui_os[i]))
                                                goto failure;
                                }
 
-                               if (eol_seen)
-                               {
+                               if (eol_seen) {
                                        int c = 0;
                                        int n;
 
                                        eol_seen = 0;
 
-                                       for (n = 0; n < 2; n++)
-                                       {
-                                               if (maui_wait(STAT_RX_AVAIL))
-                                               {
+                                       for (n = 0; n < 2; n++) {
+                                               if (maui_wait(STAT_RX_AVAIL)) {
                                                        c = inb(HOST_DATA_PORT);
                                                        break;
                                                }
                                        }
-                                       if (c != 0x80)
-                                       {
+                                       if (c != 0x80) {
                                                printk("Download not acknowledged\n");
                                                return 0;
                                        }
                                        else if (!(lines++ % 10))
                                                printk(".");
 
-                                       if (done)
-                                       {
+                                       if (done) {
                                                printk("\n");
                                                printk(KERN_INFO "Download complete\n");
                                                return 1;
@@ -181,15 +167,11 @@ failure:
        return 0;
 }
 
-static int maui_init(int irq)
+static int __init maui_init(int irq)
 {
-#ifdef CONFIG_SMP
-       int i;
-#endif 
        unsigned char bits;
 
-       switch (irq)
-       {
+       switch (irq) {
                case 9:
                        bits = 0x00;
                        break;
@@ -215,10 +197,13 @@ static int maui_init(int irq)
        outb((0xD0), HOST_CTRL_PORT);   /* Cause interrupt */
 
 #ifdef CONFIG_SMP
-       for (i = 0; i < 1000000 && !irq_ok; i++);
-
-       if (!irq_ok)
-               return 0;
+       {
+               int i;
+               for (i = 0; i < 1000000 && !irq_ok; i++)
+                       ;
+               if (!irq_ok)
+                       return 0;
+       }
 #endif
        outb((0x80), HOST_CTRL_PORT);   /* Leave reset */
 
@@ -233,8 +218,7 @@ static int maui_init(int irq)
 
        maui_write(0xf0);
        maui_write(1);
-       if (maui_read() != 0x80)
-       {
+       if (maui_read() != 0x80) {
                maui_write(0xf0);
                maui_write(1);
                if (maui_read() != 0x80)
@@ -244,14 +228,11 @@ static int maui_init(int irq)
        return 1;
 }
 
-static int maui_short_wait(int mask)
-{
+static int maui_short_wait(int mask) {
        int i;
 
-       for (i = 0; i < 1000; i++)
-       {
-               if (inb(HOST_STAT_PORT) & mask)
-               {
+       for (i = 0; i < 1000; i++) {
+               if (inb(HOST_STAT_PORT) & mask) {
                        return 1;
                }
        }
@@ -274,8 +255,7 @@ static int maui_load_patch(int dev, int format, const char *addr,
        {
                  printk(KERN_WARNING "Maui: Unknown patch format\n");
        }
-       if (count < hdr_size)
-       {
+       if (count < hdr_size) {
 /*               printk("Maui error: Patch header too short\n");*/
                  return -EINVAL;
        }
@@ -289,16 +269,14 @@ static int maui_load_patch(int dev, int format, const char *addr,
        if(copy_from_user(&((char *) &header)[offs], &(addr)[offs], hdr_size - offs))
                return -EFAULT;
 
-       if (count < header.len)
-       {
+       if (count < header.len) {
                  printk(KERN_ERR "Maui warning: Host command record too short (%d<%d)\n", count, (int) header.len);
                  header.len = count;
        }
        left = header.len;
        src_offs = 0;
 
-       for (i = 0; i < left; i++)
-       {
+       for (i = 0; i < left; i++) {
                unsigned char   data;
 
                if(get_user(*(unsigned char *) &data, (unsigned char *) &((addr)[hdr_size + i])))
@@ -310,8 +288,7 @@ static int maui_load_patch(int dev, int format, const char *addr,
                        return -EIO;
        }
 
-       if ((i = maui_read()) != 0x80)
-       {
+       if ((i = maui_read()) != 0x80) {
                if (i != -1)
                        printk("Maui: Error status %02x\n", i);
                return -EIO;
@@ -319,7 +296,7 @@ static int maui_load_patch(int dev, int format, const char *addr,
        return 0;
 }
 
-int probe_maui(struct address_info *hw_config)
+static int __init probe_maui(struct address_info *hw_config)
 {
        int i;
        int tmp1, tmp2, ret;
@@ -337,55 +314,46 @@ int probe_maui(struct address_info *hw_config)
         * Initialize the processor if necessary
         */
 
-       if (maui_osLen > 0)
-       {
+       if (maui_osLen > 0) {
                if (!(inb(HOST_STAT_PORT) & STAT_TX_AVAIL) ||
                        !maui_write(0x9F) ||    /* Report firmware version */
                        !maui_short_wait(STAT_RX_AVAIL) ||
                        maui_read() == -1 || maui_read() == -1)
-                       if (!maui_init(hw_config->irq))
-                       {
+                       if (!maui_init(hw_config->irq)) {
                                free_irq(hw_config->irq, NULL);
                                return 0;
                        }
        }
-       if (!maui_write(0xCF))  /* Report hardware version */
-       {
+       if (!maui_write(0xCF))  /* Report hardware version */ {
                printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
                free_irq(hw_config->irq, NULL);
                return 0;
        }
-       if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1)
-       {
+       if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1) {
                printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
                free_irq(hw_config->irq, NULL);
                return 0;
        }
-       if (tmp1 == 0xff || tmp2 == 0xff)
-       {
+       if (tmp1 == 0xff || tmp2 == 0xff) {
                free_irq(hw_config->irq, NULL);
                return 0;
        }
-       if (trace_init)
-               printk(KERN_DEBUG "WaveFront hardware version %d.%d\n", tmp1, tmp2);
+       printk(KERN_DEBUG "WaveFront hardware version %d.%d\n", tmp1, tmp2);
 
        if (!maui_write(0x9F))  /* Report firmware version */
                return 0;
        if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1)
                return 0;
 
-       if (trace_init)
-               printk(KERN_DEBUG "WaveFront firmware version %d.%d\n", tmp1, tmp2);
+       printk(KERN_DEBUG "WaveFront firmware version %d.%d\n", tmp1, tmp2);
 
        if (!maui_write(0x85))  /* Report free DRAM */
                return 0;
        tmp1 = 0;
-       for (i = 0; i < 4; i++)
-       {
+       for (i = 0; i < 4; i++) {
                tmp1 |= maui_read() << (7 * i);
        }
-       if (trace_init)
-               printk(KERN_DEBUG "Available DRAM %dk\n", tmp1 / 1024);
+       printk(KERN_DEBUG "Available DRAM %dk\n", tmp1 / 1024);
 
        for (i = 0; i < 1000; i++)
                if (probe_mpu401(hw_config))
@@ -399,7 +367,7 @@ int probe_maui(struct address_info *hw_config)
        return ret;
 }
 
-void attach_maui(struct address_info *hw_config)
+static void __init attach_maui(struct address_info *hw_config)
 {
        int this_dev;
 
@@ -409,8 +377,7 @@ void attach_maui(struct address_info *hw_config)
        hw_config->name = "Maui";
        attach_mpu401(hw_config);
 
-       if (hw_config->slots[1] != -1)  /* The MPU401 driver installed itself */
-       {
+       if (hw_config->slots[1] != -1)  /* The MPU401 driver installed itself */ {
                struct synth_operations *synth;
 
                this_dev = hw_config->slots[1];
@@ -423,17 +390,15 @@ void attach_maui(struct address_info *hw_config)
                synth = midi_devs[this_dev]->converter;
                synth->id = "MAUI";
 
-               if (synth != NULL)
-               {
+               if (synth != NULL) {
                        orig_load_patch = synth->load_patch;
                        synth->load_patch = &maui_load_patch;
-               }
-               else
+               } else
                        printk(KERN_ERR "Maui: Can't install patch loader\n");
        }
 }
 
-void unload_maui(struct address_info *hw_config)
+static void __exit unload_maui(struct address_info *hw_config)
 {
        int irq = hw_config->irq;
        release_region(hw_config->io_base + 2, 6);
@@ -445,37 +410,33 @@ void unload_maui(struct address_info *hw_config)
                free_irq(irq, NULL);
 }
 
-#ifdef MODULE
-
-MODULE_PARM(io,"i");
-MODULE_PARM(irq,"i");
-
-EXPORT_NO_SYMBOLS;
+static int fw_load = 0;
 
-int io = -1;
-int irq = -1;
+static struct address_info cfg;
 
-static int fw_load = 0;
+static int __initdata io = -1;
+static int __initdata irq = -1;
 
-struct address_info cfg;
+MODULE_PARM(io,"i");
+MODULE_PARM(irq,"i");
 
 /*
  *     Install a Maui card. Needs mpu401 loaded already.
  */
 
-int init_module(void)
+static int __init init_maui(void)
 {
        printk(KERN_INFO "Turtle beach Maui and Tropez driver, Copyright (C) by Hannu Savolainen 1993-1996\n");
-       if (io == -1 || irq == -1)
-       {
+
+       cfg.io_base = io;
+       cfg.irq = irq;
+
+       if (cfg.io_base == -1 || cfg.irq == -1) {
                printk(KERN_INFO "maui: irq and io must be set.\n");
                return -EINVAL;
        }
-       cfg.io_base = io;
-       cfg.irq = irq;
 
-       if (maui_os == NULL)
-       {
+       if (maui_os == NULL) {
                fw_load = 1;
                maui_osLen = mod_firmware_load("/etc/sound/oswf.mot", (char **) &maui_os);
        }
@@ -486,11 +447,30 @@ int init_module(void)
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_maui(void)
 {
        if (fw_load && maui_os)
                vfree(maui_os);
        unload_maui(&cfg);
        SOUND_LOCK_END;
 }
-#endif /* MODULE */
+
+module_init(init_maui);
+module_exit(cleanup_maui);
+
+#ifndef MODULE
+static int __init setup_maui(char *str)
+{
+        /* io, irq */
+       int ints[3];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io = ints[1];
+       irq = ints[2];
+
+       return 1;
+}
+
+__setup("maui=", setup_maui);
+#endif
index 8a334d263100b08ca275d0253ca716d8e9d47b4b..2757659aceb7cecad864d4dfcb5249b7d4d742b4 100644 (file)
@@ -15,6 +15,7 @@
  * Alan Cox            modularisation, use normal request_irq, use dev_id
  */
 
+#include <linux/init.h>
 #include <linux/module.h>
 
 #define USE_SEQ_MACROS
@@ -24,7 +25,7 @@
 #include "soundmodule.h"
 
 #include "coproc.h"
-
+#include "mpu401.h"
 
 static int      timer_mode = TMR_INTERNAL, timer_caps = TMR_INTERNAL;
 
@@ -910,7 +911,7 @@ static struct midi_operations mpu401_midi_proto =
 
 static struct midi_operations mpu401_midi_operations[MAX_MIDI_DEV];
 
-static void mpu401_chk_version(int n, struct mpu_config *devc)
+static void __init mpu401_chk_version(int n, struct mpu_config *devc)
 {
        int tmp;
        unsigned long flags;
@@ -941,7 +942,7 @@ static void mpu401_chk_version(int n, struct mpu_config *devc)
        restore_flags(flags);
 }
 
-void attach_mpu401(struct address_info *hw_config)
+void __init attach_mpu401(struct address_info *hw_config)
 {
        unsigned long flags;
        char revision_char;
@@ -1164,7 +1165,7 @@ static void set_uart_mode(int dev, struct mpu_config *devc, int arg)
 
 }
 
-int probe_mpu401(struct address_info *hw_config)
+int __init probe_mpu401(struct address_info *hw_config)
 {
        int ok = 0;
        struct mpu_config tmp_devc;
@@ -1197,7 +1198,7 @@ int probe_mpu401(struct address_info *hw_config)
        return ok;
 }
 
-void unload_mpu401(struct address_info *hw_config)
+void __exit unload_mpu401(struct address_info *hw_config)
 {
        void *p;
        int n=hw_config->slots[1];
@@ -1659,7 +1660,7 @@ static void timer_ext_event(struct mpu_config *devc, int event, int parm)
        }
 }
 
-static int mpu_timer_init(int midi_dev)
+static int __init mpu_timer_init(int midi_dev)
 {
        struct mpu_config *devc;
        int n;
@@ -1713,39 +1714,56 @@ EXPORT_SYMBOL(unload_mpu401);
 EXPORT_SYMBOL(intchk_mpu401);
 EXPORT_SYMBOL(mpuintr);
 
-#ifdef MODULE
+static struct address_info cfg;
+
+static int __initdata io = -1;
+static int __initdata irq = -1;
 
 MODULE_PARM(irq, "i");
 MODULE_PARM(io, "i");
 
-int             io = -1;
-int             irq = -1;
-struct address_info hw;
-
-int init_module(void)
+int init_mpu401(void)
 {
        /* Can be loaded either for module use or to provide functions
           to others */
-       if (io != -1 && irq != -1)
-       {
-               hw.irq = irq;
-               hw.io_base = io;
-               if (probe_mpu401(&hw) == 0)
-                       return -ENODEV;
-               attach_mpu401(&hw);
+       cfg.irq = irq;
+       cfg.io_base = io;
+       
+       if (cfg.io_base != -1 && cfg.irq != -1) {
+               printk(KERN_WARNING "mpu401: need io and irq !");
+               return -ENODEV;
        }
+       
+       if (probe_mpu401(&cfg) == 0)
+               return -ENODEV;
+       attach_mpu401(&cfg);
+
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+void cleanup_mpu401(void)
 {
-       if (io != -1 && irq != -1)
-       {
-               unload_mpu401(&hw);
-       }
-       /*  FREE SYMTAB */
+       unload_mpu401(&cfg);
        SOUND_LOCK_END;
 }
 
-#endif /* MODULE */
+module_init(init_mpu401);
+module_exit(cleanup_mpu401);
+
+#ifndef MODULE
+static int __init setup_mpu401(char *str)
+{
+        /* io, irq */
+       int ints[3];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io = ints[1];
+       irq = ints[2];
+
+       return 1;
+}
+
+__setup("mpu401=", setup_mpu401);
+#endif
diff --git a/drivers/sound/mpu401.h b/drivers/sound/mpu401.h
new file mode 100644 (file)
index 0000000..a6a41cb
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ *     uart401.h 
+ *
+ * Copyright:  Christoph Hellwig <chhellwig@gmx.net>
+ *
+ */
+
+/*     From uart401.c */
+int probe_uart401 (struct address_info *hw_config);
+void attach_uart401 (struct address_info *hw_config);
+void unload_uart401 (struct address_info *hw_config);
+
+void uart401intr (int irq, void *dev_id, struct pt_regs * dummy);
+
+/*     From mpu401.c */
+int probe_mpu401(struct address_info *hw_config);
+void attach_mpu401(struct address_info * hw_config);
+void unload_mpu401(struct address_info *hw_info);
+
+int intchk_mpu401(void *dev_id);
+void mpuintr(int irq, void *dev_id, struct pt_regs * dummy);
index 53e54404a668d19b0816400db61ce56f600d33ca..ef0a1ce2e7262d4f40d983e7640b57b780cb8148 100644 (file)
@@ -15,6 +15,7 @@
 
 #define __NO_VERSION__
 #include <linux/pci.h>
+#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pm.h>
 #include "sound_config.h"
@@ -1639,8 +1640,6 @@ static struct audio_driver nm256_audio_driver =
 
 EXPORT_SYMBOL(init_nm256);
 
-#ifdef MODULE
-
 static int loaded = 0;
 
 MODULE_PARM (usecache, "i");
@@ -1648,8 +1647,7 @@ MODULE_PARM (buffertop, "i");
 MODULE_PARM (nm256_debug, "i");
 MODULE_PARM (force_load, "i");
 
-int
-init_module (void)
+static int __init do_init_nm256(void)
 {
     nmcard_list = NULL;
     printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.1\n");
@@ -1663,8 +1661,7 @@ init_module (void)
        return -ENODEV;
 }
 
-void
-cleanup_module (void)
+static void __exit cleanup_nm256 (void)
 {
     if (loaded) {
        struct nm256_info *card;
@@ -1688,8 +1685,10 @@ cleanup_module (void)
     }
     pm_unregister_all (&handle_pm_event);
 }
-#endif
-\f
+
+module_init(do_init_nm256);
+module_exit(cleanup_nm256);
+
 /*
  * Local variables:
  *  c-basic-offset: 4
index acaf989cadd902ea958e7d50d85575af8eed74df..951dfe4d3611ce6d3e72696f7e93d0a76a10fcd6 100644 (file)
@@ -3,7 +3,7 @@
  *
  * A low level driver for Yamaha YM3812 and OPL-3 -chips
  *
-*
+ *
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  *
  *
  * Changes
- *     Thomas Sailer   ioctl code reworked (vmalloc/vfree removed)
- *     Alan Cox        modularisation, fixed sound_mem allocs.
+ *     Thomas Sailer           ioctl code reworked (vmalloc/vfree removed)
+ *     Alan Cox                modularisation, fixed sound_mem allocs.
+ *     Christoph Hellwig       Adapted to module_init/module_exit
  *
  * Status
  *     Believed to work. Badly needs rewriting a bit to support multiple
  *     OPL3 devices.
  */
 
+#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 
@@ -32,6 +34,7 @@
 #include "soundmodule.h"
 
 #include "opl3.h"
+#include "opl3_hw.h"
 
 #define MAX_VOICE      18
 #define OFFS_4OP       11
@@ -1171,18 +1174,19 @@ int opl3_init(int ioaddr, int *osp)
        return me;
 }
 
-#ifdef MODULE
+EXPORT_SYMBOL(opl3_init);
+EXPORT_SYMBOL(opl3_detect);
 
-/*
- *    We provide OPL3 functions.
- */
+static int me;
+
+static int io = -1;
 
-int io = -1;
-int me;
+MODULE_PARM(io, "i");
 
-int init_module (void)
+static int __init init_opl3 (void)
 {
        printk(KERN_INFO "YM3812 and OPL-3 driver Copyright (C) by Hannu Savolainen, Rob Hooft 1993-1996\n");
+
        if (io != -1)   /* User loading pure OPL3 module */
        {
                if (check_region(io, 4))
@@ -1195,14 +1199,14 @@ int init_module (void)
                        return -ENODEV;
                }
                me = opl3_init(io, NULL);
-               request_region(io,4,devc->fm_info.name);
+               request_region(io, 4, devc->fm_info.name);
 
        }
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_opl3(void)
 {
        if (devc && io != -1)
        {
@@ -1215,10 +1219,21 @@ void cleanup_module(void)
        SOUND_LOCK_END;
 }
 
-MODULE_PARM(io, "i");
+module_init(init_opl3);
+module_exit(cleanup_opl3);
 
-#endif /* MODULE */
+#ifndef MODULE
+static int __init setup_opl3(char *str)
+{
+        /* io  */
+       int ints[2];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io = ints[1];
 
-EXPORT_SYMBOL(opl3_init);
-EXPORT_SYMBOL(opl3_detect);
+       return 1;
+}
 
+__setup("opl3=", setup_opl3);
+#endif
index 5529d19d8a65c738964e6c7d0f6c1dba79080300..6ef00614bb86b397ac5d5db3e3b55a28692a125d 100644 (file)
 /*
- *     opl3.h  - Definitions of the OPL-3 registers
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-
-/*
- *     The OPL-3 mode is switched on by writing 0x01, to the offset 5
- *     of the right side.
- *
- *     Another special register at the right side is at offset 4. It contains
- *     a bit mask defining which voices are used as 4 OP voices.
- *
- *     The percussive mode is implemented in the left side only.
- *
- *     With the above exceptions the both sides can be operated independently.
- *     
- *     A 4 OP voice can be created by setting the corresponding
- *     bit at offset 4 of the right side.
+ *     opl3.h
  *
- *     For example setting the rightmost bit (0x01) changes the
- *     first voice on the right side to the 4 OP mode. The fourth
- *     voice is made inaccessible.
+ * Copyright:  Christoph Hellwig <chhellwig@gmx.net>
  *
- *     If a voice is set to the 2 OP mode, it works like 2 OP modes
- *     of the original YM3812 (AdLib). In addition the voice can 
- *     be connected the left, right or both stereo channels. It can
- *     even be left unconnected. This works with 4 OP voices also.
- *
- *     The stereo connection bits are located in the FEEDBACK_CONNECTION
- *     register of the voice (0xC0-0xC8). In 4 OP voices these bits are
- *     in the second half of the voice.
- */
-
-/*
- *     Register numbers for the global registers
- */
-
-#define TEST_REGISTER                          0x01
-#define   ENABLE_WAVE_SELECT           0x20
-
-#define TIMER1_REGISTER                                0x02
-#define TIMER2_REGISTER                                0x03
-#define TIMER_CONTROL_REGISTER                 0x04    /* Left side */
-#define   IRQ_RESET                    0x80
-#define   TIMER1_MASK                  0x40
-#define   TIMER2_MASK                  0x20
-#define   TIMER1_START                 0x01
-#define   TIMER2_START                 0x02
-
-#define CONNECTION_SELECT_REGISTER             0x04    /* Right side */
-#define   RIGHT_4OP_0                  0x01
-#define   RIGHT_4OP_1                  0x02
-#define   RIGHT_4OP_2                  0x04
-#define   LEFT_4OP_0                   0x08
-#define   LEFT_4OP_1                   0x10
-#define   LEFT_4OP_2                   0x20
-
-#define OPL3_MODE_REGISTER                     0x05    /* Right side */
-#define   OPL3_ENABLE                  0x01
-#define   OPL4_ENABLE                  0x02
-
-#define KBD_SPLIT_REGISTER                     0x08    /* Left side */
-#define   COMPOSITE_SINE_WAVE_MODE     0x80            /* Don't use with OPL-3? */
-#define   KEYBOARD_SPLIT               0x40
-
-#define PERCOSSION_REGISTER                    0xbd    /* Left side only */
-#define   TREMOLO_DEPTH                        0x80
-#define   VIBRATO_DEPTH                        0x40
-#define          PERCOSSION_ENABLE             0x20
-#define   BASSDRUM_ON                  0x10
-#define   SNAREDRUM_ON                 0x08
-#define   TOMTOM_ON                    0x04
-#define   CYMBAL_ON                    0x02
-#define   HIHAT_ON                     0x01
-
-/*
- *     Offsets to the register banks for operators. To get the
- *     register number just add the operator offset to the bank offset
- *
- *     AM/VIB/EG/KSR/Multiple (0x20 to 0x35)
- */
-#define AM_VIB                                 0x20
-#define   TREMOLO_ON                   0x80
-#define   VIBRATO_ON                   0x40
-#define   SUSTAIN_ON                   0x20
-#define   KSR                          0x10    /* Key scaling rate */
-#define   MULTIPLE_MASK                0x0f    /* Frequency multiplier */
-
- /*
-  *    KSL/Total level (0x40 to 0x55)
-  */
-#define KSL_LEVEL                              0x40
-#define   KSL_MASK                     0xc0    /* Envelope scaling bits */
-#define   TOTAL_LEVEL_MASK             0x3f    /* Strength (volume) of OP */
-
-/*
- *     Attack / Decay rate (0x60 to 0x75)
- */
-#define ATTACK_DECAY                           0x60
-#define   ATTACK_MASK                  0xf0
-#define   DECAY_MASK                   0x0f
-
-/*
- * Sustain level / Release rate (0x80 to 0x95)
- */
-#define SUSTAIN_RELEASE                                0x80
-#define   SUSTAIN_MASK                 0xf0
-#define   RELEASE_MASK                 0x0f
-
-/*
- * Wave select (0xE0 to 0xF5)
  */
-#define WAVE_SELECT                    0xe0
-
-/*
- *     Offsets to the register banks for voices. Just add to the
- *     voice number to get the register number.
- *
- *     F-Number low bits (0xA0 to 0xA8).
- */
-#define FNUM_LOW                               0xa0
-
-/*
- *     F-number high bits / Key on / Block (octave) (0xB0 to 0xB8)
- */
-#define KEYON_BLOCK                                    0xb0
-#define          KEYON_BIT                             0x20
-#define          BLOCKNUM_MASK                         0x1c
-#define   FNUM_HIGH_MASK                       0x03
-
-/*
- *     Feedback / Connection (0xc0 to 0xc8)
- *
- *     These registers have two new bits when the OPL-3 mode
- *     is selected. These bits controls connecting the voice
- *     to the stereo channels. For 4 OP voices this bit is
- *     defined in the second half of the voice (add 3 to the
- *     register offset).
- *
- *     For 4 OP voices the connection bit is used in the
- *     both halves (gives 4 ways to connect the operators).
- */
-#define FEEDBACK_CONNECTION                            0xc0
-#define   FEEDBACK_MASK                                0x0e    /* Valid just for 1st OP of a voice */
-#define   CONNECTION_BIT                       0x01
-/*
- *     In the 4 OP mode there is four possible configurations how the
- *     operators can be connected together (in 2 OP modes there is just
- *     AM or FM). The 4 OP connection mode is defined by the rightmost
- *     bit of the FEEDBACK_CONNECTION (0xC0-0xC8) on the both halves.
- *
- *     First half      Second half     Mode
- *
- *                                      +---+
- *                                      v   |
- *     0               0               >+-1-+--2--3--4-->
- *
- *
- *                                     
- *                                      +---+
- *                                      |   |
- *     0               1               >+-1-+--2-+
- *                                               |->
- *                                     >--3----4-+
- *                                     
- *                                      +---+
- *                                      |   |
- *     1               0               >+-1-+-----+
- *                                                |->
- *                                     >--2--3--4-+
- *
- *                                      +---+
- *                                      |   |
- *     1               1               >+-1-+--+
- *                                             |
- *                                     >--2--3-+->
- *                                             |
- *                                     >--4----+
- */
-#define   STEREO_BITS                          0x30    /* OPL-3 only */
-#define     VOICE_TO_LEFT              0x10
-#define     VOICE_TO_RIGHT             0x20
-
-/*
- *     Definition table for the physical voices
- */
-
-struct physical_voice_info {
-               unsigned char voice_num;
-               unsigned char voice_mode; /* 0=unavailable, 2=2 OP, 4=4 OP */
-               unsigned short ioaddr; /* I/O port (left or right side) */
-               unsigned char op[4]; /* Operator offsets */
-       };
-
-/*
- *     There is 18 possible 2 OP voices
- *     (9 in the left and 9 in the right).
- *     The first OP is the modulator and 2nd is the carrier.
- *
- *     The first three voices in the both sides may be connected
- *     with another voice to a 4 OP voice. For example voice 0
- *     can be connected with voice 3. The operators of voice 3 are
- *     used as operators 3 and 4 of the new 4 OP voice.
- *     In this case the 2 OP voice number 0 is the 'first half' and
- *     voice 3 is the second.
- */
-
-#define USE_LEFT       0
-#define USE_RIGHT      1
-
-static struct physical_voice_info pv_map[18] =
-{
-/*       No Mode Side          OP1     OP2     OP3   OP4       */
-/*     ---------------------------------------------------     */
-       { 0,  2, USE_LEFT,      {0x00,  0x03,   0x08, 0x0b}},
-       { 1,  2, USE_LEFT,      {0x01,  0x04,   0x09, 0x0c}},
-       { 2,  2, USE_LEFT,      {0x02,  0x05,   0x0a, 0x0d}},
-
-       { 3,  2, USE_LEFT,      {0x08,  0x0b,   0x00, 0x00}},
-       { 4,  2, USE_LEFT,      {0x09,  0x0c,   0x00, 0x00}},
-       { 5,  2, USE_LEFT,      {0x0a,  0x0d,   0x00, 0x00}},
-
-       { 6,  2, USE_LEFT,      {0x10,  0x13,   0x00, 0x00}}, /* Used by percussive voices */
-       { 7,  2, USE_LEFT,      {0x11,  0x14,   0x00, 0x00}}, /* if the percussive mode */
-       { 8,  2, USE_LEFT,      {0x12,  0x15,   0x00, 0x00}}, /* is selected */
-
-       { 0,  2, USE_RIGHT,     {0x00,  0x03,   0x08, 0x0b}},
-       { 1,  2, USE_RIGHT,     {0x01,  0x04,   0x09, 0x0c}},
-       { 2,  2, USE_RIGHT,     {0x02,  0x05,   0x0a, 0x0d}},
 
-       { 3,  2, USE_RIGHT,     {0x08,  0x0b,   0x00, 0x00}},
-       { 4,  2, USE_RIGHT,     {0x09,  0x0c,   0x00, 0x00}},
-       { 5,  2, USE_RIGHT,     {0x0a,  0x0d,   0x00, 0x00}},
+int opl3_detect (int ioaddr, int *osp);
+int opl3_init(int ioaddr, int *osp);
 
-       { 6,  2, USE_RIGHT,     {0x10,  0x13,   0x00, 0x00}},
-       { 7,  2, USE_RIGHT,     {0x11,  0x14,   0x00, 0x00}},
-       { 8,  2, USE_RIGHT,     {0x12,  0x15,   0x00, 0x00}}
-};
+void enable_opl3_mode(int left, int right, int both);
diff --git a/drivers/sound/opl3_hw.h b/drivers/sound/opl3_hw.h
new file mode 100644 (file)
index 0000000..8b11c89
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ *     opl3_hw.h       - Definitions of the OPL-3 registers
+ *
+ *
+ * Copyright (C) by Hannu Savolainen 1993-1997
+ *
+ * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
+ * Version 2 (June 1991). See the "COPYING" file distributed with this software
+ * for more info.
+ *
+ *
+ *     The OPL-3 mode is switched on by writing 0x01, to the offset 5
+ *     of the right side.
+ *
+ *     Another special register at the right side is at offset 4. It contains
+ *     a bit mask defining which voices are used as 4 OP voices.
+ *
+ *     The percussive mode is implemented in the left side only.
+ *
+ *     With the above exceptions the both sides can be operated independently.
+ *     
+ *     A 4 OP voice can be created by setting the corresponding
+ *     bit at offset 4 of the right side.
+ *
+ *     For example setting the rightmost bit (0x01) changes the
+ *     first voice on the right side to the 4 OP mode. The fourth
+ *     voice is made inaccessible.
+ *
+ *     If a voice is set to the 2 OP mode, it works like 2 OP modes
+ *     of the original YM3812 (AdLib). In addition the voice can 
+ *     be connected the left, right or both stereo channels. It can
+ *     even be left unconnected. This works with 4 OP voices also.
+ *
+ *     The stereo connection bits are located in the FEEDBACK_CONNECTION
+ *     register of the voice (0xC0-0xC8). In 4 OP voices these bits are
+ *     in the second half of the voice.
+ */
+
+/*
+ *     Register numbers for the global registers
+ */
+
+#define TEST_REGISTER                          0x01
+#define   ENABLE_WAVE_SELECT           0x20
+
+#define TIMER1_REGISTER                                0x02
+#define TIMER2_REGISTER                                0x03
+#define TIMER_CONTROL_REGISTER                 0x04    /* Left side */
+#define   IRQ_RESET                    0x80
+#define   TIMER1_MASK                  0x40
+#define   TIMER2_MASK                  0x20
+#define   TIMER1_START                 0x01
+#define   TIMER2_START                 0x02
+
+#define CONNECTION_SELECT_REGISTER             0x04    /* Right side */
+#define   RIGHT_4OP_0                  0x01
+#define   RIGHT_4OP_1                  0x02
+#define   RIGHT_4OP_2                  0x04
+#define   LEFT_4OP_0                   0x08
+#define   LEFT_4OP_1                   0x10
+#define   LEFT_4OP_2                   0x20
+
+#define OPL3_MODE_REGISTER                     0x05    /* Right side */
+#define   OPL3_ENABLE                  0x01
+#define   OPL4_ENABLE                  0x02
+
+#define KBD_SPLIT_REGISTER                     0x08    /* Left side */
+#define   COMPOSITE_SINE_WAVE_MODE     0x80            /* Don't use with OPL-3? */
+#define   KEYBOARD_SPLIT               0x40
+
+#define PERCOSSION_REGISTER                    0xbd    /* Left side only */
+#define   TREMOLO_DEPTH                        0x80
+#define   VIBRATO_DEPTH                        0x40
+#define          PERCOSSION_ENABLE             0x20
+#define   BASSDRUM_ON                  0x10
+#define   SNAREDRUM_ON                 0x08
+#define   TOMTOM_ON                    0x04
+#define   CYMBAL_ON                    0x02
+#define   HIHAT_ON                     0x01
+
+/*
+ *     Offsets to the register banks for operators. To get the
+ *     register number just add the operator offset to the bank offset
+ *
+ *     AM/VIB/EG/KSR/Multiple (0x20 to 0x35)
+ */
+#define AM_VIB                                 0x20
+#define   TREMOLO_ON                   0x80
+#define   VIBRATO_ON                   0x40
+#define   SUSTAIN_ON                   0x20
+#define   KSR                          0x10    /* Key scaling rate */
+#define   MULTIPLE_MASK                0x0f    /* Frequency multiplier */
+
+ /*
+  *    KSL/Total level (0x40 to 0x55)
+  */
+#define KSL_LEVEL                              0x40
+#define   KSL_MASK                     0xc0    /* Envelope scaling bits */
+#define   TOTAL_LEVEL_MASK             0x3f    /* Strength (volume) of OP */
+
+/*
+ *     Attack / Decay rate (0x60 to 0x75)
+ */
+#define ATTACK_DECAY                           0x60
+#define   ATTACK_MASK                  0xf0
+#define   DECAY_MASK                   0x0f
+
+/*
+ * Sustain level / Release rate (0x80 to 0x95)
+ */
+#define SUSTAIN_RELEASE                                0x80
+#define   SUSTAIN_MASK                 0xf0
+#define   RELEASE_MASK                 0x0f
+
+/*
+ * Wave select (0xE0 to 0xF5)
+ */
+#define WAVE_SELECT                    0xe0
+
+/*
+ *     Offsets to the register banks for voices. Just add to the
+ *     voice number to get the register number.
+ *
+ *     F-Number low bits (0xA0 to 0xA8).
+ */
+#define FNUM_LOW                               0xa0
+
+/*
+ *     F-number high bits / Key on / Block (octave) (0xB0 to 0xB8)
+ */
+#define KEYON_BLOCK                                    0xb0
+#define          KEYON_BIT                             0x20
+#define          BLOCKNUM_MASK                         0x1c
+#define   FNUM_HIGH_MASK                       0x03
+
+/*
+ *     Feedback / Connection (0xc0 to 0xc8)
+ *
+ *     These registers have two new bits when the OPL-3 mode
+ *     is selected. These bits controls connecting the voice
+ *     to the stereo channels. For 4 OP voices this bit is
+ *     defined in the second half of the voice (add 3 to the
+ *     register offset).
+ *
+ *     For 4 OP voices the connection bit is used in the
+ *     both halves (gives 4 ways to connect the operators).
+ */
+#define FEEDBACK_CONNECTION                            0xc0
+#define   FEEDBACK_MASK                                0x0e    /* Valid just for 1st OP of a voice */
+#define   CONNECTION_BIT                       0x01
+/*
+ *     In the 4 OP mode there is four possible configurations how the
+ *     operators can be connected together (in 2 OP modes there is just
+ *     AM or FM). The 4 OP connection mode is defined by the rightmost
+ *     bit of the FEEDBACK_CONNECTION (0xC0-0xC8) on the both halves.
+ *
+ *     First half      Second half     Mode
+ *
+ *                                      +---+
+ *                                      v   |
+ *     0               0               >+-1-+--2--3--4-->
+ *
+ *
+ *                                     
+ *                                      +---+
+ *                                      |   |
+ *     0               1               >+-1-+--2-+
+ *                                               |->
+ *                                     >--3----4-+
+ *                                     
+ *                                      +---+
+ *                                      |   |
+ *     1               0               >+-1-+-----+
+ *                                                |->
+ *                                     >--2--3--4-+
+ *
+ *                                      +---+
+ *                                      |   |
+ *     1               1               >+-1-+--+
+ *                                             |
+ *                                     >--2--3-+->
+ *                                             |
+ *                                     >--4----+
+ */
+#define   STEREO_BITS                          0x30    /* OPL-3 only */
+#define     VOICE_TO_LEFT              0x10
+#define     VOICE_TO_RIGHT             0x20
+
+/*
+ *     Definition table for the physical voices
+ */
+
+struct physical_voice_info {
+               unsigned char voice_num;
+               unsigned char voice_mode; /* 0=unavailable, 2=2 OP, 4=4 OP */
+               unsigned short ioaddr; /* I/O port (left or right side) */
+               unsigned char op[4]; /* Operator offsets */
+       };
+
+/*
+ *     There is 18 possible 2 OP voices
+ *     (9 in the left and 9 in the right).
+ *     The first OP is the modulator and 2nd is the carrier.
+ *
+ *     The first three voices in the both sides may be connected
+ *     with another voice to a 4 OP voice. For example voice 0
+ *     can be connected with voice 3. The operators of voice 3 are
+ *     used as operators 3 and 4 of the new 4 OP voice.
+ *     In this case the 2 OP voice number 0 is the 'first half' and
+ *     voice 3 is the second.
+ */
+
+#define USE_LEFT       0
+#define USE_RIGHT      1
+
+static struct physical_voice_info pv_map[18] =
+{
+/*       No Mode Side          OP1     OP2     OP3   OP4       */
+/*     ---------------------------------------------------     */
+       { 0,  2, USE_LEFT,      {0x00,  0x03,   0x08, 0x0b}},
+       { 1,  2, USE_LEFT,      {0x01,  0x04,   0x09, 0x0c}},
+       { 2,  2, USE_LEFT,      {0x02,  0x05,   0x0a, 0x0d}},
+
+       { 3,  2, USE_LEFT,      {0x08,  0x0b,   0x00, 0x00}},
+       { 4,  2, USE_LEFT,      {0x09,  0x0c,   0x00, 0x00}},
+       { 5,  2, USE_LEFT,      {0x0a,  0x0d,   0x00, 0x00}},
+
+       { 6,  2, USE_LEFT,      {0x10,  0x13,   0x00, 0x00}}, /* Used by percussive voices */
+       { 7,  2, USE_LEFT,      {0x11,  0x14,   0x00, 0x00}}, /* if the percussive mode */
+       { 8,  2, USE_LEFT,      {0x12,  0x15,   0x00, 0x00}}, /* is selected */
+
+       { 0,  2, USE_RIGHT,     {0x00,  0x03,   0x08, 0x0b}},
+       { 1,  2, USE_RIGHT,     {0x01,  0x04,   0x09, 0x0c}},
+       { 2,  2, USE_RIGHT,     {0x02,  0x05,   0x0a, 0x0d}},
+
+       { 3,  2, USE_RIGHT,     {0x08,  0x0b,   0x00, 0x00}},
+       { 4,  2, USE_RIGHT,     {0x09,  0x0c,   0x00, 0x00}},
+       { 5,  2, USE_RIGHT,     {0x0a,  0x0d,   0x00, 0x00}},
+
+       { 6,  2, USE_RIGHT,     {0x10,  0x13,   0x00, 0x00}},
+       { 7,  2, USE_RIGHT,     {0x11,  0x14,   0x00, 0x00}},
+       { 8,  2, USE_RIGHT,     {0x12,  0x15,   0x00, 0x00}}
+};
+/*
+ *     DMA buffer calls
+ */
index 721157fdd444a6bb8e9dd0f3bc4cc5114aceb3bb..6b82d2a171894f347c8c91dade5689f329b17658 100644 (file)
  *
  * Changes:
  *     Alan Cox                Modularisation
+ *     Christoph Hellwig       Adapted to module_init/module_exit
  *
  * FIXME:
  *     Check for install of mpu etc is wrong, should check result of the mss stuff
  */
+
+#include <linux/init.h>
 #include <linux/module.h>
 
 #undef  SB_OK
 
 #include "sound_config.h"
 #include "soundmodule.h"
+
+#include "ad1848.h"
+#include "mpu401.h"
+
 #ifdef SB_OK
 #include "sb.h"
 static int sb_initialized = 0;
-
 #endif
 
 static int kilroy_was_here = 0;        /* Don't detect twice */
@@ -62,7 +67,7 @@ static void opl3sa_write(int addr, int data)
        restore_flags(flags);
 }
 
-static int opl3sa_detect(void)
+static int __init opl3sa_detect(void)
 {
        int tmp;
 
@@ -102,7 +107,7 @@ static int opl3sa_detect(void)
  *     OPL3-SA
  */
 
-int probe_opl3sa_wss(struct address_info *hw_config)
+static int __init probe_opl3sa_wss(struct address_info *hw_config)
 {
        int ret;
        unsigned char tmp = 0x24;       /* WSS enable */
@@ -157,7 +162,7 @@ int probe_opl3sa_wss(struct address_info *hw_config)
        return ret;
 }
 
-void attach_opl3sa_wss(struct address_info *hw_config)
+static void __init attach_opl3sa_wss(struct address_info *hw_config)
 {
        int nm = num_mixers;
 
@@ -172,13 +177,13 @@ void attach_opl3sa_wss(struct address_info *hw_config)
 }
 
 
-void attach_opl3sa_mpu(struct address_info *hw_config)
+static void __init attach_opl3sa_mpu(struct address_info *hw_config)
 {
        hw_config->name = "OPL3-SA (MPU401)";
        attach_uart401(hw_config);
 }
 
-int probe_opl3sa_mpu(struct address_info *hw_config)
+static int __init probe_opl3sa_mpu(struct address_info *hw_config)
 {
        unsigned char conf;
        static signed char irq_bits[] = {
@@ -236,7 +241,7 @@ int probe_opl3sa_mpu(struct address_info *hw_config)
        return probe_uart401(hw_config);
 }
 
-void unload_opl3sa_wss(struct address_info *hw_config)
+static void __exit unload_opl3sa_wss(struct address_info *hw_config)
 {
        int dma2 = hw_config->dma2;
 
@@ -254,26 +259,29 @@ void unload_opl3sa_wss(struct address_info *hw_config)
        sound_unload_audiodev(hw_config->slots[0]);
 }
 
-void unload_opl3sa_mpu(struct address_info *hw_config)
+static inline void __exit unload_opl3sa_mpu(struct address_info *hw_config)
 {
        unload_uart401(hw_config);
 }
 
 #ifdef SB_OK
-void unload_opl3sa_sb(struct address_info *hw_config)
+static inline void __exit unload_opl3sa_sb(struct address_info *hw_config)
 {
        sb_dsp_unload(hw_config);
 }
 #endif
 
-#ifdef MODULE
-int             io = -1;
-int             irq = -1;
-int             dma = -1;
-int             dma2 = -1;
+static int found_mpu;
+
+static struct address_info cfg;
+static struct address_info cfg_mpu;
 
-int            mpu_io = -1;
-int            mpu_irq = -1;
+static int __initdata io       = -1;
+static int __initdata irq      = -1;
+static int __initdata dma      = -1;
+static int __initdata dma2     = -1;
+static int __initdata mpu_io   = -1;
+static int __initdata mpu_irq  = -1;
 
 MODULE_PARM(io,"i");
 MODULE_PARM(irq,"i");
@@ -282,43 +290,61 @@ MODULE_PARM(dma2,"i");
 MODULE_PARM(mpu_io,"i");
 MODULE_PARM(mpu_irq,"i");
 
-struct address_info cfg;
-struct address_info mpu_cfg;
-static int found_mpu;
-
-int init_module(void)
+static int __init init_opl3sa(void)
 {
-       if (io == -1 || irq == -1 || dma == -1)
-       {
+       if (io == -1 || irq == -1 || dma == -1) {
                printk(KERN_ERR "opl3sa: dma, irq and io must be set.\n");
                return -EINVAL;
        }
+
        cfg.io_base = io;
        cfg.irq = irq;
        cfg.dma = dma;
        cfg.dma2 = dma2;
        
-       mpu_cfg.io_base = mpu_io;
-       mpu_cfg.irq = mpu_irq;
+       cfg_mpu.io_base = mpu_io;
+       cfg_mpu.irq = mpu_irq;
 
        if (probe_opl3sa_wss(&cfg) == 0)
                return -ENODEV;
 
-       found_mpu=probe_opl3sa_mpu(&mpu_cfg);
+       found_mpu=probe_opl3sa_mpu(&cfg_mpu);
 
        attach_opl3sa_wss(&cfg);
        if(found_mpu)
-               attach_opl3sa_mpu(&mpu_cfg);
+               attach_opl3sa_mpu(&cfg_mpu);
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_opl3sa(void)
 {
        if(found_mpu)
-               unload_opl3sa_mpu(&mpu_cfg);
+               unload_opl3sa_mpu(&cfg_mpu);
        unload_opl3sa_wss(&cfg);
        SOUND_LOCK_END;
 }
 
-#endif /* MODULE */
+module_init(init_opl3sa);
+module_exit(cleanup_opl3sa);
+
+#ifndef MODULE
+static int __init setup_opl3sa(char *str)
+{
+       /* io, irq, dma, dma2, mpu_io, mpu_irq */
+       int ints[7];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io      = ints[1];
+       irq     = ints[2];
+       dma     = ints[3];
+       dma2    = ints[4];
+       mpu_io  = ints[5];
+       mpu_irq = ints[6];
+
+       return 1;
+}
+
+__setup("opl3sa=", setup_opl3sa);
+#endif
index c3fff526f836d441410fd3bea58f65d8573adbcf..23f85733e2da97acb95eb60dfaf29bcf2e459db5 100644 (file)
  * Scott Murray            Simpler detection code should work all the time now
  *                         (with thanks to Ben Hutchings for the heuristic),
  *                         removed now unnecessary force option. (Jan 5, 1999)
+ * Christoph Hellwig      Adapted to module_init/module_exit (Mar 4, 2000)
  *
  */
 
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/module.h>
 
 #include "sound_config.h"
 #include "soundmodule.h"
 
+#include "ad1848.h"
+#include "mpu401.h"
+
 /* Useful control port indexes: */
 #define OPL3SA2_MASTER_LEFT  0x07
 #define OPL3SA2_MASTER_RIGHT 0x08
@@ -439,31 +444,31 @@ static struct mixer_operations opl3sa2_mixer_operations =
 /* End of mixer-related stuff */
 
 
-int probe_opl3sa2_mpu(struct address_info *hw_config)
+static inline int __init probe_opl3sa2_mpu(struct address_info *hw_config)
 {
        return probe_mpu401(hw_config);
 }
 
 
-void attach_opl3sa2_mpu(struct address_info *hw_config)
+static inline void __init attach_opl3sa2_mpu(struct address_info *hw_config)
 {
        attach_mpu401(hw_config);
 }
 
 
-void unload_opl3sa2_mpu(struct address_info *hw_config)
+static inline void __exit unload_opl3sa2_mpu(struct address_info *hw_config)
 {
        unload_mpu401(hw_config);
 }
 
 
-int probe_opl3sa2_mss(struct address_info *hw_config)
+static inline int __init probe_opl3sa2_mss(struct address_info *hw_config)
 {
        return probe_ms_sound(hw_config);
 }
 
 
-void attach_opl3sa2_mss(struct address_info *hw_config)
+static void __init attach_opl3sa2_mss(struct address_info *hw_config)
 {
        char mixer_name[64];
 
@@ -506,13 +511,13 @@ void attach_opl3sa2_mss(struct address_info *hw_config)
 }
 
 
-void unload_opl3sa2_mss(struct address_info *hw_config)
+static inline void __exit unload_opl3sa2_mss(struct address_info *hw_config)
 {
        unload_ms_sound(hw_config);
 }
 
 
-int probe_opl3sa2(struct address_info *hw_config)
+static int __init probe_opl3sa2(struct address_info *hw_config)
 {
        unsigned char version = 0;
        char tag;
@@ -582,16 +587,13 @@ int probe_opl3sa2(struct address_info *hw_config)
        {
                /* Generate a pretty name */
                sprintf(chipset_name, "OPL3-SA%c", tag);
-#if defined(CONFIG_OPL3SA2_MPU_BASE) && !defined(MODULE)
-               sound_getconf(SNDCARD_OPL3SA2_MPU)->always_detect = 1;
-#endif
                return 1;
        }
        return 0;
 }
 
 
-void attach_opl3sa2(struct address_info *hw_config)
+static void __init attach_opl3sa2(struct address_info *hw_config)
 {
        request_region(hw_config->io_base, 2, chipset_name);
 
@@ -599,7 +601,7 @@ void attach_opl3sa2(struct address_info *hw_config)
 }
 
 
-void unload_opl3sa2(struct address_info *hw_config)
+static void __exit unload_opl3sa2(struct address_info *hw_config)
 {
         /* Release control ports */
        release_region(hw_config->io_base, 2);
@@ -609,15 +611,16 @@ void unload_opl3sa2(struct address_info *hw_config)
                sound_unload_mixerdev(opl3sa2_mixer);
 }
 
+static struct address_info cfg;
+static struct address_info cfg2;
+static struct address_info cfg_mpu;
 
-#ifdef MODULE
-
-int io      = -1;
-int mss_io  = -1;
-int mpu_io  = -1;
-int irq     = -1;
-int dma     = -1;
-int dma2    = -1;
+static int __initdata io       = -1;
+static int __initdata mss_io   = -1;
+static int __initdata mpu_io   = -1;
+static int __initdata irq      = -1;
+static int __initdata dma      = -1;
+static int __initdata dma2     = -1;
 
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "Set i/o base of OPL3-SA2 or SA3 card (usually 0x370)");
@@ -640,30 +643,15 @@ MODULE_PARM_DESC(dma2, "Set MSS (audio) second DMA channel (0, 1, 3)");
 MODULE_DESCRIPTION("Module for OPL3-SA2 and SA3 sound cards (uses AD1848 MSS driver).");
 MODULE_AUTHOR("Scott Murray <scottm@interlog.com>");
 
-EXPORT_NO_SYMBOLS;
-
-struct address_info cfg;
-struct address_info mss_cfg;
-struct address_info mpu_cfg;
-
-
 /*
  * Install a OPL3SA2 based card.
  *
  * Need to have ad1848 and mpu401 loaded ready.
  */
-int init_module(void)
+static int __init init_opl3sa2(void)
 {
         int i;
 
-       if(io == -1 || irq == -1 || dma == -1 || dma2 == -1 || mss_io == -1)
-       {
-               printk(KERN_ERR
-                      "%s: io, mss_io, irq, dma, and dma2 must be set.\n",
-                      __FILE__);
-               return -EINVAL;
-       }
-   
         /* Our own config: */
         cfg.io_base = io;
        cfg.irq     = irq;
@@ -671,16 +659,26 @@ int init_module(void)
        cfg.dma2    = dma2;
        
         /* The MSS config: */
-       mss_cfg.io_base      = mss_io;
-       mss_cfg.irq          = irq;
-       mss_cfg.dma          = dma;
-       mss_cfg.dma2         = dma2;
-       mss_cfg.card_subtype = 1;      /* No IRQ or DMA setup */
+       cfg2.io_base      = mss_io;
+       cfg2.irq          = irq;
+       cfg2.dma          = dma;
+       cfg2.dma2         = dma2;
+       cfg2.card_subtype = 1;      /* No IRQ or DMA setup */
+
+       cfg_mpu.io_base       = mpu_io;
+       cfg_mpu.irq           = irq;
+       cfg_mpu.dma           = dma;
+       cfg_mpu.always_detect = 1;  /* It's there, so use shared IRQs */
+
+       if(cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.dma2 == -1 || cfg2.io_base == -1) {
+               printk(KERN_ERR "opl3sa2: io, mss_io, irq, dma, and dma2 must be set.\n");
+               return -EINVAL;
+       }
 
        /* Call me paranoid: */
        for(i = 0; i < 6; i++)
        {
-               cfg.slots[i] = mss_cfg.slots[i] = mpu_cfg.slots[i] = -1;
+               cfg.slots[i] = cfg2.slots[i] = cfg_mpu.slots[i] = -1;
        }
 
        if(probe_opl3sa2(&cfg) == 0)
@@ -688,41 +686,54 @@ int init_module(void)
                return -ENODEV;
        }
 
-       if(probe_opl3sa2_mss(&mss_cfg) == 0)
+       if(probe_opl3sa2_mss(&cfg2) == 0)
        {
                return -ENODEV;
        }
 
        attach_opl3sa2(&cfg);
-       attach_opl3sa2_mss(&mss_cfg);
+       attach_opl3sa2_mss(&cfg2);
 
-       if(mpu_io != -1)
-       {
-            /* MPU config: */
-           mpu_cfg.io_base       = mpu_io;
-           mpu_cfg.irq           = irq;
-           mpu_cfg.dma           = dma;
-           mpu_cfg.always_detect = 1;  /* It's there, so use shared IRQs */
-
-           if(probe_opl3sa2_mpu(&mpu_cfg))
-           {
-                   attach_opl3sa2_mpu(&mpu_cfg);
-           }
+       if(cfg_mpu.io_base != -1) {
+               if(probe_opl3sa2_mpu(&cfg_mpu)) {
+                       attach_opl3sa2_mpu(&cfg_mpu);
+               }
        }
        SOUND_LOCK;
        return 0;
 }
 
 
-void cleanup_module(void)
+static void __exit cleanup_opl3sa2(void)
 {
-        if(mpu_cfg.slots[1] != -1)
-       {
-               unload_opl3sa2_mpu(&mpu_cfg);
+        if(cfg_mpu.slots[1] != -1) {
+               unload_opl3sa2_mpu(&cfg_mpu);
        }
-       unload_opl3sa2_mss(&mss_cfg);
+       unload_opl3sa2_mss(&cfg2);
        unload_opl3sa2(&cfg);
        SOUND_LOCK_END;
 }
 
-#endif /* MODULE */
+module_init(init_opl3sa2);
+module_exit(cleanup_opl3sa2);
+
+#ifndef MODULE
+static int __init setup_opl3sa2(char *str)
+{
+       /* io, irq, dma, dma2 */
+       int ints[7];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io      = ints[1];
+       irq     = ints[2];
+       dma     = ints[3];
+       dma2    = ints[4];
+       mss_io  = ints[5];
+       mpu_io  = ints[6];
+
+       return 1;
+}
+
+__setup("opl3sa2=", setup_opl3sa2);
+#endif
diff --git a/drivers/sound/pas2.h b/drivers/sound/pas2.h
new file mode 100644 (file)
index 0000000..7ac521f
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * pas2.h
+ *
+ * Copyright:  Christoph Hellwig <chhellwig@gmx.net>
+ *
+ */
+
+/*     From pas_card.c */
+int pas_set_intr(int mask);
+int pas_remove_intr(int mask);
+unsigned char pas_read(int ioaddr);
+void pas_write(unsigned char data, int ioaddr);
+
+/*     From pas_audio.c */
+void pas_pcm_interrupt(unsigned char status, int cause);
+void pas_pcm_init(struct address_info *hw_config);
+
+/*     From pas_mixer.c */
+int pas_init_mixer(void);
+
+/*     From pas_midi.c */
+void pas_midi_init(void);
+void pas_midi_interrupt(void);
index 762871063f7d9f4c6da325928e8e09e408687bc2..68936e577f905dd0dcaa672f5ab3b03d3bec8ce7 100644 (file)
@@ -5,10 +5,14 @@
  */
 
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/module.h>
 #include "sound_config.h"
 #include "soundmodule.h"
 
+#include "pas2.h"
+#include "sb.h"
+
 static unsigned char dma_bits[] = {
        4, 1, 2, 3, 0, 5, 6, 7
 };
@@ -51,6 +55,8 @@ static int    broken_bus_clock = 1;
 static int     broken_bus_clock = 0;
 #endif
 
+static struct address_info cfg;
+static struct address_info cfg2;
 
 char            pas_model = 0;
 static char    *pas_model_names[] = {
@@ -81,7 +87,7 @@ void pas_write(unsigned char data, int ioaddr)
 
 /******************* Begin of the Interrupt Handler ********************/
 
-static void pasintr(int irq, void *dev_id, struct pt_regs *dummy)
+void pasintr(int irq, void *dev_id, struct pt_regs *dummy)
 {
        int             status;
 
@@ -126,9 +132,7 @@ int pas_remove_intr(int mask)
 
 /******************* Begin of the Initialization Code ******************/
 
-extern struct address_info sbhw_config;
-
-static int config_pas_hw(struct address_info *hw_config)
+static int __init config_pas_hw(struct address_info *hw_config)
 {
        char            ok = 1;
        unsigned        int_ptrs;       /* scsi/sound interrupt pointers */
@@ -238,12 +242,8 @@ static int config_pas_hw(struct address_info *hw_config)
        {
                struct address_info *sb_config;
 
-#ifndef MODULE
-               if ((sb_config = sound_getconf(SNDCARD_SB)))
-#else
-               sb_config = &sbhw_config;
+               sb_config = &cfg2;
                if (sb_config->io_base)
-#endif
                {
                        unsigned char   irq_dma;
 
@@ -286,7 +286,7 @@ static int config_pas_hw(struct address_info *hw_config)
        return ok;
 }
 
-static int detect_pas_hw(struct address_info *hw_config)
+static int __init detect_pas_hw(struct address_info *hw_config)
 {
        unsigned char   board_id, foo;
 
@@ -327,7 +327,7 @@ static int detect_pas_hw(struct address_info *hw_config)
        return pas_model;
 }
 
-void attach_pas_card(struct address_info *hw_config)
+static void __init attach_pas_card(struct address_info *hw_config)
 {
        pas_irq = hw_config->irq;
 
@@ -348,7 +348,6 @@ void attach_pas_card(struct address_info *hw_config)
                        pas_pcm_init(hw_config);
 
 #if !defined(MODULE) && !defined(DISABLE_SB_EMULATION)
-
                        sb_dsp_disable_midi(pas_sb_base);       /* No MIDI capability */
 #endif
 
@@ -358,12 +357,12 @@ void attach_pas_card(struct address_info *hw_config)
        }
 }
 
-int probe_pas(struct address_info *hw_config)
+static inline int __init probe_pas(struct address_info *hw_config)
 {
        return detect_pas_hw(hw_config);
 }
 
-void unload_pas(struct address_info *hw_config)
+static void __exit unload_pas(struct address_info *hw_config)
 {
        extern int pas_audiodev;
        extern int pas2_mididev;
@@ -381,17 +380,15 @@ void unload_pas(struct address_info *hw_config)
                sound_unload_audiodev(pas_audiodev);
 }
 
-#ifdef MODULE
-
-int             io = -1;
-int             irq = -1;
-int             dma = -1;
-int             dma16 = -1;    /* Set this for modules that need it */
+static int __initdata io       = -1;
+static int __initdata irq      = -1;
+static int __initdata dma      = -1;
+static int __initdata dma16    = -1;   /* Set this for modules that need it */
 
-int             sb_io = 0;
-int             sb_irq = -1;
-int             sb_dma = -1;
-int             sb_dma16 = -1;
+static int __initdata sb_io    = 0;
+static int __initdata sb_irq   = -1;
+static int __initdata sb_dma   = -1;
+static int __initdata sb_dma16 = -1;
 
 MODULE_PARM(io,"i");
 MODULE_PARM(irq,"i");
@@ -407,40 +404,61 @@ MODULE_PARM(joystick,"i");
 MODULE_PARM(symphony,"i");
 MODULE_PARM(broken_bus_clock,"i");
 
-struct address_info config;
-struct address_info sbhw_config;
-
-int init_module(void)
+static int __init init_pas2(void)
 {
        printk(KERN_INFO "Pro Audio Spectrum driver Copyright (C) by Hannu Savolainen 1993-1996\n");
 
-       if (io == -1 || dma == -1 || irq == -1)
-       {
-                 printk(KERN_INFO "I/O, IRQ, DMA and type are mandatory\n");
-                 return -EINVAL;
-       }
-       config.io_base = io;
-       config.irq = irq;
-       config.dma = dma;
-       config.dma2 = dma16;
+       cfg.io_base = io;
+       cfg.irq = irq;
+       cfg.dma = dma;
+       cfg.dma2 = dma16;
+
+       cfg2.io_base = sb_io;
+       cfg2.irq = sb_irq;
+       cfg2.dma = sb_dma;
+       cfg2.dma2 = sb_dma16;
 
-       sbhw_config.io_base = sb_io;
-       sbhw_config.irq = sb_irq;
-       sbhw_config.dma = sb_dma;
-       sbhw_config.dma2 = sb_dma16;
+       if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
+               printk(KERN_INFO "I/O, IRQ, DMA and type are mandatory\n");
+               return -EINVAL;
+       }
 
-       if (!probe_pas(&config))
+       if (!probe_pas(&cfg))
                return -ENODEV;
-       attach_pas_card(&config);
+       attach_pas_card(&cfg);
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_pas2(void)
 {
-       unload_pas(&config);
+       unload_pas(&cfg);
        SOUND_LOCK_END;
 }
 
+module_init(init_pas2);
+module_exit(cleanup_pas2);
+
+#ifndef MODULE
+static int __init setup_pas2(char *str)
+{
+       /* io, irq, dma, dma2, sb_io, sb_irq, sb_dma, sb_dma2 */
+       int ints[9];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+
+       io      = ints[1];
+       irq     = ints[2];
+       dma     = ints[3];
+       dma16   = ints[4];
+
+       sb_io   = ints[5];
+       sb_irq  = ints[6];
+       sb_dma  = ints[7];
+       sb_dma16 = ints[8];
+
+       return 1;
+}
 
-#endif /* MODULE */
+__setup("pas2=", setup_pas2);
+#endif
index 83d6ff5bd298197abf20be63354dc82efb64a0de..385bdd1db3e7192daa20de68c9d57f7757d869f4 100644 (file)
  * Version 2 (June 1991). See the "COPYING" file distributed with this software
  * for more info.
  */
+
 #include "sound_config.h"
 
+#include "pas2.h"
+
 static int      midi_busy = 0, input_opened = 0;
 static int      my_dev;
 
index 1f2f1233629baf408ac99dc7f3e5456c1aabc537..86e9a50cad89dd13faf87d35fda8091d41fd7ff8 100644 (file)
@@ -17,6 +17,8 @@
  */
 #include "sound_config.h"
 
+#include "pas2.h"
+
 #ifndef DEB
 #define DEB(what)              /* (what) */
 #endif
index 36fc7f72b295975acbbfcf0caa42639ac162af15..5a79ebb8655ffbb4ccdcefd44002243f23ad7d7d 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "sound_config.h"
 
+#include "pas2.h"
+
 #ifndef DEB
 #define DEB(WHAT)
 #endif
index ffbb08b773cfcbf1be58314b228118f9422f51f9..7e883a625aec667fb79683b19ab594ad7137b900 100644 (file)
  *          To probe_pss_mss added test for initialize AD1848
  * 98-05-28: Vladimir Michl <vladimir.michl@upol.cz>
  *          Fixed computation of mixer volumes
+ * 00-03-03: Christoph Hellwig <chhellwig@gmx.net>
+ *          Adapted to module_init/module_exit
  */
 
 
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/module.h>
 
 #include "sound_config.h"
 #include "sound_firmware.h"
 #include "soundmodule.h"
 
+#include "ad1848.h"
+#include "mpu401.h"
+
 /*
  * PSS registers.
  */
@@ -910,14 +916,14 @@ static coproc_operations pss_coproc_operations =
        &pss_data
 };
 
-void attach_pss_mpu(struct address_info *hw_config)
+static void __init attach_pss_mpu(struct address_info *hw_config)
 {
        attach_mpu401(hw_config);       /* Slot 1 */
        if (hw_config->slots[1] != -1)  /* The MPU driver installed itself */
                midi_devs[hw_config->slots[1]]->coproc = &pss_coproc_operations;
 }
 
-int probe_pss_mss(struct address_info *hw_config)
+static int __init probe_pss_mss(struct address_info *hw_config)
 {
        volatile int timeout;
 
@@ -950,16 +956,20 @@ int probe_pss_mss(struct address_info *hw_config)
         * downloaded to the ADSP2115 spends some time initializing the card.
         * Let's try to wait until it finishes this task.
         */
-       for (timeout = 0; timeout < 100000 && (inb(hw_config->io_base + WSS_INDEX) & WSS_INITIALIZING); timeout++);
+       for (timeout = 0; timeout < 100000 && (inb(hw_config->io_base + WSS_INDEX) &
+         WSS_INITIALIZING); timeout++)
+               ;
 
        outb((0x0b), hw_config->io_base + WSS_INDEX);   /* Required by some cards */
 
-       for (timeout = 0; (inb(hw_config->io_base + WSS_DATA) & WSS_AUTOCALIBRATION) && (timeout < 100000); timeout++);
+       for (timeout = 0; (inb(hw_config->io_base + WSS_DATA) & WSS_AUTOCALIBRATION) &&
+         (timeout < 100000); timeout++)
+               ;
 
        return probe_ms_sound(hw_config);
 }
 
-void attach_pss_mss(struct address_info *hw_config)
+static void __init attach_pss_mss(struct address_info *hw_config)
 {
        int        my_mix = -999;       /* gcc shut up */
        
@@ -991,36 +1001,33 @@ void attach_pss_mss(struct address_info *hw_config)
        }
 }
 
-void unload_pss(struct address_info *hw_config)
+static inline void __exit unload_pss(struct address_info *hw_config)
 {
        release_region(hw_config->io_base, 0x10);
        release_region(hw_config->io_base+0x10, 0x9);
 }
 
-void unload_pss_mpu(struct address_info *hw_config)
+static inline void __exit unload_pss_mpu(struct address_info *hw_config)
 {
        unload_mpu401(hw_config);
 }
 
-void unload_pss_mss(struct address_info *hw_config)
+static inline void __exit unload_pss_mss(struct address_info *hw_config)
 {
        unload_ms_sound(hw_config);
 }
 
-#ifdef MODULE
-
-int pss_io = -1;
-
-int mss_io = -1;
-int mss_irq = -1;
-int mss_dma = -1;
 
-int mpu_io = -1;
-int mpu_irq = -1;
+static struct address_info cfg;
+static struct address_info cfg2;
+static struct address_info cfg_mpu;
 
-struct address_info cfgpss = { 0 /* pss_io */, 0, -1, -1 };
-struct address_info cfgmpu = { 0 /* mpu_io */, 0 /* mpu_irq */, 0, -1 };
-struct address_info cfgmss = { 0 /* mss_io */, 0 /* mss_irq */, 0 /* mss_dma */, -1 };
+static int pss_io __initdata   = -1;
+static int mss_io __initdata   = -1;
+static int mss_irq __initdata  = -1;
+static int mss_dma __initdata  = -1;
+static int mpu_io __initdata   = -1;
+static int mpu_irq __initdata  = -1;
 
 MODULE_PARM(pss_io, "i");
 MODULE_PARM_DESC(pss_io, "Set i/o base of PSS card (probably 0x220 or 0x240)");
@@ -1046,54 +1053,76 @@ static int pssmpu = 0, pssmss = 0;
  *    Load a PSS sound card module
  */
 
-int init_module(void)
+static int __init init_pss(void)
 {
-       if (pss_io == -1 || mss_io == -1 || mss_irq == -1 || mss_dma == -1) {
-               printk(KERN_INFO "pss: mss_io, mss_dma, mss_irq and pss_io must be set.\n");
-               return -EINVAL;
-       }
+       cfg.io_base = pss_io;
 
-       cfgpss.io_base = pss_io;
+       cfg2.io_base = mss_io;
+       cfg2.irq = mss_irq;
+       cfg2.dma = mss_dma;
 
-       cfgmss.io_base = mss_io;
-       cfgmss.irq = mss_irq;
-       cfgmss.dma = mss_dma;
+       cfg_mpu.io_base = mpu_io;
+       cfg_mpu.irq = mpu_irq;
 
-       cfgmpu.io_base = mpu_io;
-       cfgmpu.irq = mpu_irq;
+       if (cfg.io_base == -1 || cfg2.io_base == -1 || cfg2.irq == -1 || cfg.dma == -1) {
+               printk(KERN_INFO "pss: mss_io, mss_dma, mss_irq and pss_io must be set.\n");
+               return -EINVAL;
+       }
 
-       if (!pss_synth) 
-       {
+       if (!pss_synth) {
                fw_load = 1;
                pss_synthLen = mod_firmware_load("/etc/sound/pss_synth", (void *) &pss_synth);
        }
-       if (!probe_pss(&cfgpss))
+       if (!probe_pss(&cfg))
                return -ENODEV;
-       attach_pss(&cfgpss);
+       attach_pss(&cfg);
        /*
         *    Attach stuff
         */
-       if (probe_pss_mpu(&cfgmpu)) {
+       if (probe_pss_mpu(&cfg_mpu)) {
                pssmpu = 1;
-               attach_pss_mpu(&cfgmpu);
+               attach_pss_mpu(&cfg_mpu);
        }
-       if (probe_pss_mss(&cfgmss)) {
+       if (probe_pss_mss(&cfg2)) {
                pssmss = 1;
-               attach_pss_mss(&cfgmss);
+               attach_pss_mss(&cfg2);
        }
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_pss(void)
 {
        if (fw_load && pss_synth)
                vfree(pss_synth);
        if (pssmss)
-               unload_pss_mss(&cfgmss);
+               unload_pss_mss(&cfg2);
        if (pssmpu)
-               unload_pss_mpu(&cfgmpu);
-       unload_pss(&cfgpss);
+               unload_pss_mpu(&cfg_mpu);
+       unload_pss(&cfg);
        SOUND_LOCK_END;
 }
-#endif /* MODULE */
+
+module_init(init_pss);
+module_exit(cleanup_pss);
+
+#ifndef MODULE
+static int __init setup_pss(char *str)
+{
+       /* io, mss_io, mss_irq, mss_dma, mpu_io, mpu_irq */
+       int ints[7];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+
+       pss_io  = ints[1];
+       mss_io  = ints[2];
+       mss_irq = ints[3];
+       mss_dma = ints[4];
+       mpu_io  = ints[5];
+       mpu_irq = ints[6];
+
+       return 1;
+}
+
+__setup("pss=", setup_pss);
+#endif
index b2eef825476112371d8502a9d8e7118106255403..282e644a36bd0d5ccc363948ecf37903cd7bc19e 100644 (file)
@@ -164,3 +164,13 @@ void sb_audio_close(int dev);
 
 extern int acer;
 extern sb_devc *last_sb;
+
+/*     From sb_common.c */
+void sb_dsp_disable_midi(int port);
+void sb_dsp_disable_recording(int port);
+void attach_sbmpu (struct address_info *hw_config);
+int probe_sbmpu (struct address_info *hw_config);
+void unload_sbmpu (struct address_info *hw_config);
+
+void unload_sb16(struct address_info *hw_info);
+void unload_sb16midi(struct address_info *hw_info);
index cf43655e2bcf067c507ef9150692476f5688851f..7e3ecb1a103817d95f2cdab27959ed7c328d44bf 100644 (file)
  * for more info.
  *
  *
- * 26th November 1999 - patched to compile without ISA PnP support in the
- * kernel. -Daniel Stone (tamriel@ductape.net) 
+ * 26-11-1999 Patched to compile without ISA PnP support in the
+ * kernel - Daniel Stone (tamriel@ductape.net) 
  *
  * 06-01-2000 Refined and bugfixed ISA PnP support, added
  *  CMI 8330 support - Alessandro Zummo <azummo@ita.flashnet.it>
  *
+ * 18-01-2000 Separated sb_card and sb_common
+ *  Jeff Garzik <jgarzik@mandrakesoft.com>
+ *
  * 04-02-2000 Added Soundblaster AWE 64 PnP support, isapnpjump
  *  Alessandro Zummo <azummo@ita.flashnet.it>
  *
  * 11-02-2000 Added Soundblaster AWE 32 PnP support, refined PnP code
  *  Alessandro Zummo <azummo@ita.flashnet.it>
  *
- * 13-02-2000 Hopefully fixed awe/sb16 related bugs, code cleanup.
+ * 13-02-2000 Hopefully fixed awe/sb16 related bugs, code cleanup
  *  Alessandro Zummo <azummo@ita.flashnet.it>
  *
  */
 
 static int sbmpu = 0;
 
-void attach_sb_card(struct address_info *hw_config)
+extern void *smw_free;
+
+static void __init attach_sb_card(struct address_info *hw_config)
 {
        if(!sb_dsp_init(hw_config))
                hw_config->slots[0] = -1;
+       SOUND_LOCK;
 }
 
-int probe_sb(struct address_info *hw_config)
+static int __init probe_sb(struct address_info *hw_config)
 {
+       if (hw_config->io_base == -1 || hw_config->dma == -1 || hw_config->irq == -1)
+       {
+               printk(KERN_ERR "sb_card: I/O, IRQ, and DMA are mandatory\n");
+               return -EINVAL;
+       }
+
 #ifdef CONFIG_MCA
        /* MCA code added by ZP Gu (zpg@castle.net) */
        if (MCA_bus) {               /* no multiple REPLY card probing */
@@ -121,19 +133,16 @@ iobase=0x%x irq=%d lo_dma=%d hi_dma=%d\n",
        return sb_dsp_detect(hw_config, 0, 0);
 }
 
-void unload_sb(struct address_info *hw_config)
+static void __exit unload_sb(struct address_info *hw_config)
 {
        if(hw_config->slots[0]!=-1)
                sb_dsp_unload(hw_config, sbmpu);
 }
 
-int sb_be_quiet=0;
 extern int esstype;    /* ESS chip type */
 
-#ifdef MODULE
-
-static struct address_info config;
-static struct address_info config_mpu;
+static struct address_info cfg;
+static struct address_info cfg_mpu;
 
 struct pci_dev         *sb_dev         = NULL, 
                *wss_dev        = NULL, 
@@ -146,25 +155,21 @@ struct pci_dev    *sb_dev         = NULL,
  *    to the 8bit channel.
  */
 
-int mpu_io     = 0;
-int io                 = -1;
-int irq        = -1;
-int dma        = -1;
-int dma16      = -1;   /* Set this for modules that need it */
-int type       = 0;    /* Can set this to a specific card type */
-int mad16      = 0;    /* Set mad16=1 to load this as support for mad16 */
-int trix       = 0;    /* Set trix=1 to load this as support for trix */
-int pas2       = 0;    /* Set pas2=1 to load this as support for pas2 */
-int support    = 0;    /* Set support to load this as a support module */
-int sm_games   = 0;    /* Mixer - see sb_mixer.c */
-int acer       = 0;    /* Do acer notebook init */
+static int __initdata mpu_io   = 0;
+static int __initdata io       = -1;
+static int __initdata irq      = -1;
+static int __initdata dma      = -1;
+static int __initdata dma16    = -1;   /* Set this for modules that need it */
+static int __initdata type     = 0;    /* Can set this to a specific card type */
+
 
 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
-int isapnp      = 1;
-int isapnpjump  = 0;
-int nosbwave    = 0;   /* This option will be removed when the new awe_wave driver will be in the kernel tree */
+static int isapnp      = 1;
+static int isapnpjump  = 0;
+static int nosbwave    = 0;    /* This option will be removed when the new awe_wave driver will be
+                                  in the kernel tree */
 #else
-int isapnp     = 0;
+int isapnp     = 0;
 #endif
 
 MODULE_DESCRIPTION("Soundblaster driver");
@@ -175,10 +180,6 @@ MODULE_PARM(dma,   "i");
 MODULE_PARM(dma16,     "i");
 MODULE_PARM(mpu_io,    "i");
 MODULE_PARM(type,      "i");
-MODULE_PARM(mad16,     "i");
-MODULE_PARM(support,   "i");
-MODULE_PARM(trix,      "i");
-MODULE_PARM(pas2,      "i");
 MODULE_PARM(sm_games,  "i");
 MODULE_PARM(esstype,   "i");
 MODULE_PARM(acer,      "i");
@@ -198,16 +199,10 @@ MODULE_PARM_DESC(dma,             "8-bit DMA channel (0,1,3)");
 MODULE_PARM_DESC(dma16,                "16-bit DMA channel (5,6,7)");
 MODULE_PARM_DESC(mpu_io,       "Mpu base address");
 MODULE_PARM_DESC(type,         "You can set this to specific card type");
-MODULE_PARM_DESC(mad16,                "Enable MAD16 support");
-MODULE_PARM_DESC(trix,         "Enable Audiotrix support");
-MODULE_PARM_DESC(pas2,         "Enable Pas2 support");
-MODULE_PARM_DESC(support,      "Set this to load as generic support module");
 MODULE_PARM_DESC(sm_games,     "Enable support for Logitech soundman games");
 MODULE_PARM_DESC(esstype,      "ESS chip type");
 MODULE_PARM_DESC(acer,         "Set this to detect cards in some ACER notebooks");
 
-void *smw_free = NULL;
-
 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
 
 /* That's useful. */
@@ -631,7 +626,7 @@ static int __init sb_init_isapnp(struct address_info *hw_config, struct address_
    Should this be fixed? - azummo
 */
 
-static int __init sb_probe_isapnp(struct address_info *hw_config, struct address_info *mpu_config) 
+int __init sb_probe_isapnp(struct address_info *hw_config, struct address_info *mpu_config) 
 {
        int i;
 
@@ -687,65 +682,55 @@ static int __init sb_probe_isapnp(struct address_info *hw_config, struct address
 }
 #endif
 
-int init_module(void)
+static int __init init_sb(void)
 {
        printk(KERN_INFO "Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
 
-       if (mad16 == 0 && trix == 0 && pas2 == 0 && support == 0)
-       {
-               /* Please remember that even with CONFIG_ISAPNP defined one should still be
-                       able to disable PNP support for this single driver!
-               */
+       /* Please remember that even with CONFIG_ISAPNP defined one should still be
+               able to disable PNP support for this single driver!
+       */
 
 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE                      
-               if(isapnp && (sb_probe_isapnp(&config, &config_mpu) < 0) )
-               {
-                       printk(KERN_NOTICE "sb_card: No ISAPnP cards found, trying standard ones...\n");
-                       isapnp = 0;
-               }
+       if(isapnp && (sb_probe_isapnp(&cfg, &cfg_mpu) < 0) ) {
+               printk(KERN_NOTICE "sb_card: No ISAPnP cards found, trying standard ones...\n");
+               isapnp = 0;
+       }
 #endif
-               if(isapnp == 0)
-               {
-                       if (io == -1 || dma == -1 || irq == -1)
-                       {
-                               printk(KERN_ERR "sb_card: I/O, IRQ, and DMA are mandatory\n");
-                               return -EINVAL;
-                       }
 
-                       config.io_base  = io;
-                       config.irq      = irq;
-                       config.dma      = dma;
-                       config.dma2     = dma16;
-               }
+       if( isapnp == 0 ) {
+               cfg.io_base     = io;
+               cfg.irq         = irq;
+               cfg.dma         = dma;
+               cfg.dma2        = dma16;
+       }
 
-               config.card_subtype = type;
+       cfg.card_subtype = type;
 
-               if (!probe_sb(&config))
-                       return -ENODEV;
-               attach_sb_card(&config);
-       
-               if(config.slots[0]==-1)
-                       return -ENODEV;
-
-               if (isapnp == 0) 
-                       config_mpu.io_base = mpu_io;
-               if (probe_sbmpu(&config_mpu))
-                       sbmpu = 1;
-               if (sbmpu)
-                       attach_sbmpu(&config_mpu);
-       }
-       SOUND_LOCK;
+       if (!probe_sb(&cfg))
+               return -ENODEV;
+       attach_sb_card(&cfg);
+
+       if(cfg.slots[0]==-1)
+               return -ENODEV;
+               
+       if (isapnp == 0) 
+               cfg_mpu.io_base = mpu_io;
+       if (probe_sbmpu(&cfg_mpu))
+               sbmpu = 1;
+       if (sbmpu)
+               attach_sbmpu(&cfg_mpu);
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_sb(void)
 {
-       if (smw_free)
+       if (smw_free) {
                vfree(smw_free);
-       if (!mad16 && !trix && !pas2 && !support)
-               unload_sb(&config);
+               smw_free = NULL;
+       }
+       unload_sb(&cfg);
        if (sbmpu)
-               unload_sbmpu(&config_mpu);
+               unload_sbmpu(&cfg_mpu);
        SOUND_LOCK_END;
 
        if(sb_dev)      sb_dev->deactivate(sb_dev);
@@ -755,28 +740,23 @@ void cleanup_module(void)
        if(wss_dev)     wss_dev->deactivate(wss_dev);
 }
 
-#else
+module_init(init_sb);
+module_exit(cleanup_sb);
 
-#ifdef CONFIG_SM_GAMES
-int             sm_games = 1;
-#else
-int             sm_games = 0;
-#endif
-#ifdef CONFIG_SB_ACER
-int             acer = 1;
-#else
-int             acer = 0;
-#endif
-#endif
+#ifndef MODULE
+static int __init setup_sb(char *str)
+{
+       /* io, irq, dma, dma2 */
+       int ints[5];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io      = ints[1];
+       irq     = ints[2];
+       dma     = ints[3];
+       dma16   = ints[4];
 
-EXPORT_SYMBOL(sb_dsp_init);
-EXPORT_SYMBOL(sb_dsp_detect);
-EXPORT_SYMBOL(sb_dsp_unload);
-EXPORT_SYMBOL(sb_dsp_disable_midi);
-EXPORT_SYMBOL(attach_sb_card);
-EXPORT_SYMBOL(probe_sb);
-EXPORT_SYMBOL(unload_sb);
-EXPORT_SYMBOL(sb_be_quiet);
-EXPORT_SYMBOL(attach_sbmpu);
-EXPORT_SYMBOL(probe_sbmpu);
-EXPORT_SYMBOL(unload_sbmpu);
+       return 1;
+}
+__setup("sb=", setup_sb);
+#endif
index bda10bfad5dae26e54133c77cda212892977c24b..ffb1204addf182337d32c678faab2fa3aa33def7 100644 (file)
@@ -9,25 +9,42 @@
  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  * Version 2 (June 1991). See the "COPYING" file distributed with this software
  * for more info.
- */
-/*
+ *
+ *
  * Daniel J. Rodriksson: Modified sbintr to handle 8 and 16 bit interrupts
  *                       for full duplex support ( only sb16 by now )
  * Rolf Fokkens:        Added (BETA?) support for ES1887 chips.
  * (fokkensr@vertis.nl)         Which means: You can adjust the recording levels.
+ *
+ * 2000/01/18 - separated sb_card and sb_common -
+ * Jeff Garzik <jgarzik@mandrakesoft.com>
+ *
  */
+
+/* FIXME: *grr* why can't the f**in Makefile do this for me ? */
+#define EXPORT_SYMTAB
+
 #include <linux/config.h>
-#include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
 
 #include "sound_config.h"
 #include "sound_firmware.h"
+#include "soundmodule.h"
+
+#include "mpu401.h"
 
 #include "sb_mixer.h"
 #include "sb.h"
-
 #include "sb_ess.h"
 
+/*
+ * global module flag
+ */
+
+int sb_be_quiet = 0;
+
 static sb_devc *detected_devc = NULL;  /* For communication from probe to init */
 static sb_devc *last_devc = NULL;      /* For MPU401 initialization */
 
@@ -39,6 +56,16 @@ static unsigned char jazz_dma_bits[] = {
        0, 1, 0, 2, 0, 3, 0, 4
 };
 
+/* Do acer notebook init? */
+int acer = 0;
+
+/* soundman games? */
+int sm_games = 0;
+
+extern int esstype;
+
+void *smw_free = NULL;
+
 /*
  * Jazz16 chipset specific control variables
  */
@@ -1033,8 +1060,6 @@ static int smw_midi_init(sb_devc * devc, struct address_info *hw_config)
 #ifdef MODULE
        if (!smw_ucode)
        {
-               extern void *smw_free;
-
                smw_ucodeLen = mod_firmware_load("/etc/sound/midi0001.bin", (void *) &smw_ucode);
                smw_free = smw_ucode;
        }
@@ -1272,3 +1297,17 @@ void unload_sbmpu(struct address_info *hw_config)
 #endif
        unload_uart401(hw_config);
 }
+
+MODULE_PARM(acer, "i");
+MODULE_PARM(sm_games, "i");
+MODULE_PARM(esstype, "i");
+
+EXPORT_SYMBOL(sb_dsp_init);
+EXPORT_SYMBOL(sb_dsp_detect);
+EXPORT_SYMBOL(sb_dsp_unload);
+EXPORT_SYMBOL(sb_dsp_disable_midi);
+EXPORT_SYMBOL(sb_be_quiet);
+EXPORT_SYMBOL(attach_sbmpu);
+EXPORT_SYMBOL(probe_sbmpu);
+EXPORT_SYMBOL(unload_sbmpu);
+EXPORT_SYMBOL(smw_free);
index 6859b20c3a913507f67cbf2685071cca2bc9e628..7c02ee8b241c0f3cd136004662bc32e18f1d0b63 100644 (file)
@@ -9,8 +9,8 @@
  *    Aztech Sound Galaxy Washington 16
  *
  * Based on cs4232.c by Hannu Savolainen and Alan Cox.
- */
-/*
+ *
+ *
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  * for more info.
  */
 
+#include <linux/init.h>
 #include <linux/module.h>
 
 #include "sound_config.h"
 #include "soundmodule.h"
 
+#include "ad1848.h"
+
 static void sleep( unsigned howlong )
 {
        current->state   = TASK_INTERRUPTIBLE;
@@ -79,10 +82,9 @@ static int sb_cmd( int base, unsigned char val )
 
 #define ai_sgbase    driver_use_1
 
-int probe_sgalaxy( struct address_info *ai )
+static int __init probe_sgalaxy( struct address_info *ai )
 {
-       if ( check_region( ai->io_base, 8 ) )
-       {
+       if ( check_region( ai->io_base, 8 ) ) {
                printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
                return 0;
        }
@@ -90,8 +92,7 @@ int probe_sgalaxy( struct address_info *ai )
        if ( ad1848_detect( ai->io_base+4, NULL, ai->osp ) )
                return probe_ms_sound(ai);  /* The card is already active, check irq etc... */
 
-       if ( check_region( ai->ai_sgbase, 0x10 ) )
-       {
+       if ( check_region( ai->ai_sgbase, 0x10 ) ) {
                printk(KERN_ERR "sgalaxy: SB IO port 0x%03x not available\n", ai->ai_sgbase);
                return 0;
        }
@@ -108,7 +109,7 @@ int probe_sgalaxy( struct address_info *ai )
        return probe_ms_sound(ai);
 }
 
-void attach_sgalaxy( struct address_info *ai )
+static void __init attach_sgalaxy( struct address_info *ai )
 {
        int n;
        
@@ -117,27 +118,26 @@ void attach_sgalaxy( struct address_info *ai )
        attach_ms_sound( ai );
        n=ai->slots[0];
        
-       if (n!=-1 && audio_devs[n]->mixer_dev != -1 )
-       {
+       if (n!=-1 && audio_devs[n]->mixer_dev != -1 ) {
                AD1848_REROUTE( SOUND_MIXER_LINE1, SOUND_MIXER_LINE );   /* Line-in */
                AD1848_REROUTE( SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH );  /* FM+Wavetable*/
                AD1848_REROUTE( SOUND_MIXER_LINE3, SOUND_MIXER_CD );     /* CD */
        }
 }
 
-void unload_sgalaxy( struct address_info *ai )
+static void __exit unload_sgalaxy( struct address_info *ai )
 {
        unload_ms_sound( ai );
        release_region( ai->ai_sgbase, 0x10 );
 }
 
-#ifdef MODULE
+static struct address_info cfg;
 
-int   io       = -1;
-int   irq      = -1;
-int   dma      = -1;
-int   dma2     = -1;
-int   sgbase   = -1;
+static int __initdata io       = -1;
+static int __initdata irq      = -1;
+static int __initdata dma      = -1;
+static int __initdata dma2     = -1;
+static int __initdata sgbase   = -1;
 
 MODULE_PARM(io,"i");
 MODULE_PARM(irq,"i");
@@ -145,38 +145,52 @@ MODULE_PARM(dma,"i");
 MODULE_PARM(dma2,"i");
 MODULE_PARM(sgbase,"i");
 
-EXPORT_NO_SYMBOLS;
-
-struct address_info ai;
-
-
-int init_module(void)
+static int __init init_sgalaxy(void)
 {
-       if ( io==-1 || irq==-1 || dma==-1 || sgbase==-1 )
-       {
+       cfg.io_base   = io;
+       cfg.irq       = irq;
+       cfg.dma       = dma;
+       cfg.dma2      = dma2;
+       cfg.ai_sgbase = sgbase;
+
+       if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.ai_sgbase == -1 ) {
                printk(KERN_ERR "sgalaxy: io, irq, dma and sgbase must be set.\n");
                return -EINVAL;
        }
 
-       ai.io_base   = io;
-       ai.irq       = irq;
-       ai.dma       = dma;
-       ai.dma2      = dma2;
-       ai.ai_sgbase = sgbase;
-
-       if ( probe_sgalaxy( &ai )==0 )
+       if ( probe_sgalaxy(&cfg) == 0 )
                return -ENODEV;
 
-       attach_sgalaxy( &ai );
+       attach_sgalaxy(&cfg);
 
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_sgalaxy(void)
 {
-       unload_sgalaxy( &ai );
+       unload_sgalaxy(&cfg);
        SOUND_LOCK_END;
 }
 
-#endif /* MODULE */
+module_init(init_sgalaxy);
+module_exit(cleanup_sgalaxy);
+
+#ifndef MODULE
+static int __init setup_sgalaxy(char *str)
+{
+       /* io, irq, dma, dma2, sgbase */
+       int ints[6];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       io      = ints[1];
+       irq     = ints[2];
+       dma     = ints[3];
+       dma2    = ints[4];
+       sgbase  = ints[5];
+
+       return 1;
+}
+
+__setup("sgalaxy=", setup_sgalaxy);
+#endif
index ac8e4034f99ca5b8234aef1eb12c447566742053..0ef54e6d0843fd2930b236a476eecf231a7f850b 100644 (file)
  * for more info.
  *
  *
- * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
+ * Thomas Sailer       : ioctl code reworked (vmalloc/vfree removed)
+ * Christoph Hellwig   : adapted to module_init/module_exit
  */
+
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/module.h>
 
 /*
@@ -1445,7 +1448,7 @@ static struct sound_lowlev_timer soft_tmr =
        soft_tmr_restart
 };
 
-int probe_softsyn(struct address_info *hw_config)
+static int __init probe_softsyn(struct address_info *hw_config)
 {
        int i;
 
@@ -1484,7 +1487,7 @@ int probe_softsyn(struct address_info *hw_config)
        return 1;
 }
 
-void attach_softsyn_card(struct address_info *hw_config)
+static void __init attach_softsyn_card(struct address_info *hw_config)
 {
        voice_alloc = &softsyn_operations.alloc;
        synth_devs[devc->synthdev = num_synths++] = &softsyn_operations;
@@ -1497,7 +1500,7 @@ void attach_softsyn_card(struct address_info *hw_config)
 #endif
 }
 
-void unload_softsyn(struct address_info *hw_config)
+static void __exit unload_softsyn(struct address_info *hw_config)
 {
        if (!softsynth_loaded)
                return;
@@ -1506,25 +1509,25 @@ void unload_softsyn(struct address_info *hw_config)
        reset_samples(devc);
 }
 
-#ifdef MODULE
-
-static struct address_info config;
+static struct address_info cfg;
 
-int init_module(void)
+static int __init init_softoss(void)
 {
        printk(KERN_INFO "SoftOSS driver Copyright (C) by Hannu Savolainen 1993-1997\n");
-       if (!probe_softsyn(&config))
+       if (!probe_softsyn(&cfg))
                return -ENODEV;
-       attach_softsyn_card(&config);
+       attach_softsyn_card(&cfg);
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_softoss(void)
 {
-       unload_softsyn(&config);
+       unload_softsyn(&cfg);
        sound_unload_synthdev(devc->synthdev);
        sound_unload_timerdev(devc->timerdev);
        SOUND_LOCK_END;
 }
-#endif /* MODULE */
+
+module_init(init_softoss);
+module_exit(cleanup_softoss);
index 1029df1f265e6f5169126ff7232f87cebf162e9e..8d450ca66ad4e7f03822c97f7a99ac5700363dc2 100644 (file)
@@ -76,10 +76,6 @@ int MIDIbuf_avail(int dev);
 void MIDIbuf_bytes_received(int dev, unsigned char *buf, int count);
 void MIDIbuf_init(void);
 
-/*
- *
- *     Misc calls from various sources
- */
 
 /*     From soundcard.c        */
 void request_sound_timer (int count);
@@ -87,237 +83,16 @@ void sound_stop_timer(void);
 void conf_printf(char *name, struct address_info *hw_config);
 void conf_printf2(char *name, int base, int irq, int dma, int dma2);
 
-/*     From opl3.c     */
-int opl3_detect (int ioaddr, int *osp);
-int opl3_init(int ioaddr, int *osp);
-
-/*     From sb_card.c  */
-void attach_sb_card(struct address_info *hw_config);
-int probe_sb(struct address_info *hw_config);
-
-/*     From sb_common.c */
-void sb_dsp_disable_midi(int port);
-void sb_dsp_disable_recording(int port);
-void attach_sbmpu (struct address_info *hw_config);
-int probe_sbmpu (struct address_info *hw_config);
-void unload_sbmpu (struct address_info *hw_config);
-
-/*     From uart401.c */
-void attach_uart401 (struct address_info *hw_config);
-int probe_uart401 (struct address_info *hw_config);
-void unload_uart401 (struct address_info *hw_config);
-void uart401intr (int irq, void *dev_id, struct pt_regs * dummy);
-
-/*     From adlib_card.c       */
-void attach_adlib_card(struct address_info *hw_config);
-int probe_adlib(struct address_info *hw_config);
-
-/*     From pas_card.c */
-void attach_pas_card(struct address_info *hw_config);
-int probe_pas(struct address_info *hw_config);
-int pas_set_intr(int mask);
-int pas_remove_intr(int mask);
-unsigned char pas_read(int ioaddr);
-void pas_write(unsigned char data, int ioaddr);
-
-/*     From pas_audio.c */
-void pas_pcm_interrupt(unsigned char status, int cause);
-void pas_pcm_init(struct address_info *hw_config);
-
-/*     From pas_mixer.c */
-int pas_init_mixer(void);
-
-/*     From pas_midi.c */
-void pas_midi_init(void);
-void pas_midi_interrupt(void);
-
-/*     From gus_card.c */
-void attach_gus_card(struct address_info * hw_config);
-int probe_gus(struct address_info *hw_config);
-int gus_set_midi_irq(int num);
-void gusintr(int irq, void *dev_id, struct pt_regs * dummy);
-void attach_gus_db16(struct address_info * hw_config);
-int probe_gus_db16(struct address_info *hw_config);
-
-/*     From gus_wave.c */
-int gus_wave_detect(int baseaddr);
-void gus_wave_init(struct address_info *hw_config);
-void gus_wave_unload (struct address_info *hw_config);
-void gus_voice_irq(void);
-void gus_write8(int reg, unsigned int data);
-void guswave_dma_irq(void);
-void gus_delay(void);
-int gus_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg);
-void gus_timer_command (unsigned int addr, unsigned int val);
-
-/*     From gus_midi.c */
-void gus_midi_init(struct address_info *hw_config);
-void gus_midi_interrupt(int dummy);
-
-/*     From mpu401.c */
-void attach_mpu401(struct address_info * hw_config);
-int probe_mpu401(struct address_info *hw_config);
-int intchk_mpu401(void *dev_id);
-void mpuintr(int irq, void *dev_id, struct pt_regs * dummy);
-
-/*     From uart6850.c */
-void attach_uart6850(struct address_info * hw_config);
-int probe_uart6850(struct address_info *hw_config);
-
-/*     From opl3.c */
-void enable_opl3_mode(int left, int right, int both);
-
-/*     From ics2101.c */
-int ics2101_mixer_init(void);
-
 /*     From sound_timer.c */
 void sound_timer_interrupt(void);
 void sound_timer_syncinterval(unsigned int new_usecs);
 
-/*     From ad1848.c */
-int ad1848_init (char *name, int io_base, int irq, int dma_playback, int dma_capture, int share_dma, int *osp);
-void ad1848_unload (int io_base, int irq, int dma_playback, int dma_capture, int share_dma);
-
-int ad1848_detect (int io_base, int *flags, int *osp);
-#define AD_F_CS4231    0x0001  /* Returned if a CS4232 (or compatible) detected */
-#define AD_F_CS4248    0x0001  /* Returned if a CS4248 (or compatible) detected */
-
-int     ad1848_control(int cmd, int arg);
-#define                AD1848_SET_XTAL         1
-#define                AD1848_MIXER_REROUTE    2
-#define AD1848_REROUTE(oldctl, newctl) \
-               ad1848_control(AD1848_MIXER_REROUTE, ((oldctl)<<8)|(newctl))
-
-void adintr(int irq, void *dev_id, struct pt_regs * dummy);
-void attach_ms_sound(struct address_info * hw_config);
-int probe_ms_sound(struct address_info *hw_config);
-
-/*     From pss.c */
-int probe_pss (struct address_info *hw_config);
-void attach_pss (struct address_info *hw_config);
-int probe_pss_mpu (struct address_info *hw_config);
-void attach_pss_mpu (struct address_info *hw_config);
-int probe_pss_mss (struct address_info *hw_config);
-void attach_pss_mss (struct address_info *hw_config);
-
-/*     From sscape.c */
-int probe_sscape (struct address_info *hw_config);
-void attach_sscape (struct address_info *hw_config);
-int probe_ss_ms_sound (struct address_info *hw_config);
-void attach_ss_ms_sound(struct address_info * hw_config);
-
-/* From ad1816.c */
-void unload_ad1816(struct address_info *hw_info);
-int probe_ad1816 (struct address_info *hw_config);
-void attach_ad1816 (struct address_info *hw_config);
+/*      From midi_synth.c       */
+void do_midi_msg (int synthno, unsigned char *msg, int mlen);
 
-/* From aedsp16.c */
+#ifdef FIXED_LOWLEVEL_SOUND
+/*     From aedsp16.c */
 int InitAEDSP16_SBPRO(struct address_info *hw_config);
 int InitAEDSP16_MSS(struct address_info *hw_config);
 int InitAEDSP16_MPU401(struct address_info *hw_config);
-
-/*     From midi_synth.c       */
-void do_midi_msg (int synthno, unsigned char *msg, int mlen);
-
-/*     From trix.c     */
-void attach_trix_wss (struct address_info *hw_config);
-int probe_trix_wss (struct address_info *hw_config);
-void attach_trix_sb (struct address_info *hw_config);
-int probe_trix_sb (struct address_info *hw_config);
-void attach_trix_mpu (struct address_info *hw_config);
-int probe_trix_mpu (struct address_info *hw_config);
-
-/*     From mad16.c    */
-void attach_mad16 (struct address_info *hw_config);
-int probe_mad16 (struct address_info *hw_config);
-void attach_mad16_mpu (struct address_info *hw_config);
-int probe_mad16_mpu (struct address_info *hw_config);
-
-/*     Unload routines from various source files*/
-void unload_pss(struct address_info *hw_info);
-void unload_pss_mpu(struct address_info *hw_info);
-void unload_pss_mss(struct address_info *hw_info);
-void unload_mad16(struct address_info *hw_info);
-void unload_mad16_mpu(struct address_info *hw_info);
-void unload_adlib(struct address_info *hw_info);
-void unload_pas(struct address_info *hw_info);
-void unload_mpu401(struct address_info *hw_info);
-void unload_maui(struct address_info *hw_info);
-void unload_uart6850(struct address_info *hw_info);
-void unload_sb(struct address_info *hw_info);
-void unload_sb16(struct address_info *hw_info);
-void unload_sb16midi(struct address_info *hw_info);
-void unload_gus_db16(struct address_info *hw_info);
-void unload_ms_sound(struct address_info *hw_info);
-void unload_gus(struct address_info *hw_info);
-void unload_sscape(struct address_info *hw_info);
-void unload_ss_ms_sound(struct address_info *hw_info);
-void unload_trix_wss(struct address_info *hw_info);
-void unload_trix_sb(struct address_info *hw_info);
-void unload_trix_mpu(struct address_info *hw_info);
-void unload_cs4232(struct address_info *hw_info);
-void unload_cs4232_mpu(struct address_info *hw_info);
-void unload_opl3sa_wss(struct address_info *hw_info);
-void unload_opl3sa_sb(struct address_info *hw_info);
-void unload_opl3sa_mpu(struct address_info *hw_info);
-void unload_opl3sa2(struct address_info *hw_info);
-void unload_opl3sa2_mpu(struct address_info *hw_info);
-void unload_opl3sa2_mss(struct address_info *hw_info);
-void unload_softsyn (struct address_info *hw_config);
-
-/*     From cs4232.c */
-int probe_cs4232 (struct address_info *hw_config);
-void attach_cs4232 (struct address_info *hw_config);
-int probe_cs4232_mpu (struct address_info *hw_config);
-void attach_cs4232_mpu (struct address_info *hw_config);
-
-/*     From opl3sa.c */
-void attach_opl3sa_wss (struct address_info *hw_config);
-int probe_opl3sa_wss (struct address_info *hw_config);
-void attach_opl3sa_sb (struct address_info *hw_config);
-int probe_opl3sa_sb (struct address_info *hw_config);
-void attach_opl3sa_mpu (struct address_info *hw_config);
-int probe_opl3sa_mpu (struct address_info *hw_config);
-
-/*     From opl3sa2.c */
-int probe_opl3sa2 (struct address_info *hw_config);
-void attach_opl3sa2 (struct address_info *hw_config);
-int probe_opl3sa2_mpu (struct address_info *hw_config);
-void attach_opl3sa2_mpu (struct address_info *hw_config);
-int probe_opl3sa2_mss (struct address_info *hw_config);
-void attach_opl3sa2_mss (struct address_info *hw_config);
-
-/*     From softoss.c */
-void attach_softsyn_card (struct address_info *hw_config);
-int probe_softsyn (struct address_info *hw_config);
-
-/*     From maui.c */
-void attach_maui(struct address_info * hw_config);
-int probe_maui(struct address_info *hw_config);
-
-/*     From v_midi.c */
-void attach_v_midi (struct address_info *hw_config);
-int probe_v_midi (struct address_info *hw_config);
-void unload_v_midi (struct address_info *hw_config);
-
-/*     From vidc.c */
-void attach_vidc(struct address_info *hw_config);
-int probe_vidc(struct address_info *hw_config);
-void unload_vidc(struct address_info *hw_config);
-
-/*     From waveartist.c */
-void attach_waveartist(struct address_info *hw_config);
-int probe_waveartist(struct address_info *hw_config);
-void unload_waveartist(struct address_info *hw_config);
-
-/*     From wavefront.c */
-void attach_wavefront (struct address_info *hw_config);
-int probe_wavefront (struct address_info *hw_config);
-void unload_wavefront (struct address_info *hw_config);
-
-/*     From wf_midi.c */
-void attach_wf_mpu(struct address_info * hw_config);
-int probe_wf_mpu(struct address_info *hw_config);
-void unload_wf_mpu(struct address_info *hw_config);
-int virtual_midi_enable (void);
-int virtual_midi_disable (void);
+#endif
index 7621f33be76e0cb1ecea1f0f468812265b9eeb31..35c39e94744ab3f291e55f32c8e23382ec8b1747 100644 (file)
 #define CONFIG_PAS_BASE        0x388
 #endif
 
-#if defined(CONFIG_SB16_DMA) && !defined(CONFIG_SB_DMA2)
-#  define CONFIG_SB_DMA2 CONFIG_SB16_DMA
-#endif
-
-#if defined(SB16MIDI_BASE) && !defined(CONFIG_SB_MPU_BASE)
-#   define CONFIG_SB_MPU_BASE SB16MIDI_BASE
-#endif
-
-#ifndef CONFIG_SB_MPU_IRQ
-#  define CONFIG_SB_MPU_IRQ CONFIG_SB_IRQ
-#endif
-
 /* SEQ_MAX_QUEUE is the maximum number of sequencer events buffered by the
    driver. (There is no need to alter this) */
 #define SEQ_MAX_QUEUE  1024
index bf3ff10fec13a051faa9e4733814c1de7b12fdaf..b6f2855be1f53907997e42f961e0d0649cb31792 100644 (file)
@@ -46,8 +46,6 @@ EXPORT_SYMBOL(sound_unload_synthdev);
 
 EXPORT_SYMBOL(load_mixer_volumes);
 
-EXPORT_SYMBOL(trace_init); /* oops! this is needed for maui.c -- AJK */
-
 EXPORT_SYMBOL(conf_printf);
 EXPORT_SYMBOL(conf_printf2);
 
index 81f9cdb1916d25861ef2333de18f2334deb31609..00f8b6e7b49a82491e20953d38d15b10206b346a 100644 (file)
@@ -2,24 +2,24 @@
  * linux/drivers/sound/soundcard.c
  *
  * Sound card driver for Linux
- */
-/*
+ *
+ *
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  * Version 2 (June 1991). See the "COPYING" file distributed with this software
  * for more info.
- */
-/*
- * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
+ *
+ *
+ * Thomas Sailer     : ioctl code reworked (vmalloc/vfree removed)
  *                   integrated sound_switch.c
- * Stefan Reinauer : integrated /proc/sound (equals to /dev/sndstat,
+ * Stefan Reinauer   : integrated /proc/sound (equals to /dev/sndstat,
  *                   which should disappear in the near future)
- * Eric Dumas      : devfs support (22-Jan-98) <dumas@linux.eu.org> with fixups
- *                   by C. Scott Ananian <cananian@alumni.princeton.edu>
- * Richard Gooch   : moved common (non OSS-specific) devices to sound_core.c
- *
- * Rob Riggs           Added persistent DMA buffers support (1998/10/17)
+ * Eric Dumas       : devfs support (22-Jan-98) <dumas@linux.eu.org> with
+ *                   fixups by C. Scott Ananian <cananian@alumni.princeton.edu>
+ * Richard Gooch     : moved common (non OSS-specific) devices to sound_core.c
+ * Rob Riggs        : Added persistent DMA buffers support (1998/10/17)
+ * Christoph Hellwig : Some cleanup work (2000/03/01)
  */
 
 #include <linux/config.h>
@@ -32,7 +32,6 @@
 #include <linux/ctype.h>
 #include <linux/stddef.h>
 #include <linux/kmod.h>
-#ifdef __KERNEL__
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/segment.h>
 #include <linux/ioport.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/major.h>
-#endif                         /* __KERNEL__ */
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/smp_lock.h>
 #include "soundmodule.h"
 
+
+#if defined(CONFIG_LOWLEVEL_SOUND) && !defined MODULE
+extern void sound_preinit_lowlevel_drivers(void);
+extern void sound_init_lowlevel_drivers(void);
+#endif
+
 /* From obsolete legacy.h */
 #define SELECTED_SOUND_OPTIONS 0x0
 
 struct notifier_block *sound_locker=(struct notifier_block *)0;
 static int lock_depth = 0;
 
-#ifdef MODULE
-#define modular 1
-#else
-#define modular 0
-#endif
-
 /*
  * This ought to be moved into include/asm/dma.h
  */
@@ -76,16 +74,9 @@ caddr_t         sound_mem_blocks[1024];
 int             sound_nblocks = 0;
 
 /* Persistent DMA buffers */
-#ifdef CONFIG_SOUND_DMAP
-int            sound_dmap_flag = 1;
-#else
 int            sound_dmap_flag = 0;
-#endif
-
 static int      soundcard_configured = 0;
-
-static char     dma_alloc_map[MAX_DMA_CHANNELS] =
-{0};
+static char     dma_alloc_map[MAX_DMA_CHANNELS] = {0};
 
 #define DMA_MAP_UNAVAIL                0
 #define DMA_MAP_FREE           1
@@ -101,6 +92,8 @@ unsigned long seq_time = 0;  /* Time for /dev/sequencer */
 static mixer_vol_table mixer_vols[MAX_MIXER_DEV];
 static int num_mixer_volumes = 0;
 
+int traceinit = 0;
+
 int *load_mixer_volumes(char *name, int *levels, int present)
 {
        int             i, n;
@@ -159,137 +152,6 @@ static int get_mixer_levels(caddr_t arg)
        return 0;
 }
 
-static int sound_proc_get_info(char *buffer, char **start, off_t offset, int length)
-{
-       int len, i, drv;
-        off_t pos = 0;
-        off_t begin = 0;
-
-#ifdef MODULE
-#define MODULEPROCSTRING "Driver loaded as a module"
-#else
-#define MODULEPROCSTRING "Driver compiled into kernel"
-#endif
-
-       down_read(&uts_sem);    
-
-       len = sprintf(buffer, "OSS/Free:" SOUND_VERSION_STRING "\n"
-                     "Load type: " MODULEPROCSTRING "\n"
-                     "Kernel: %s %s %s %s %s\n"
-                     "Config options: %x\n\nInstalled drivers: \n", 
-                     system_utsname.sysname, system_utsname.nodename, system_utsname.release, 
-                     system_utsname.version, system_utsname.machine, SELECTED_SOUND_OPTIONS);
-       up_read(&uts_sem);
-       
-       for (i = 0; (i < num_sound_drivers) && (pos <= offset + length); i++) {
-               if (!sound_drivers[i].card_type)
-                       continue;
-               len += sprintf(buffer + len, "Type %d: %s\n", 
-                              sound_drivers[i].card_type, sound_drivers[i].name);
-               pos = begin + len;
-               if (pos < offset) {
-                       len = 0;
-                       begin = pos;
-               }
-       }
-       len += sprintf(buffer + len, "\nCard config: \n");
-
-       for (i = 0; (i < num_sound_cards) && (pos <= offset + length); i++) 
-       {
-               if (!snd_installed_cards[i].card_type)
-                       continue;
-               if (!snd_installed_cards[i].enabled)
-                       len += sprintf(buffer + len, "(");
-               if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) != -1)
-                       len += sprintf(buffer + len, "%s", sound_drivers[drv].name);
-               if (snd_installed_cards[i].config.io_base)
-                       len += sprintf(buffer + len, " at 0x%x", snd_installed_cards[i].config.io_base);
-               if (snd_installed_cards[i].config.irq != 0)
-                       len += sprintf(buffer + len, " irq %d", abs(snd_installed_cards[i].config.irq));
-               if (snd_installed_cards[i].config.dma != -1) {
-                       len += sprintf(buffer + len, " drq %d", snd_installed_cards[i].config.dma);
-                       if (snd_installed_cards[i].config.dma2 != -1)
-                               len += sprintf(buffer + len, ",%d", snd_installed_cards[i].config.dma2);
-               }
-               if (!snd_installed_cards[i].enabled)
-                       len += sprintf(buffer + len, ")");
-               len += sprintf(buffer + len, "\n");
-               pos = begin + len;
-               if (pos < offset) {
-                       len = 0;
-                       begin = pos;
-               }
-       }
-       if (!sound_started)
-               len += sprintf(buffer + len, "\n\n***** Sound driver not started *****\n\n");
-       len += sprintf(buffer + len, "\nAudio devices:\n");
-       for (i = 0; (i < num_audiodevs) && (pos <= offset + length); i++) {
-               if (audio_devs[i] == NULL)
-                       continue;
-               len += sprintf(buffer + len, "%d: %s%s\n", i, audio_devs[i]->name, 
-                              audio_devs[i]->flags & DMA_DUPLEX ? " (DUPLEX)" : "");
-               pos = begin + len;
-               if (pos < offset) {
-                       len = 0;
-                       begin = pos;
-               }
-       }
-
-       len += sprintf(buffer + len, "\nSynth devices:\n");
-       for (i = 0; (i < num_synths) && (pos <= offset + length); i++) {
-               if (synth_devs[i] == NULL)
-                       continue;
-               len += sprintf(buffer + len, "%d: %s\n", i, synth_devs[i]->info->name);
-               pos = begin + len;
-               if (pos < offset) {
-                       len = 0;
-                       begin = pos;
-               }
-       }
-
-       len += sprintf(buffer + len, "\nMidi devices:\n");
-       for (i = 0; (i < num_midis) && (pos <= offset + length); i++) {
-               if (midi_devs[i] == NULL)
-                       continue;
-               len += sprintf(buffer + len, "%d: %s\n", i, midi_devs[i]->info.name);
-               pos = begin + len;
-               if (pos < offset) {
-                       len = 0;
-                       begin = pos;
-               }
-       }
-
-       len += sprintf(buffer + len, "\nTimers:\n");
-
-       for (i = 0; (i < num_sound_timers) && (pos <= offset + length); i++) {
-               if (sound_timer_devs[i] == NULL)
-                       continue;
-               len += sprintf(buffer + len, "%d: %s\n", i, sound_timer_devs[i]->info.name);
-               pos = begin + len;
-               if (pos < offset) {
-                       len = 0;
-                       begin = pos;
-               }
-       }
-
-       len += sprintf(buffer + len, "\nMixers:\n");
-       for (i = 0; (i < num_mixers) && (pos <= offset + length); i++) {
-               if (mixer_devs[i] == NULL)
-                       continue;
-               len += sprintf(buffer + len, "%d: %s\n", i, mixer_devs[i]->name);
-               pos = begin + len;
-               if (pos < offset) {
-                       len = 0;
-                       begin = pos;
-               }
-       }
-       *start = buffer + (offset - begin);
-       len -= (offset - begin);
-        if (len > length) 
-               len = length;
-        return len;
-}
-
 #ifndef MIN
 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
 #endif
@@ -297,67 +159,6 @@ static int sound_proc_get_info(char *buffer, char **start, off_t offset, int len
 /* 4K page size but our output routines use some slack for overruns */
 #define PROC_BLOCK_SIZE (3*1024)
 
-/*
- * basically copied from fs/proc/generic.c:proc_file_read 
- * should be removed sometime in the future together with /dev/sndstat
- * (a symlink /dev/sndstat -> /proc/sound will do as well)
- */
-static ssize_t sndstat_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
-{
-        char    *page;
-        ssize_t retval=0;
-        int     eof=0;
-        ssize_t n, count;
-        char    *start;
-
-        if (!(page = (char*) __get_free_page(GFP_KERNEL)))
-                return -ENOMEM;
-
-        while ((nbytes > 0) && !eof)
-        {
-                count = MIN(PROC_BLOCK_SIZE, nbytes);
-
-                start = NULL;
-               n = sound_proc_get_info(page, &start, *ppos, count);
-               if (n < count)
-                       eof = 1;
-                        
-                if (!start) {
-                        /*
-                         * For proc files that are less than 4k
-                         */
-                        start = page + *ppos;
-                        n -= *ppos;
-                        if (n <= 0)
-                                break;
-                        if (n > count)
-                                n = count;
-                }
-                if (n == 0)
-                        break;  /* End of file */
-                if (n < 0) {
-                        if (retval == 0)
-                                retval = n;
-                        break;
-                }
-                
-                n -= copy_to_user(buf, start, n);       /* BUG ??? */
-                if (n == 0) {
-                        if (retval == 0)
-                                retval = -EFAULT;
-                        break;
-                }
-                
-                *ppos += n;     /* Move down the file */
-                nbytes -= n;
-                buf += n;
-                retval += n;
-        }
-        free_page((unsigned long) page);
-        return retval;
-}
-
-
 static ssize_t sound_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 {
        int dev = MINOR(file->f_dentry->d_inode->i_rdev);
@@ -373,10 +174,6 @@ static ssize_t sound_read(struct file *file, char *buf, size_t count, loff_t *pp
        
        DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count));
        switch (dev & 0x0f) {
-       case SND_DEV_STATUS:
-               ret = sndstat_file_read(file, buf, count, ppos);
-               break;
-
        case SND_DEV_DSP:
        case SND_DEV_DSP16:
        case SND_DEV_AUDIO:
@@ -484,10 +281,8 @@ static int sound_open(struct inode *inode, struct file *file)
        }
        in_use++;
 
-#ifdef CONFIG_MODULES
        notifier_call_chain(&sound_locker, 1, 0);
        lock_depth++;
-#endif
 
        return 0;
 }
@@ -522,10 +317,8 @@ static int sound_release(struct inode *inode, struct file *file)
        }
        in_use--;
 
-#ifdef CONFIG_MODULES
        notifier_call_chain(&sound_locker, 0, 0);
        lock_depth--;
-#endif
 
        return 0;
 }
@@ -844,22 +637,13 @@ soundcard_init(void)
 
        soundcard_configured = 1;
 
-       sndtable_init();        /* Initialize call tables and detect cards */
-
-
-#ifdef FIXME
-       if (sndtable_get_cardcount() == 0)
-               return;         /* No cards detected */
+#if defined(CONFIG_LOWLEVEL_SOUND) && !defined(MODULE)
+        sound_preinit_lowlevel_drivers();
+       sound_init_lowlevel_drivers();
 #endif
 
-       if (num_audiodevs || modular)   /* Audio devices present */
-       {
-               audio_init_devices();
-       }
-#ifdef CONFIG_PROC_FS
-       if (!create_proc_info_entry("sound", 0, NULL, sound_proc_get_info))
-               printk(KERN_ERR "sound: registering /proc/sound failed\n");
-#endif         
+       audio_init_devices();
+
        soundcard_register_devfs(1); /* register after we know # of devices */
 }
 
@@ -876,7 +660,6 @@ static int      sound[20] = {
        0
 };
 
-int traceinit = 0;
 static int dmabuf = 0;
 static int dmabug = 0;
 
@@ -892,8 +675,6 @@ int init_module(void)
        int             i;
 #endif
 
-       trace_init=traceinit;
-       
 #ifdef HAS_BRIDGE_BUGGY_FUNC
        if(dmabug)
                isa_dma_bridge_buggy = dmabug;
@@ -956,7 +737,6 @@ void cleanup_module(void)
                sound_unload_lowlevel_drivers();
        }
 #endif
-       sound_unload_drivers();
        sequencer_unload();
 
        for (i = 0; i < MAX_DMA_CHANNELS; i++)
@@ -1075,9 +855,8 @@ void sound_stop_timer(void)
 
 void conf_printf(char *name, struct address_info *hw_config)
 {
-       if (!trace_init)
+       if (!traceinit)
                return;
-
        printk("<%s> at 0x%03x", name, hw_config->io_base);
 
        if (hw_config->irq)
@@ -1094,7 +873,7 @@ void conf_printf(char *name, struct address_info *hw_config)
 
 void conf_printf2(char *name, int base, int irq, int dma, int dma2)
 {
-       if (!trace_init)
+       if (!traceinit)
                return;
 
        printk("<%s> at 0x%03x", name, base);
index b89e74e519f279f4a9054f33d3c6ea64154dc4ce..6fb0b00a0330ddf2dac7bccb2dca7148d532ced4 100644 (file)
@@ -2,12 +2,11 @@
 #define _SOUNDMODULE_H
 
 #include <linux/notifier.h>
+#include <linux/module.h>
 
 extern struct notifier_block *sound_locker;
 extern void sound_notifier_chain_register(struct notifier_block *);
 
-#ifdef MODULE
-
 #define SOUND_LOCK             sound_notifier_chain_register(&sound_notifier); 
 #define SOUND_LOCK_END         notifier_chain_unregister(&sound_locker, &sound_notifier)
 
@@ -28,4 +27,3 @@ static struct notifier_block sound_notifier=
 };
 
 #endif
-#endif
index 1c06b7c31c2cb111bb104539bdccdac245c48e07..5efd99dd225a6745047fbe5ab66429c17ef4491f 100644 (file)
@@ -2,21 +2,22 @@
  * sound/sscape.c
  *
  * Low level driver for Ensoniq SoundScape
- */
-/*
+ *
+ *
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  * Version 2 (June 1991). See the "COPYING" file distributed with this software
  * for more info.
- */
-/*
+ *
+ *
  * Thomas Sailer       : ioctl code reworked (vmalloc/vfree removed)
  * Sergey Smitienko    : ensoniq p'n'p support
+ * Christoph Hellwig   : adapted to module_init/module_exit
  */
 
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/module.h>
 
 #include "sound_config.h"
 #include <linux/ctype.h>
 #include <linux/stddef.h>
 #include <linux/kmod.h>
-#ifdef __KERNEL__
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/segment.h>
 #include <linux/wait.h>
 #include <linux/malloc.h>
 #include <linux/ioport.h>
-#endif                         /* __KERNEL__ */
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 
 #include "coproc.h"
 
+#include "ad1848.h"
+#include "mpu401.h"
+
 /*
  *    I/O ports
  */
@@ -1005,7 +1007,7 @@ static    int     sscape_pnp_upload_file(sscape_info* devc, char* fn)
        return 1;
 }
 
-static void    sscape_pnp_init_hw(sscape_info* devc)
+static void __init sscape_pnp_init_hw(sscape_info* devc)
 {      
        unsigned char midi_irq = 0, sb_irq = 0;
        unsigned i;
@@ -1127,7 +1129,7 @@ static    void    sscape_pnp_init_hw(sscape_info* devc)
        sscape_pnp_free_dma(devc);
 }
 
-static int     detect_sscape_pnp(sscape_info* devc)
+static int __init detect_sscape_pnp(sscape_info* devc)
 {
        long     i, irq_bits = 0xff;
        unsigned int d;
@@ -1240,7 +1242,7 @@ static int        detect_sscape_pnp(sscape_info* devc)
        return 1;       
 }
 
-int probe_sscape(struct address_info *hw_config)
+static int __init probe_sscape(struct address_info *hw_config)
 {
 
        if (sscape_detected != 0 && sscape_detected != hw_config->io_base)
@@ -1289,7 +1291,7 @@ int probe_sscape(struct address_info *hw_config)
        return 1;
 }
 
-int probe_ss_ms_sound(struct address_info *hw_config)
+static int __init probe_ss_ms_sound(struct address_info *hw_config)
 {
        int i, irq_bits = 0xff;
        int ad_flags = 0;
@@ -1332,7 +1334,7 @@ int probe_ss_ms_sound(struct address_info *hw_config)
        }
 }
 
-void attach_ss_ms_sound(struct address_info *hw_config)
+static void __init attach_ss_ms_sound(struct address_info *hw_config)
 {
        /*
         * This routine configures the SoundScape card for use with the
@@ -1413,13 +1415,13 @@ void attach_ss_ms_sound(struct address_info *hw_config)
 
 }
 
-void unload_sscape(struct address_info *hw_config)
+static void __exit unload_sscape(struct address_info *hw_config)
 {
        release_region(devc->base + 2, 6);
        unload_mpu401(hw_config);
 }
 
-void unload_ss_ms_sound(struct address_info *hw_config)
+static void __exit unload_ss_ms_sound(struct address_info *hw_config)
 {
        ad1848_unload(hw_config->io_base,
                      hw_config->irq,
@@ -1429,18 +1431,16 @@ void unload_ss_ms_sound(struct address_info *hw_config)
        sound_unload_audiodev(hw_config->slots[0]);
 }
 
-#ifdef MODULE
-
-int             dma = -1;
-int             irq = -1;
-int             io = -1;
+static struct address_info cfg;
+static struct address_info cfg_mpu;
 
-int             mpu_irq = -1;
-int             mpu_io = -1;
-
-int            spea = -1;
-
-static int      mss = 0;
+static int __initdata spea = -1;
+static int __initdata mss = 0;
+static int __initdata dma = -1;
+static int __initdata irq = -1;
+static int __initdata io = -1;
+static int __initdata mpu_irq = -1;
+static int __initdata mpu_io = -1;
 
 MODULE_PARM(dma, "i");
 MODULE_PARM(irq, "i");
@@ -1450,63 +1450,80 @@ MODULE_PARM(mpu_irq, "i");
 MODULE_PARM(mpu_io, "i");
 MODULE_PARM(mss, "i");
 
-struct address_info config;
-struct address_info mpu_config;
-
-int init_module(void)
+static int __init init_sscape(void)
 {
        printk(KERN_INFO "Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n");
-       if (dma == -1 || irq == -1 || io == -1)
-       {
-               printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
-               return -EINVAL;
-       }
-       if (mpu_irq == -1 && mpu_io != -1)
-       {
-                 printk(KERN_ERR "CONFIG_MPU_IRQ must be specified if CONFIG_MPU_IO is set.\n");
-                 return -EINVAL;
-       }
        
-       devc->codec = io;
-       devc->codec_irq = irq;
+       cfg.irq = irq;
+       cfg.dma = dma;
+       cfg.io_base = io;
+
+       cfg_mpu.irq = mpu_irq;
+       cfg_mpu.io_base = mpu_io;
+       /* WEH - Try to get right dma channel */
+        cfg_mpu.dma = dma;
+       
+       devc->codec = cfg.io_base;
+       devc->codec_irq = cfg.irq;
        devc->codec_type = 0;
        devc->ic_type = 0;
        devc->raw_buf = NULL;
-       
-       config.irq = irq;
-       config.dma = dma;
-       config.io_base = io;
 
-       mpu_config.irq = mpu_irq;
-       mpu_config.io_base = mpu_io;
-       /* WEH - Try to get right dma channel */
-        mpu_config.dma = dma;
-      
-       if(spea != -1)
-       {
+       if (cfg.dma == -1 || cfg.irq == -1 || cfg.io_base == -1) {
+               printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
+               return -EINVAL;
+       }
+       
+       if (cfg_mpu.irq == -1 && cfg_mpu.io_base != -1) {
+               printk(KERN_ERR "MPU_IRQ must be specified if MPU_IO is set.\n");
+               return -EINVAL;
+       }
+       
+       if(spea != -1) {
                old_hardware = spea;
                printk(KERN_INFO "Forcing %s hardware support.\n",
                        spea?"new":"old");
        }       
-       if (probe_sscape(&mpu_config) == 0)
+       if (probe_sscape(&cfg_mpu) == 0)
                return -ENODEV;
 
-       attach_sscape(&mpu_config);
+       attach_sscape(&cfg_mpu);
        
-       mss = probe_ss_ms_sound(&config);
+       mss = probe_ss_ms_sound(&cfg);
 
        if (mss)
-               attach_ss_ms_sound(&config);
+               attach_ss_ms_sound(&cfg);
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_sscape(void)
 {
        if (mss)
-               unload_ss_ms_sound(&config);
+               unload_ss_ms_sound(&cfg);
        SOUND_LOCK_END;
-       unload_sscape(&mpu_config);
+       unload_sscape(&cfg_mpu);
+}
+
+module_init(init_sscape);
+module_exit(cleanup_sscape);
+
+#ifndef MODULE
+static int __init setup_sscape(char *str)
+{
+       /* io, irq, dma, mpu_io, mpu_irq */
+       int ints[6];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io      = ints[1];
+       irq     = ints[2];
+       dma     = ints[3];
+       mpu_io  = ints[4];
+       mpu_irq = ints[5];
+
+       return 1;
 }
 
-#endif /* MODULE */
+__setup("sscape=", setup_sscape);
+#endif
index 107c6ca9e641c1865b012884aef4c6010fce1775..d36da3f9cf0fd2954a981b12ae9a92fcaf60e6fb 100644 (file)
  *
  * Changes
  *     Alan Cox                Modularisation, cleanup.
+ *     Christoph Hellwig       Adapted to module_init/module_exit
  */
  
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/module.h>
 
 #include "sound_config.h"
 #include "sb.h"
 #include "sound_firmware.h"
 
-#include <linux/init.h>
-#include "trix_boot.h"
+#include "ad1848.h"
+#include "mpu401.h"
 
+#include "trix_boot.h"
 
 static int kilroy_was_here = 0;        /* Don't detect twice */
 static int sb_initialized = 0;
@@ -35,11 +38,7 @@ static int *trix_osp = NULL;
 
 static int mpu = 0;
 
-#ifdef TRIX_JOYSTICK
-static int joystick=1;
-#else
 static int joystick=0;
-#endif
 
 static unsigned char trix_read(int addr)
 {
@@ -137,7 +136,7 @@ static int trix_set_wss_port(struct address_info *hw_config)
  *      AudioTrix Pro
  */
 
-int probe_trix_wss(struct address_info *hw_config)
+static int __init probe_trix_wss(struct address_info *hw_config)
 {
        int ret;
 
@@ -202,8 +201,7 @@ int probe_trix_wss(struct address_info *hw_config)
        return ret;
 }
 
-void
-attach_trix_wss(struct address_info *hw_config)
+static void __init attach_trix_wss(struct address_info *hw_config)
 {
        static unsigned char interrupt_bits[12] = {
                0, 0, 0, 0, 0, 0, 0, 0x08, 0, 0x10, 0x18, 0x20
@@ -273,7 +271,7 @@ attach_trix_wss(struct address_info *hw_config)
        }
 }
 
-int probe_trix_sb(struct address_info *hw_config)
+static int __init probe_trix_sb(struct address_info *hw_config)
 {
 
        int tmp;
@@ -323,7 +321,7 @@ int probe_trix_sb(struct address_info *hw_config)
        return sb_dsp_detect(hw_config, 0, 0);
 }
 
-void attach_trix_sb(struct address_info *hw_config)
+static void __init attach_trix_sb(struct address_info *hw_config)
 {
        extern int sb_be_quiet;
        int old_quiet;
@@ -339,13 +337,13 @@ void attach_trix_sb(struct address_info *hw_config)
        sb_be_quiet = old_quiet;
 }
 
-void attach_trix_mpu(struct address_info *hw_config)
+static void __init attach_trix_mpu(struct address_info *hw_config)
 {
        hw_config->name = "AudioTrix Pro";
        attach_uart401(hw_config);
 }
 
-int probe_trix_mpu(struct address_info *hw_config)
+static int __init probe_trix_mpu(struct address_info *hw_config)
 {
        unsigned char conf;
        static char irq_bits[] = {
@@ -406,7 +404,7 @@ int probe_trix_mpu(struct address_info *hw_config)
        return probe_uart401(hw_config);
 }
 
-void unload_trix_wss(struct address_info *hw_config)
+static void __exit unload_trix_wss(struct address_info *hw_config)
 {
        int dma2 = hw_config->dma2;
 
@@ -424,31 +422,32 @@ void unload_trix_wss(struct address_info *hw_config)
        sound_unload_audiodev(hw_config->slots[0]);
 }
 
-void unload_trix_mpu(struct address_info *hw_config)
+static inline void __exit unload_trix_mpu(struct address_info *hw_config)
 {
        unload_uart401(hw_config);
 }
 
-void unload_trix_sb(struct address_info *hw_config)
+static inline void __exit unload_trix_sb(struct address_info *hw_config)
 {
        sb_dsp_unload(hw_config, mpu);
 }
 
-#ifdef MODULE
-
-int             io = -1;
-int             irq = -1;
-int             dma = -1;
-int             dma2 = -1;     /* Set this for modules that need it */
-
-int             sb_io = -1;
-int             sb_dma = -1;
-int             sb_irq = -1;
+static struct address_info cfg;
+static struct address_info cfg2;
+static struct address_info cfg_mpu;
 
-int             mpu_io = -1;
-int             mpu_irq = -1;
+static int sb = 0;
+static int fw_load;
 
-EXPORT_NO_SYMBOLS;
+static int __initdata io       = -1;
+static int __initdata irq      = -1;
+static int __initdata dma      = -1;
+static int __initdata dma2     = -1;   /* Set this for modules that need it */
+static int __initdata sb_io    = -1;
+static int __initdata sb_dma   = -1;
+static int __initdata sb_irq   = -1;
+static int __initdata mpu_io   = -1;
+static int __initdata mpu_irq  = -1;
 
 MODULE_PARM(io,"i");
 MODULE_PARM(irq,"i");
@@ -460,42 +459,33 @@ MODULE_PARM(sb_irq,"i");
 MODULE_PARM(mpu_io,"i");
 MODULE_PARM(mpu_irq,"i");
 MODULE_PARM(joystick, "i");
-struct address_info config;
-struct address_info sb_config;
-struct address_info mpu_config;
 
-static int      sb = 0;
-
-static int      fw_load;
-
-int init_module(void)
+static int __init init_trix(void)
 {
        printk(KERN_INFO "MediaTrix audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
 
-       if (io == -1 || dma == -1 || irq == -1)
-       {
+       cfg.io_base = io;
+       cfg.irq = irq;
+       cfg.dma = dma;
+       cfg.dma2 = dma2;
+
+       cfg2.io_base = sb_io;
+       cfg2.irq = sb_irq;
+       cfg2.dma = sb_dma;
+
+       cfg_mpu.io_base = mpu_io;
+       cfg_mpu.irq = mpu_irq;
+
+       if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
                printk(KERN_INFO "I/O, IRQ, DMA and type are mandatory\n");
                return -EINVAL;
        }
-       config.io_base = io;
-       config.irq = irq;
-       config.dma = dma;
-       config.dma2 = dma2;
-
-       sb_config.io_base = sb_io;
-       sb_config.irq = sb_irq;
-       sb_config.dma = sb_dma;
 
-       mpu_config.io_base = mpu_io;
-       mpu_config.irq = mpu_irq;
-
-       if (sb_io != -1 && (sb_irq == -1 || sb_dma == -1))
-       {
+       if (cfg2.io_base != -1 && (cfg2.irq == -1 || cfg2.dma == -1)) {
                printk(KERN_INFO "CONFIG_SB_IRQ and CONFIG_SB_DMA must be specified if SB_IO is set.\n");
                return -EINVAL;
        }
-       if (mpu_io != -1 && mpu_irq == -1)
-       {
+       if (cfg_mpu.io_base != -1 && cfg_mpu.irq == -1) {
                printk(KERN_INFO "CONFIG_MPU_IRQ must be specified if MPU_IO is set.\n");
                return -EINVAL;
        }
@@ -505,42 +495,65 @@ int init_module(void)
                trix_boot_len = mod_firmware_load("/etc/sound/trxpro.bin",
                                                    (char **) &trix_boot);
        }
-       if (!probe_trix_wss(&config))
+       if (!probe_trix_wss(&cfg))
                return -ENODEV;
-       attach_trix_wss(&config);
+       attach_trix_wss(&cfg);
 
        /*
         *    We must attach in the right order to get the firmware
         *      loaded up in time.
         */
 
-       if (sb_io != -1)
-       {
-               sb = probe_trix_sb(&sb_config);
+       if (cfg2.io_base != -1) {
+               sb = probe_trix_sb(&cfg2);
                if (sb)
-                       attach_trix_sb(&sb_config);
+                       attach_trix_sb(&cfg2);
        }
        
-       if (mpu_io != -1)
-       {
-               mpu = probe_trix_mpu(&mpu_config);
+       if (cfg_mpu.io_base != -1) {
+               mpu = probe_trix_mpu(&cfg_mpu);
                if (mpu)
-                       attach_trix_mpu(&mpu_config);
+                       attach_trix_mpu(&cfg_mpu);
        }
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_trix(void)
 {
        if (fw_load && trix_boot)
                vfree(trix_boot);
        if (sb)
-               unload_trix_sb(&sb_config);
+               unload_trix_sb(&cfg2);
        if (mpu)
-               unload_trix_mpu(&mpu_config);
-       unload_trix_wss(&config);
+               unload_trix_mpu(&cfg_mpu);
+       unload_trix_wss(&cfg);
        SOUND_LOCK_END;
 }
 
-#endif /* MODULE */
+module_init(init_trix);
+module_exit(cleanup_trix);
+
+#ifndef MODULE
+static int __init setup_trix (char *str)
+{
+       /* io, irq, dma, dma2, sb_io, sb_irq, sb_dma, mpu_io, mpu_irq */
+       int ints[9];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+
+       io      = ints[1];
+       irq     = ints[2];
+       dma     = ints[3];
+       dma2    = ints[4];
+       sb_io   = ints[5];
+       sb_irq  = ints[6];
+       sb_dma  = ints[6];
+       mpu_io  = ints[7];
+       mpu_irq = ints[8];
+
+       return 1;
+}
+
+__setup("trix=", setup_trix);
+#endif
index c4f105ef539139bc58e8e25230fcf86618f6c4cf..71721dd3e74d0358e560f9673beb0dd22e9e61a1 100644 (file)
@@ -2,8 +2,8 @@
  * sound/uart401.c
  *
  * MPU-401 UART driver (formerly uart401_midi.c)
- */
-/*
+ *
+ *
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  * for more info.
  *
  * Changes:
- *     Alan Cox        Reformatted, removed sound_mem usage, use normal Linux
- *                     interrupt allocation. Protect against bogus unload
- *                     Fixed to allow IRQ > 15
+ *     Alan Cox                Reformatted, removed sound_mem usage, use normal Linux
+ *                             interrupt allocation. Protect against bogus unload
+ *                             Fixed to allow IRQ > 15
+ *     Christoph Hellwig       Adapted to module_init/module_exit
  *
  * Status:
  *             Untested
  */
+
+#include <linux/init.h>
 #include <linux/module.h>
 
 #include "sound_config.h"
 #include "soundmodule.h"
 
+#include "mpu401.h"
+
 typedef struct uart401_devc
 {
        int             base;
@@ -177,21 +181,21 @@ static int uart401_out(int dev, unsigned char midi_byte)
        return 1;
 }
 
-static int uart401_start_read(int dev)
+static inline int uart401_start_read(int dev)
 {
        return 0;
 }
 
-static int uart401_end_read(int dev)
+static inline int uart401_end_read(int dev)
 {
        return 0;
 }
 
-static void uart401_kick(int dev)
+static inline void uart401_kick(int dev)
 {
 }
 
-static int uart401_buffer_status(int dev)
+static inline int uart401_buffer_status(int dev)
 {
        return 0;
 }
@@ -444,43 +448,60 @@ void unload_uart401(struct address_info *hw_config)
        sound_unload_mididev(hw_config->slots[4]);
 }
 
-#ifdef MODULE
+EXPORT_SYMBOL(attach_uart401);
+EXPORT_SYMBOL(probe_uart401);
+EXPORT_SYMBOL(unload_uart401);
+EXPORT_SYMBOL(uart401intr);
 
-int io = -1;
-int irq = -1;
+static struct address_info cfg_mpu;
+
+static int __initdata io = -1;
+static int __initdata irq = -1;
 
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
-struct address_info hw;
 
-int init_module(void)
+
+static int __init init_uart401(void)
 {
+       cfg_mpu.irq = irq;
+       cfg_mpu.io_base = io;
+
        /* Can be loaded either for module use or to provide functions
           to others */
-       if (io != -1 && irq != -1)
-       {
+       if (cfg_mpu.io_base != -1 && cfg_mpu.irq != -1) {
                printk(KERN_INFO "MPU-401 UART driver Copyright (C) Hannu Savolainen 1993-1997");
-               hw.irq = irq;
-               hw.io_base = io;
-               if (probe_uart401(&hw) == 0)
+               if (probe_uart401(&cfg_mpu) == 0)
                        return -ENODEV;
-               attach_uart401(&hw);
+               attach_uart401(&cfg_mpu);
        }
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_uart401(void)
 {
-       if (io != -1 && irq != -1)
-               unload_uart401(&hw);
-       /*  FREE SYMTAB */
+       if (cfg_mpu.io_base != -1 && cfg_mpu.irq != -1)
+               unload_uart401(&cfg_mpu);
        SOUND_LOCK_END;
 }
 
-#endif /* MODULE */
+module_init(init_uart401);
+module_exit(cleanup_uart401);
 
-EXPORT_SYMBOL(attach_uart401);
-EXPORT_SYMBOL(probe_uart401);
-EXPORT_SYMBOL(unload_uart401);
-EXPORT_SYMBOL(uart401intr);
+#ifndef MODULE
+static int __init setup_uart401(char *str)
+{
+       /* io, irq */
+       int ints[3];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+
+       io = ints[1];
+       irq = ints[2];
+       
+       return 1;
+}
+
+__setup("uart401=", setup_uart401);
+#endif
index b0548d513e63cf8d35085e3f1ba3ebd3bacc3585..6540df0f6bc468467ba05873e323efb57e0ea87e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * sound/uart6850.c
- */
-/*
+ *
+ *
  * Copyright (C) by Hannu Savolainen 1993-1997
  *
  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  * Extended by Alan Cox for Red Hat Software. Now a loadable MIDI driver.
  * 28/4/97 - (C) Copyright Alan Cox. Released under the GPL version 2.
  *
- * Alan Cox:   Updated for new modular code. Removed snd_* irq handling. Now
- *             uses native linux resources
+ * Alan Cox:           Updated for new modular code. Removed snd_* irq handling. Now
+ *                     uses native linux resources
+ * Christoph Hellwig:  Adapted to module_init/module_exit
  *
  *     Status: Testing required
  *
  */
+
+#include <linux/init.h>
 #include <linux/module.h>
 
 /* Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl:
@@ -199,26 +202,26 @@ static int uart6850_out(int dev, unsigned char midi_byte)
        return 1;
 }
 
-static int uart6850_command(int dev, unsigned char *midi_byte)
+static inline int uart6850_command(int dev, unsigned char *midi_byte)
 {
        return 1;
 }
 
-static int uart6850_start_read(int dev)
+static inline int uart6850_start_read(int dev)
 {
        return 0;
 }
 
-static int uart6850_end_read(int dev)
+static inline int uart6850_end_read(int dev)
 {
        return 0;
 }
 
-static void uart6850_kick(int dev)
+static inline void uart6850_kick(int dev)
 {
 }
 
-static int uart6850_buffer_status(int dev)
+static inline int uart6850_buffer_status(int dev)
 {
        return 0;               /*
                                 * No data in buffers
@@ -246,7 +249,7 @@ static struct midi_operations uart6850_operations =
 };
 
 
-void attach_uart6850(struct address_info *hw_config)
+static void __init attach_uart6850(struct address_info *hw_config)
 {
        int ok, timeout;
        unsigned long   flags;
@@ -292,7 +295,7 @@ static int reset_uart6850(void)
 }
 
 
-int probe_uart6850(struct address_info *hw_config)
+static int __init probe_uart6850(struct address_info *hw_config)
 {
        int ok = 0;
 
@@ -308,45 +311,58 @@ int probe_uart6850(struct address_info *hw_config)
        return ok;
 }
 
-void unload_uart6850(struct address_info *hw_config)
+static void __exit unload_uart6850(struct address_info *hw_config)
 {
        free_irq(hw_config->irq, NULL);
        sound_unload_mididev(hw_config->slots[4]);
 }
 
+static struct address_info cfg_mpu;
 
-#ifdef MODULE
-
-int io = -1;
-int irq = -1;
+static int __initdata io = -1;
+static int __initdata irq = -1;
 
 MODULE_PARM(io,"i");
 MODULE_PARM(irq,"i");
 
-EXPORT_NO_SYMBOLS;
-
-struct address_info cfg;
-
-int init_module(void)
+static int __init init_uart6850(void)
 {
-       if (io == -1 || irq == -1)
-       {
+       cfg_mpu.io_base = io;
+       cfg_mpu.irq = irq;
+
+       if (cfg_mpu.io_base == -1 || cfg_mpu.irq == -1) {
                printk(KERN_INFO "uart6850: irq and io must be set.\n");
                return -EINVAL;
        }
-       cfg.io_base = io;
-       cfg.irq = irq;
 
-       if (probe_uart6850(&cfg))
+       if (probe_uart6850(&cfg_mpu))
                return -ENODEV;
 
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_uart6850(void)
 {
-       unload_uart6850(&cfg);
+       unload_uart6850(&cfg_mpu);
        SOUND_LOCK_END;
 }
-#endif /* MODULE */
+
+module_init(init_uart6850);
+module_exit(cleanup_uart6850);
+
+#ifndef MODULE
+static int __init setup_uart6850(char *str)
+{
+       /* io, irq */
+       int ints[3];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io = ints[1];
+       irq = ints[2];
+
+       return 1;
+}
+__setup("uart6850=", setup_uart6850);
+#endif
index 0cab16199f050ae9865d4675585d1c8c4ca80b0d..9c18ff5c8e463a8969382add0d44954609014be3 100644 (file)
  *
  * Changes
  *     Alan Cox                Modularisation, changed memory allocations
+ *     Christoph Hellwig       Adapted to module_init/module_exit
  *
  * Status
  *     Untested
  */
 
+#include <linux/init.h>
 #include <linux/module.h>
 
 #include "sound_config.h"
@@ -29,28 +31,6 @@ static vmidi_devc *v_devc[2] = { NULL, NULL};
 static int midi1,midi2;
 static void *midi_mem = NULL;
 
-#ifdef MODULE
-
-static struct address_info config;     /* dummy */
-
-int init_module(void)
-{
-       printk("MIDI Loopback device driver\n");
-       if (!probe_v_midi(&config))
-               return -ENODEV;
-       attach_v_midi(&config);
-       SOUND_LOCK;
-       return 0;
-}
-
-void cleanup_module(void)
-{
-       unload_v_midi(&config);
-       SOUND_LOCK_END;
-}
-
-#endif /* MODULE */
-
 /*
  * The DSP channel can be used either for input or output. Variable
  * 'sb_irq_mode' will be set when the program calls read or write first time
@@ -126,7 +106,7 @@ static int v_midi_out (int dev, unsigned char midi_byte)
        return 1;
 }
 
-static int v_midi_start_read (int dev)
+static inline int v_midi_start_read (int dev)
 {
        return 0;
 }
@@ -143,7 +123,7 @@ static int v_midi_end_read (int dev)
 
 /* why -EPERM and not -EINVAL?? */
 
-static int v_midi_ioctl (int dev, unsigned cmd, caddr_t arg)
+static inline int v_midi_ioctl (int dev, unsigned cmd, caddr_t arg)
 {
        return -EPERM;
 }
@@ -201,7 +181,7 @@ struct vmidi_memory
        struct vmidi_devc v_ops[2];
 };
 
-void attach_v_midi (struct address_info *hw_config)
+static void __init attach_v_midi (struct address_info *hw_config)
 {
        struct vmidi_memory *m;
        /* printk("Attaching v_midi device.....\n"); */
@@ -282,15 +262,38 @@ void attach_v_midi (struct address_info *hw_config)
        /* printk("Attached v_midi device\n"); */
 }
 
-int probe_v_midi(struct address_info *hw_config)
+static inline int __init probe_v_midi(struct address_info *hw_config)
 {
        return(1);      /* always OK */
 }
 
 
-void unload_v_midi(struct address_info *hw_config)
+static void __exit unload_v_midi(struct address_info *hw_config)
 {
        sound_unload_mididev(midi1);
        sound_unload_mididev(midi2);
        kfree(midi_mem);
 }
+
+static struct address_info cfg; /* dummy */
+
+static int __init init_vmidi(void)
+{
+       printk("MIDI Loopback device driver\n");
+       if (!probe_v_midi(&cfg))
+               return -ENODEV;
+       attach_v_midi(&cfg);
+
+       SOUND_LOCK;
+
+       return 0;
+}
+
+static void __exit cleanup_vmidi(void)
+{
+       unload_v_midi(&cfg);
+       SOUND_LOCK_END;
+}
+
+module_init(init_vmidi);
+module_exit(cleanup_vmidi);
index cee2e7b0ac9375a315560bff179ddd52825acc30..5745a9037138ee22c4eb781d5a8108ddd4f809a9 100644 (file)
@@ -33,6 +33,7 @@
 #include "soundmodule.h"
 #include "sb.h"
 #include "ac97.h"
+#include "mpu401.h"
 
 #ifndef SOUND_LOCK
 #define SOUND_LOCK do {} while (0)
index 578d4dff9911cdab3d403644c513171149a51d2d..9cebcc324aa0c1221041af741f297e7ea2952fb9 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 
@@ -412,7 +413,7 @@ void vidc_update_filler(int format, int channels)
        }
 }
 
-void attach_vidc(struct address_info *hw_config)
+static void __init attach_vidc(struct address_info *hw_config)
 {
        char name[32];
        int i, adev;
@@ -486,7 +487,7 @@ audio_failed:
        return;
 }
 
-int probe_vidc(struct address_info *hw_config)
+static int __init probe_vidc(struct address_info *hw_config)
 {
        hw_config->irq          = IRQ_DMAS0;
        hw_config->dma          = DMA_VIRTUAL_SOUND;
@@ -496,7 +497,7 @@ int probe_vidc(struct address_info *hw_config)
        return 1;
 }
 
-void unload_vidc(struct address_info *hw_config)
+static void __exit unload_vidc(struct address_info *hw_config)
 {
        int i, adev = vidc_adev;
 
@@ -516,27 +517,27 @@ void unload_vidc(struct address_info *hw_config)
        }
 }
 
-#ifdef MODULE
-static struct address_info config;
+static struct address_info cfg;
 /*
  * Note! Module use count is handled by SOUNDLOCK/SOUND_LOCK_END
  */
 
-int init_module(void)
+static int __init init_vidc(void)
 {
-       if (probe_vidc(&config) == 0)
+       if (probe_vidc(&cfg) == 0)
                return -ENODEV;
 
        SOUND_LOCK;
-       attach_vidc(&config);
+       attach_vidc(&cfg);
 
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_vidc(void)
 {
-       unload_vidc(&config);
+       unload_vidc(&cfg);
        SOUND_LOCK_END;
 }
 
-#endif
+module_init(init_vidc);
+module_exit(cleanup_vidc);
index 905b9cff6ab64c5d6ebc8165ea2906da18cdf2b1..d1631defd01de603f2410c855b2e860598bb2b22 100644 (file)
@@ -6,9 +6,8 @@
  *
  * Cleaned up and integrated into 2.1 by Russell King (rmk@arm.linux.org.uk)
  * and Pat Beirne (patb@corel.ca)
- */
-
-/*
+ *
+ *
  * Copyright (C) by Rebel.com 1998-1999
  *
  * RWA010 specs received under NDA from Rockwell
@@ -31,6 +30,7 @@
 #define debug_flg (0)
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
@@ -1281,8 +1281,7 @@ nomem:
        return -1;
 }
 
-int
-probe_waveartist(struct address_info *hw_config)
+static int __init probe_waveartist(struct address_info *hw_config)
 {
        wavnc_info *devc = &adev_info[nr_waveartist_devs];
 
@@ -1316,8 +1315,7 @@ probe_waveartist(struct address_info *hw_config)
        return 1;
 }
 
-void
-attach_waveartist(struct address_info *hw)
+static void __init attach_waveartist(struct address_info *hw)
 {
        wavnc_info *devc = &adev_info[nr_waveartist_devs];
 
@@ -1359,8 +1357,7 @@ attach_waveartist(struct address_info *hw)
        }
 }
 
-void
-unload_waveartist(struct address_info *hw)
+static void __exit unload_waveartist(struct address_info *hw)
 {
        wavnc_info *devc = NULL;
        int i;
@@ -1757,45 +1754,63 @@ vnc_private_ioctl(int dev, unsigned int cmd, caddr_t arg)
        return -ENOIOCTLCMD;
 }
 
-#ifdef MODULE
+static struct address_info cfg;
+
+static int attached;
+
+static int __initdata io;
+static int __initdata irq;
+static int __initdata dma;
+static int __initdata dma2;
+
 
 MODULE_PARM(io, "i");          /* IO base */
 MODULE_PARM(irq, "i");         /* IRQ */
 MODULE_PARM(dma, "i");         /* DMA */
 MODULE_PARM(dma2, "i");                /* DMA2 */
 
-static int io   = CONFIG_WAVEARTIST_BASE;
-static int irq  = CONFIG_WAVEARTIST_IRQ;
-static int dma  = CONFIG_WAVEARTIST_DMA;
-static int dma2 = CONFIG_WAVEARTIST_DMA2;
-
-static int attached;
-
-static struct address_info hw_config;
-
-int init_module(void)
+static int __init init_waveartist(void)
 {
-       hw_config.io_base = io;
-       hw_config.irq = irq;
-       hw_config.dma = dma;
-       hw_config.dma2 = dma2;
+       cfg.io_base = io;
+       cfg.irq = irq;
+       cfg.dma = dma;
+       cfg.dma2 = dma2;
 
-       if (!probe_waveartist(&hw_config))
+       if (!probe_waveartist(&cfg))
                return -ENODEV;
 
-       attach_waveartist(&hw_config);
+       attach_waveartist(&cfg);
        attached = 1;
 
        SOUND_LOCK;
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit cleanup_waveartist(void)
 {
        if (attached) {
                SOUND_LOCK_END;
-
-               unload_waveartist(&hw_config);
+               unload_waveartist(&cfg);
        }
 }
+
+module_init(init_waveartist);
+module_exit(cleanup_waveartist);
+
+#ifndef MODULE
+static int __init setup_waveartist(char *str)
+{
+       /* io, irq, dma, dma2 */
+       int ints[5];
+       
+       str = get_options(str, ARRAY_SIZE(ints), ints);
+       
+       io      = ints[1];
+       irq     = ints[2];
+       dma     = ints[3];
+       dma16   = ints[4];
+
+       return 1;
+}
+__setup("waveartist=", setup_waveartist);
 #endif
index 2967fdf18b7ba62c6c21b730cbeff1b83d977016..af1f8970d09839df849a8a8eec45a74ef10bce04 100644 (file)
@@ -65,6 +65,7 @@
 #include <linux/module.h>
 
 #include <linux/kernel.h>
+#include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/ptrace.h>
 #include <linux/fcntl.h>
@@ -128,10 +129,6 @@ static int (*midi_load_patch) (int devno, int format, const char *addr,
                               int offs, int count, int pmgr_flag) = NULL;
 #endif OSS_SUPPORT_SEQ
 
-/* This is meant to work as a module */
-
-#if defined(CONFIG_SOUND_WAVEFRONT_MODULE) && defined(MODULE)
-
 /* if WF_DEBUG not defined, no run-time debugging messages will
    be available via the debug flag setting. Given the current
    beta state of the driver, this will remain set until a future 
@@ -2144,25 +2141,23 @@ static struct synth_operations wavefront_operations =
 
 #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_STATIC_INSTALL
 
-void attach_wavefront (struct address_info *hw_config)
-
+static void __init attach_wavefront (struct address_info *hw_config)
 {
     (void) install_wavefront ();
 }
 
-int probe_wavefront (struct address_info *hw_config)
-
+static int __init probe_wavefront (struct address_info *hw_config)
 {
     return !detect_wavefront (hw_config->irq, hw_config->io_base);
 }
 
-void unload_wavefront (struct address_info *hw_config) 
+static void __exit unload_wavefront (struct address_info *hw_config) 
 {
     (void) uninstall_wavefront ();
 }
 
 #endif OSS_SUPPORT_STATIC_INSTALL
-\f
+
 /***********************************************************************/
 /* WaveFront: Linux modular sound kernel installation interface        */
 /***********************************************************************/
@@ -2814,8 +2809,7 @@ wavefront_do_reset (int atboot)
        return 1;
 }
 
-static int
-wavefront_init (int atboot)
+static int __init wavefront_init (int atboot)
 {
        int samples_are_from_rom;
 
@@ -2884,9 +2878,7 @@ static int __init install_wavefront (void)
        return dev.oss_dev;
 }
 
-void
-uninstall_wavefront (void)
-
+static void __exit uninstall_wavefront (void)
 {
        /* the first two i/o addresses are freed by the wf_mpu code */
        release_region (dev.base+2, 6);
@@ -2938,7 +2930,7 @@ wffx_idle (void)
        return (1);
 }
 
-static int __init detect_wffx (void)
+int __init detect_wffx (void)
 {
        /* This is a crude check, but its the best one I have for now.
           Certainly on the Maui and the Tropez, wffx_idle() will
@@ -2954,7 +2946,7 @@ static int __init detect_wffx (void)
        return 0;
 }      
 
-static int __init attach_wffx (void)
+int __init attach_wffx (void)
 {
        if ((dev.fx_mididev = sound_alloc_mididev ()) < 0) {
                printk (KERN_WARNING LOGNAME "cannot install FX Midi driver\n");
@@ -2964,7 +2956,7 @@ static int __init attach_wffx (void)
        return 0;
 }
 
-static void
+void
 wffx_mute (int onoff)
     
 {
@@ -3087,9 +3079,7 @@ wffx_ioctl (wavefront_fx_info *r)
    a somewhat "algorithmic" approach.
 */
 
-static int
-wffx_init (void)
-
+static int wffx_init (void)
 {
        int i;
        int j;
@@ -3543,18 +3533,15 @@ wffx_init (void)
        return (0);
 }
 
-EXPORT_NO_SYMBOLS;
-
-int io = -1;
-int irq = -1;
+static int io = -1;
+static int irq = -1;
 
 MODULE_AUTHOR      ("Paul Barton-Davis <pbd@op.net>");
 MODULE_DESCRIPTION ("Turtle Beach WaveFront Linux Driver");
 MODULE_PARM        (io,"i");
 MODULE_PARM        (irq,"i");
 
-int init_module (void)
-
+static int __init init_wavfront (void)
 {
        printk ("Turtle Beach WaveFront Driver\n"
                "Copyright (C) by Hannu Solvainen, "
@@ -3585,14 +3572,11 @@ int init_module (void)
        return 0;
 }
 
-void cleanup_module (void)
-
+static void __exit cleanup_wavfront (void)
 {
        uninstall_wavefront ();
-
        SOUND_LOCK_END;
 }
 
-#endif CONFIG_SOUND_WAVEFRONT_MODULE && MODULE
-
-
+module_init(init_wavfront);
+module_exit(cleanup_wavfront);
index 45db0f8b1a8afe98a54ca2141b1ac4ab28460314..4b0708ec7f31e6da9790ab5aa45d0ff2e5146ce0 100644 (file)
@@ -42,7 +42,7 @@
  * Copyright (C) by Paul Barton-Davis 1998
  * Some portions of this file are derived from work that is:
  *
- *    Copyright (C) by Hannu Savolainen 1993-1996
+ *    CopyriGht (C) by Hannu Savolainen 1993-1996
  *
  * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  * Version 2 (June 1991). See the "COPYING" file distributed with this software
@@ -56,7 +56,7 @@
 
 #include <linux/wavefront.h>
 
-#if defined(CONFIG_SOUND_WAVEFRONT_MODULE) && defined(MODULE)
+#ifdef MODULE
 
 struct wf_mpu_config {
        int             base;
@@ -87,37 +87,27 @@ static void start_uart_mode (void);
 #define        MPU_ACK         0xFE
 #define        UART_MODE_ON    0x3F
 
-static inline int 
-wf_mpu_status (void)
-
+static inline int wf_mpu_status (void)
 {
        return inb (STATPORT (phys_dev));
 }
 
-static inline int 
-input_avail (void)
-
+static inline int input_avail (void)
 {
        return !(wf_mpu_status() & INPUT_AVAIL);
 }
 
-static inline int
-output_ready (void)
-
+static inline int output_ready (void)
 {
        return !(wf_mpu_status() & OUTPUT_READY);
 }
 
-static inline int 
-read_data (void)
-
+static inline int  read_data (void)
 {
        return inb (DATAPORT (phys_dev));
 }
 
-static inline void 
-write_data (unsigned char byte)
-
+static inline void write_data (unsigned char byte)
 {
        outb (byte, DATAPORT (phys_dev));
 }
@@ -536,28 +526,22 @@ wf_mpu_out (int dev, unsigned char midi_byte)
        return 1;
 }
 
-static int
-wf_mpu_start_read (int dev)
-{
+static inline int wf_mpu_start_read (int dev) {
        return 0;
 }
 
-static int
-wf_mpu_end_read (int dev)
-{
+static inline int wf_mpu_end_read (int dev) {
        return 0;
 }
 
-static int
-wf_mpu_ioctl (int dev, unsigned cmd, caddr_t arg)
+static int wf_mpu_ioctl (int dev, unsigned cmd, caddr_t arg)
 {
        printk (KERN_WARNING
                "WF-MPU: Intelligent mode not supported by hardware.\n");
        return -(EINVAL);
 }
 
-static int
-wf_mpu_buffer_status (int dev)
+static int wf_mpu_buffer_status (int dev)
 {
        return 0;
 }
@@ -901,31 +885,4 @@ start_uart_mode (void)
 
        restore_flags (flags);
 }
-
-#ifdef OSS_SUPPORT
-
-int
-probe_wf_mpu (struct address_info *hw_config)
-
-{
-       return !detect_wf_mpu (hw_config->irq, hw_config->io_base);
-}
-
-void
-attach_wf_mpu (struct address_info *hw_config)
-
-{
-       (void) install_wf_mpu ();
-}
-
-void
-unload_wf_mpu (void)
-{
-       uninstall_wf_mpu ();
-}
-
-#endif OSS_SUPPORT
-
-#endif CONFIG_SOUND_WAVEFRONT_MODULE_AND_MODULE
-
-
+#endif
index b1f889e89b176320d18e229caf07757a97dfd9f7..afcd5d1057708769d5808ed23a5a79259cbef177 100644 (file)
@@ -134,6 +134,7 @@ struct acm {
        struct tty_struct *tty;                         /* the coresponding tty */
        struct urb ctrlurb, readurb, writeurb;          /* urbs */
        struct acm_line line;                           /* line coding (bits, stop, parity) */
+       struct tq_struct tqueue;                        /* task queue for line discipline waking up */
        unsigned int ctrlin;                            /* input control lines (DCD, DSR, RI, break, overruns) */
        unsigned int ctrlout;                           /* output control lines (DTR, RTS) */
        unsigned int writesize;                         /* max packet size for the output bulk endpoint */
@@ -251,13 +252,22 @@ static void acm_read_bulk(struct urb *urb)
 static void acm_write_bulk(struct urb *urb)
 {
        struct acm *acm = (struct acm *)urb->context;
-       struct tty_struct *tty = acm->tty;
 
        if (!ACM_READY(acm)) return;
 
        if (urb->status)
                dbg("nonzero write bulk status received: %d", urb->status);
 
+       queue_task(&acm->tqueue, &tq_scheduler);
+}
+
+static void acm_softint(void *private)
+{
+       struct acm *acm = private;
+       struct tty_struct *tty = acm->tty;
+
+       if (!ACM_READY(acm)) return;
+
        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
                (tty->ldisc.write_wakeup)(tty);
 
@@ -535,6 +545,9 @@ static void *acm_probe(struct usb_device *dev, unsigned int ifnum)
                acm->minor = minor;
                acm->dev = dev;
 
+               acm->tqueue.routine = acm_softint;
+               acm->tqueue.data = acm;
+
                if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
                        err("out of memory");
                        kfree(acm);
diff --git a/drivers/usb/keyspan_pda_fw.h b/drivers/usb/keyspan_pda_fw.h
new file mode 100644 (file)
index 0000000..5366c0a
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * keyspan_pda_fw.h
+ *
+ * Generated from keyspan_pda.s by ezusb_convert.pl
+ * This file is presumed to be under the same copyright as the source file
+ * from which it was derived.
+ */
+
+static const struct ezusb_hex_record keyspan_pda_firmware[] = {
+{ 0x0000,      3,      {0x02, 0x02, 0x00} },
+{ 0x0023,      4,      {0x02, 0x05, 0x5f, 0x00} },
+{ 0x0043,      4,      {0x02, 0x01, 0x00, 0x00} },
+{ 0x0030,      5,      {0x00, 0x00, 0x00, 0x00, 0x00} },
+{ 0x0100,      16,     {0x02, 0x02, 0x96, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00} },
+{ 0x0110,      16,     {0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00} },
+{ 0x0120,      16,     {0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x04, 0x61, 0x00, 0x02, 0x04, 0x89, 0x00} },
+{ 0x0200,      16,     {0x75, 0x81, 0x5e, 0xe4, 0xf5, 0x32, 0xf5, 0x33, 0xf5, 0x30, 0xf5, 0x31, 0xf5, 0x34, 0xc2, 0x00} },
+{ 0x0210,      16,     {0xc2, 0x01, 0xa9, 0x00, 0x74, 0xfe, 0x90, 0x10, 0x00, 0xf0, 0xa3, 0xd9, 0xfc, 0x74, 0xfd, 0x90} },
+{ 0x0220,      16,     {0x11, 0x00, 0xf0, 0xa3, 0xd9, 0xfc, 0x74, 0x02, 0x90, 0x7f, 0x9d, 0xf0, 0x74, 0x00, 0x90, 0x7f} },
+{ 0x0230,      16,     {0x97, 0xf0, 0x74, 0x86, 0x90, 0x7f, 0x9e, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0x03, 0xf0, 0x90, 0x7f} },
+{ 0x0240,      16,     {0xaf, 0xe0, 0xd2, 0xe0, 0xf0, 0x74, 0x01, 0x90, 0x7f, 0xab, 0xf0, 0x90, 0x7f, 0xae, 0xf0, 0x90} },
+{ 0x0250,      16,     {0x7f, 0xac, 0x74, 0x04, 0xf0, 0x90, 0x7f, 0xad, 0x74, 0x04, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x74} },
+{ 0x0260,      16,     {0x84, 0x90, 0x7f, 0x98, 0xf0, 0x74, 0x00, 0xf5, 0x98, 0x75, 0xc8, 0x30, 0x7b, 0x05, 0x91, 0x20} },
+{ 0x0270,      16,     {0xd2, 0xca, 0x75, 0x98, 0x50, 0xd2, 0xe8, 0xd2, 0xaf, 0xd2, 0xac, 0x74, 0x00, 0xf5, 0x86, 0x90} },
+{ 0x0280,      16,     {0x7f, 0xd6, 0x74, 0x02, 0xf0, 0x79, 0x2e, 0x7a, 0x00, 0x7b, 0x00, 0xdb, 0xfe, 0xda, 0xfa, 0xd9} },
+{ 0x0290,      16,     {0xf6, 0x74, 0x06, 0xf0, 0x80, 0xfe, 0xc0, 0x86, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x84, 0xc0, 0x85} },
+{ 0x02a0,      16,     {0xc0, 0xe0, 0xe5, 0x91, 0xc2, 0xe4, 0xf5, 0x91, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0x90, 0x7f} },
+{ 0x02b0,      16,     {0xe8, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb, 0xa3, 0xe0, 0xfc, 0xe9, 0x54, 0x60, 0xb4} },
+{ 0x02c0,      16,     {0x00, 0x03, 0x02, 0x03, 0x39, 0xb4, 0x40, 0x6e, 0xba, 0x00, 0x0b, 0x12, 0x04, 0x20, 0x40, 0x03} },
+{ 0x02d0,      16,     {0x02, 0x04, 0x02, 0x02, 0x04, 0x0a, 0xba, 0x01, 0x03, 0x02, 0x04, 0x0a, 0xba, 0x02, 0x03, 0x02} },
+{ 0x02e0,      16,     {0x04, 0x0a, 0xba, 0x03, 0x03, 0x02, 0x04, 0x44, 0xba, 0x04, 0x1e, 0xbb, 0x00, 0x0a, 0x90, 0x7f} },
+{ 0x02f0,      16,     {0x95, 0xe0, 0x44, 0x02, 0xf0, 0x02, 0x04, 0x02, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfd, 0xf0, 0x90} },
+{ 0x0300,      16,     {0x7f, 0x95, 0xe0, 0x54, 0xfd, 0xf0, 0x02, 0x04, 0x02, 0xba, 0x05, 0x03, 0x02, 0x04, 0x0a, 0xba} },
+{ 0x0310,      16,     {0x06, 0x19, 0xbb, 0x00, 0x08, 0xe5, 0x33, 0xd3, 0x95, 0x32, 0x02, 0x03, 0xde, 0xbb, 0x01, 0x08} },
+{ 0x0320,      16,     {0xe5, 0x32, 0xc3, 0x95, 0x33, 0x02, 0x03, 0xde, 0x02, 0x04, 0x0a, 0xba, 0x07, 0x05, 0x8b, 0x34} },
+{ 0x0330,      16,     {0x02, 0x04, 0x02, 0x02, 0x04, 0x0a, 0x02, 0x04, 0x0a, 0xba, 0x00, 0x20, 0xb9, 0x80, 0x10, 0x90} },
+{ 0x0340,      16,     {0x7f, 0x00, 0xe4, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x04, 0x02, 0xb9} },
+{ 0x0350,      16,     {0x82, 0x02, 0x80, 0xeb, 0xb9, 0x81, 0x02, 0x80, 0xe6, 0x02, 0x04, 0x0a, 0xba, 0x01, 0x0f, 0xbb} },
+{ 0x0360,      16,     {0x00, 0x03, 0x02, 0x04, 0x0a, 0xbb, 0x01, 0x03, 0x02, 0x04, 0x02, 0x02, 0x04, 0x0a, 0xba, 0x03} },
+{ 0x0370,      16,     {0x0f, 0xbb, 0x00, 0x03, 0x02, 0x04, 0x0a, 0xbb, 0x01, 0x03, 0x02, 0x04, 0x02, 0x02, 0x04, 0x0a} },
+{ 0x0380,      16,     {0xba, 0x06, 0x56, 0xbc, 0x01, 0x0f, 0x90, 0x7f, 0xd4, 0x74, 0x06, 0xf0, 0x90, 0x7f, 0xd5, 0x74} },
+{ 0x0390,      16,     {0x12, 0xf0, 0x02, 0x04, 0x02, 0xbc, 0x02, 0x12, 0xbb, 0x00, 0x6f, 0x90, 0x7f, 0xd4, 0x74, 0x06} },
+{ 0x03a0,      16,     {0xf0, 0x90, 0x7f, 0xd5, 0x74, 0x24, 0xf0, 0x02, 0x04, 0x02, 0xbc, 0x03, 0x29, 0x74, 0x04, 0xc3} },
+{ 0x03b0,      16,     {0x9b, 0x40, 0x57, 0x60, 0x55, 0xeb, 0x2b, 0x90, 0x06, 0x44, 0x25, 0x82, 0xf5, 0x82, 0x74, 0x00} },
+{ 0x03c0,      16,     {0x35, 0x83, 0xf5, 0x83, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa, 0x90, 0x7f, 0xd4, 0xe9, 0xf0, 0x90, 0x7f} },
+{ 0x03d0,      16,     {0xd5, 0xea, 0xf0, 0x02, 0x04, 0x02, 0x02, 0x04, 0x0a, 0xba, 0x08, 0x0f, 0x74, 0x01, 0x90, 0x7f} },
+{ 0x03e0,      16,     {0x00, 0xf0, 0x74, 0x01, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x04, 0x02, 0xba, 0x09, 0x03, 0x02, 0x04} },
+{ 0x03f0,      16,     {0x02, 0xba, 0x0a, 0x05, 0x74, 0x00, 0x02, 0x03, 0xde, 0xba, 0x0b, 0x03, 0x02, 0x04, 0x02, 0x02} },
+{ 0x0400,      16,     {0x04, 0x0a, 0x90, 0x7f, 0xb4, 0x74, 0x02, 0xf0, 0x80, 0x09, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01} },
+{ 0x0410,      16,     {0xf0, 0x80, 0x00, 0xd0, 0xe0, 0xd0, 0x85, 0xd0, 0x84, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0x86, 0x32} },
+{ 0x0420,      16,     {0xeb, 0x20, 0xe7, 0x1e, 0xc3, 0x94, 0x0a, 0x50, 0x19, 0xeb, 0x23, 0x24, 0xfe, 0xf5, 0x82, 0x74} },
+{ 0x0430,      16,     {0x05, 0x34, 0x00, 0xf5, 0x83, 0xe0, 0xf5, 0xcb, 0xf5, 0xcd, 0xa3, 0xe0, 0xf5, 0xca, 0xf5, 0xcc} },
+{ 0x0440,      16,     {0xc3, 0x22, 0xd3, 0x22, 0xb9, 0x41, 0x11, 0xeb, 0x64, 0xff, 0x54, 0x84, 0xfb, 0x90, 0x7f, 0x98} },
+{ 0x0450,      16,     {0xe0, 0x54, 0x7b, 0x4b, 0xf0, 0x02, 0x04, 0x02, 0x90, 0x7f, 0x9b, 0xe0, 0x64, 0xff, 0x02, 0x03} },
+{ 0x0460,      16,     {0xde, 0xc0, 0x86, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x84, 0xc0, 0x85, 0xc0, 0xe0, 0xe5, 0x91, 0xc2} },
+{ 0x0470,      16,     {0xe4, 0xf5, 0x91, 0x90, 0x7f, 0xa9, 0x74, 0x04, 0xf0, 0x12, 0x05, 0xa0, 0xd0, 0xe0, 0xd0, 0x85} },
+{ 0x0480,      16,     {0xd0, 0x84, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0x86, 0x32, 0xc0, 0x86, 0xc0, 0x82, 0xc0, 0x83, 0xc0} },
+{ 0x0490,      16,     {0x84, 0xc0, 0x85, 0xc0, 0xe0, 0xe5, 0x91, 0xc2, 0xe4, 0xf5, 0x91, 0x90, 0x7f, 0xaa, 0x74, 0x04} },
+{ 0x04a0,      16,     {0xf0, 0x90, 0x7f, 0xc9, 0xe0, 0xf9, 0xe4, 0xf5, 0x86, 0x90, 0x7d, 0xc0, 0x75, 0x85, 0x10, 0x85} },
+{ 0x04b0,      16,     {0x32, 0x84, 0xe0, 0x05, 0x86, 0x05, 0x84, 0xf0, 0xe5, 0x84, 0xb5, 0x33, 0x02, 0x80, 0x09, 0x05} },
+{ 0x04c0,      16,     {0x32, 0x05, 0x86, 0xa3, 0xd9, 0xec, 0x80, 0x00, 0x90, 0x7f, 0xc9, 0xf0, 0xb1, 0x31, 0xd0, 0xe0} },
+{ 0x04d0,      16,     {0xd0, 0x85, 0xd0, 0x84, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0x86, 0x32, 0xe4, 0xf5, 0x86, 0x90, 0x7f} },
+{ 0x04e0,      16,     {0xbc, 0xe0, 0x20, 0xe1, 0x4b, 0x90, 0x7d, 0x00, 0xe5, 0x32, 0xf0, 0xa3, 0xe5, 0x33, 0xf0, 0xa3} },
+{ 0x04f0,      16,     {0xe5, 0x30, 0xf0, 0xa3, 0xe5, 0x31, 0xf0, 0xa3, 0xe4, 0x30, 0x00, 0x01, 0x04, 0xf0, 0xa3, 0x05} },
+{ 0x0500,      16,     {0x86, 0x90, 0x10, 0x00, 0x79, 0x10, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xd9, 0xf6} },
+{ 0x0510,      16,     {0x05, 0x86, 0x74, 0xfc, 0xf0, 0xa3, 0x05, 0x86, 0x90, 0x11, 0x00, 0x79, 0x10, 0xe0, 0xa3, 0x05} },
+{ 0x0520,      16,     {0x86, 0xf0, 0xa3, 0x05, 0x86, 0xd9, 0xf6, 0xe4, 0xf5, 0x86, 0x90, 0x7f, 0xbd, 0x74, 0x26, 0xf0} },
+{ 0x0530,      16,     {0x22, 0x20, 0x00, 0x13, 0xe5, 0x32, 0xb5, 0x33, 0x01, 0x22, 0x05, 0x33, 0x75, 0x83, 0x10, 0x85} },
+{ 0x0540,      16,     {0x33, 0x82, 0xe0, 0xf5, 0x99, 0xd2, 0x00, 0x74, 0x00, 0xb5, 0x34, 0x01, 0x22, 0xe5, 0x33, 0xd3} },
+{ 0x0550,      16,     {0x95, 0x32, 0xc3, 0x95, 0x34, 0x40, 0xf5, 0x75, 0x34, 0x00, 0xd2, 0x01, 0x02, 0x05, 0xa0, 0xc0} },
+{ 0x0560,      16,     {0x86, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0x84, 0xc0, 0x85, 0xc0, 0xe0, 0x30, 0x99, 0x07, 0xc2, 0x99} },
+{ 0x0570,      16,     {0xc2, 0x00, 0x12, 0x05, 0x34, 0x30, 0x98, 0x05, 0x12, 0x05, 0x8a, 0xc2, 0x98, 0xd0, 0xe0, 0xd0} },
+{ 0x0580,      16,     {0x85, 0xd0, 0x84, 0xd0, 0x83, 0xd0, 0x82, 0xd0, 0x86, 0x32, 0x75, 0x83, 0x11, 0x85, 0x30, 0x82} },
+{ 0x0590,      16,     {0x05, 0x82, 0xe5, 0x99, 0xf0, 0xe5, 0x82, 0xb5, 0x31, 0x01, 0x22, 0x05, 0x30, 0xb1, 0xa0, 0x22} },
+{ 0x05a0,      16,     {0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x38, 0x20, 0x01, 0x36, 0xe5, 0x30, 0xb5, 0x31, 0x01, 0x22} },
+{ 0x05b0,      16,     {0xe4, 0xf5, 0x86, 0x75, 0x83, 0x11, 0x05, 0x86, 0x90, 0x7e, 0x00, 0xf0, 0xa3, 0x05, 0x86, 0x79} },
+{ 0x05c0,      16,     {0x01, 0xe5, 0x30, 0xb5, 0x31, 0x02, 0x80, 0x10, 0x05, 0x31, 0x85, 0x31, 0x82, 0xe0, 0x05, 0x86} },
+{ 0x05d0,      16,     {0xf0, 0xa3, 0x05, 0x86, 0x09, 0xb9, 0x40, 0xe9, 0x90, 0x7f, 0xb9, 0xe9, 0x60, 0x01, 0xf0, 0x22} },
+{ 0x05e0,      16,     {0xc2, 0x01, 0xe4, 0xf5, 0x86, 0x90, 0x7e, 0x00, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x02, 0xf0, 0x90} },
+{ 0x05f0,      16,     {0x7f, 0xb9, 0xf0, 0x22, 0xc2, 0x99, 0xf5, 0x99, 0x30, 0x99, 0xfd, 0xc2, 0x99, 0x22, 0xe5, 0x5e} },
+{ 0x0600,      16,     {0xf6, 0x3c, 0xfd, 0x8f, 0xfe, 0xc8, 0xff, 0x64, 0xff, 0xb2, 0xff, 0xd9, 0xff, 0xed, 0xff, 0xf3} },
+{ 0x0610,      16,     {0xff, 0xfa, 0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40, 0xcd, 0x06, 0x04, 0x01, 0x89, 0xab} },
+{ 0x0620,      16,     {0x01, 0x02, 0x03, 0x01, 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00} },
+{ 0x0630,      16,     {0x00, 0x02, 0xff, 0xff, 0xff, 0x00, 0x07, 0x05, 0x82, 0x03, 0x40, 0x00, 0x01, 0x07, 0x05, 0x02} },
+{ 0x0640,      16,     {0x02, 0x40, 0x00, 0x00, 0x06, 0x4c, 0x06, 0x50, 0x06, 0x72, 0x06, 0xa0, 0x04, 0x03, 0x00, 0x00} },
+{ 0x0650,      16,     {0x22, 0x03, 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00} },
+{ 0x0660,      16,     {0x62, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00} },
+{ 0x0670,      16,     {0x73, 0x00, 0x2e, 0x03, 0x41, 0x00, 0x43, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x55, 0x00} },
+{ 0x0680,      16,     {0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00} },
+{ 0x0690,      16,     {0x6c, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x64, 0x00, 0x67, 0x00, 0x65, 0x00, 0x74, 0x00} },
+{ 0x06a0,      6,      {0x06, 0x03, 0x34, 0x00, 0x37, 0x00} },
+{ 0xffff,      0,      {0x00} }
+};
index 40c935ce930b2d15d83372706f65f67c0bf8a17f..4af99326467b053f5d8b798253a88c990c935fad 100644 (file)
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (03/06/2000) gkh
+ *     Added the keyspan pda code from Brian Warner <warner@lothar.com>
+ *     Moved a bunch of the port specific stuff into its own structure. This
+ *     is in anticipation of the true multiport devices (there's a bug if you
+ *     try to access more than one port of any multiport device right now)
+ *
  * (02/21/2000) gkh
  *     Made it so that any serial devices only have to specify which functions
  *     they want to overload from the generic function calls (great, 
 #include "whiteheat.h"         /* firmware for the ConnectTech WhiteHEAT device */
 #endif
 
+#ifdef CONFIG_USB_SERIAL_KEYSPAN_PDA
+struct ezusb_hex_record {
+       __u16 address;
+       __u8 data_size;
+       __u8 data[16];
+};
+#include "keyspan_pda_fw.h"
+#endif
+
 #include "usb-serial.h"
 
 /* parity check flag */
@@ -214,23 +229,9 @@ static struct usb_serial   *serial_table[SERIAL_TTY_MINORS] = {NULL, };
 
 static struct usb_serial *get_serial_by_minor (int minor)
 {
-       int i;
-
        dbg("get_serial_by_minor %d", minor);
 
-       if (serial_table[minor] == NULL)
-               return (NULL);
-
-       if (serial_table[minor] != SERIAL_PTR_EMPTY)
-               return (serial_table[minor]);
-
-       i = minor;
-       while (serial_table[i] == SERIAL_PTR_EMPTY) {
-               if (i == 0)
-                       return (NULL);
-               --i;
-               }
-       return (serial_table[i]);
+       return serial_table[minor];
 }
 
 
@@ -263,10 +264,10 @@ static struct usb_serial *get_free_serial (int num_ports, int *minor)
                *minor = i;
                dbg("minor base = %d", *minor);
                for (i = *minor+1; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i)
-                       serial_table[i] = SERIAL_PTR_EMPTY;
-               return (serial);
+                       serial_table[i] = serial;
+               return serial;
                }
-       return (NULL);
+       return NULL;
 }
 
 
@@ -317,7 +318,7 @@ static int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit)
        if (response < 0) {
                err("ezusb_set_reset %d failed", reset_bit);
        }
-       return (response);
+       return response;
 }
 
 #endif /* USES_EZUSB_FUNCTIONS */
@@ -382,8 +383,8 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
                dbg("serial->type == NULL!");
                return;
        }
-       if (!serial->active[port]) {
-               dbg ("device already open");
+       if (!serial->port[port].active) {
+               dbg ("device not opened");
                return;
        }
 
@@ -412,7 +413,7 @@ static int serial_write (struct tty_struct * tty, int from_user, const unsigned
                dbg("serial->type == NULL!");
                return (-ENODEV);
        }
-       if (!serial->active[port]) {
+       if (!serial->port[port].active) {
                dbg ("device not opened");
                return (-EINVAL);
        }
@@ -442,7 +443,7 @@ static int serial_write_room (struct tty_struct *tty)
                dbg("serial->type == NULL!");
                return (-ENODEV);
        }
-       if (!serial->active[port]) {
+       if (!serial->port[port].active) {
                dbg ("device not open");
                return (-EINVAL);
        }
@@ -472,7 +473,7 @@ static int serial_chars_in_buffer (struct tty_struct *tty)
                dbg("serial->type == NULL!");
                return (-ENODEV);
        }
-       if (!serial->active[port]) {
+       if (!serial->port[port].active) {
                dbg ("device not open");
                return (-EINVAL);
        }
@@ -502,7 +503,7 @@ static void serial_throttle (struct tty_struct * tty)
                dbg("serial->type == NULL!");
                return;
        }
-       if (!serial->active[port]) {
+       if (!serial->port[port].active) {
                dbg ("device not open");
                return;
        }
@@ -534,7 +535,7 @@ static void serial_unthrottle (struct tty_struct * tty)
                dbg("serial->type == NULL!");
                return;
        }
-       if (!serial->active[port]) {
+       if (!serial->port[port].active) {
                dbg ("device not open");
                return;
        }
@@ -571,7 +572,7 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in
                dbg("serial->type == NULL!");
                return -ENODEV;
        }
-       if (!serial->active[port]) {
+       if (!serial->port[port].active) {
                dbg ("device not open");
                return -ENODEV;
        }
@@ -606,7 +607,7 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old)
                dbg("serial->type == NULL!");
                return;
        }
-       if (!serial->active[port]) {
+       if (!serial->port[port].active) {
                dbg ("device not open");
                return;
        }
@@ -622,6 +623,38 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old)
 }
 
 
+static void serial_break (struct tty_struct *tty, int break_state)
+{
+       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+       int port;       
+
+       if (!serial) {
+               dbg("serial == NULL!");
+               return;
+       }
+
+       port = MINOR(tty->device) - serial->minor;
+
+       dbg("serial_break port %d", port);
+       
+       /* do some sanity checking that we really have a device present */
+       if (!serial->type) {
+               dbg("serial->type == NULL!");
+               return;
+       }
+       if (!serial->port[port].active) {
+               dbg ("device not open");
+               return;
+       }
+
+       /* pass on to the driver specific version of this function if it is
+           available */
+       if (serial->type->break_ctl) {
+               serial->type->break_ctl(tty, break_state);
+       }
+}
+
+
 #ifdef CONFIG_USB_SERIAL_WHITEHEAT
 /*****************************************************************************
  * Connect Tech's White Heat specific driver functions
@@ -629,18 +662,19 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old)
 static int whiteheat_serial_open (struct tty_struct *tty, struct file *filp)
 {
        struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
 
-       dbg("whiteheat_serial_open port %d", port);
+       dbg("whiteheat_serial_open port %d", portNumber);
 
-       if (serial->active[port]) {
+       if (port->active) {
                dbg ("device already open");
                return -EINVAL;
        }
-       serial->active[port] = 1;
+       port->active = 1;
  
        /*Start reading from the device*/
-       if (usb_submit_urb(&serial->read_urb[port]))
+       if (usb_submit_urb(&port->read_urb))
                dbg("usb_submit_urb(read bulk) failed");
 
        /* Need to do device specific setup here (control lines, baud rate, etc.) */
@@ -653,17 +687,18 @@ static int whiteheat_serial_open (struct tty_struct *tty, struct file *filp)
 static void whiteheat_serial_close(struct tty_struct *tty, struct file * filp)
 {
        struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
 
-       dbg("whiteheat_serial_close port %d", port);
+       dbg("whiteheat_serial_close port %d", portNumber);
        
        /* Need to change the control lines here */
        /* FIXME */
        
        /* shutdown our bulk reads and writes */
-       usb_unlink_urb (&serial->write_urb[port]);
-       usb_unlink_urb (&serial->read_urb[port]);
-       serial->active[port] = 0;
+       usb_unlink_urb (&port->write_urb);
+       usb_unlink_urb (&port->read_urb);
+       port->active = 0;
 }
 
 
@@ -798,19 +833,20 @@ static int  whiteheat_startup (struct usb_serial *serial)
 static int visor_serial_open (struct tty_struct *tty, struct file *filp)
 {
        struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
-       int port = MINOR(tty->device) - serial->minor;
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
 
-       dbg("visor_serial_open port %d", port);
+       dbg("visor_serial_open port %d", portNumber);
 
-       if (serial->active[port]) {
+       if (port->active) {
                dbg ("device already open");
                return -EINVAL;
        }
 
-       serial->active[port] = 1;
+       port->active = 1;
 
        /*Start reading from the device*/
-       if (usb_submit_urb(&serial->read_urb[port]))
+       if (usb_submit_urb(&port->read_urb))
                dbg("usb_submit_urb(read bulk) failed");
 
        return (0);
@@ -819,10 +855,11 @@ static int visor_serial_open (struct tty_struct *tty, struct file *filp)
 static void visor_serial_close(struct tty_struct *tty, struct file * filp)
 {
        struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
-       int port = MINOR(tty->device) - serial->minor;
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
        unsigned char *transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
        
-       dbg("visor_serial_close port %d", port);
+       dbg("visor_serial_close port %d", portNumber);
                         
        if (!transfer_buffer) {
                err("visor_serial_close: kmalloc(%d) failed.", 0x12);
@@ -833,9 +870,9 @@ static void visor_serial_close(struct tty_struct *tty, struct file * filp)
        }
 
        /* shutdown our bulk reads and writes */
-       usb_unlink_urb (&serial->write_urb[port]);
-       usb_unlink_urb (&serial->read_urb[port]);
-       serial->active[port] = 0;
+       usb_unlink_urb (&port->write_urb);
+       usb_unlink_urb (&port->read_urb);
+       port->active = 0;
 }
 
 
@@ -846,7 +883,7 @@ static void visor_throttle (struct tty_struct * tty)
 
        dbg("visor_throttle port %d", port);
 
-       usb_unlink_urb (&serial->read_urb[port]);
+       usb_unlink_urb (&serial->port[port].read_urb);
 
        return;
 }
@@ -859,7 +896,7 @@ static void visor_unthrottle (struct tty_struct * tty)
 
        dbg("visor_unthrottle port %d", port);
 
-       if (usb_unlink_urb (&serial->read_urb[port]))
+       if (usb_unlink_urb (&serial->port[port].read_urb))
                dbg("usb_submit_urb(read bulk) failed");
 
        return;
@@ -947,16 +984,17 @@ static int  visor_startup (struct usb_serial *serial)
 static int  ftdi_sio_serial_open (struct tty_struct *tty, struct file *filp)
 {
        struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
        char buf[1]; /* Needed for the usb_control_msg I think */
-       int port = MINOR(tty->device) - serial->minor;
 
-       dbg("ftdi_sio_serial_open port %d", port);
+       dbg("ftdi_sio_serial_open port %d", portNumber);
 
-       if (serial->active[port]) {
+       if (port->active) {
                dbg ("device already open");
                return -EINVAL;
        }
-       serial->active[port] = 1;
+       port->active = 1;
 
        usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                        FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, 
@@ -1024,10 +1062,9 @@ static int  ftdi_sio_serial_open (struct tty_struct *tty, struct file *filp)
        }
        
        /*Start reading from the device*/
-       if (usb_submit_urb(&serial->read_urb[port]))
+       if (usb_submit_urb(&port->read_urb))
                dbg("usb_submit_urb(read bulk) failed");
 
-
        return (0);
 }
 
@@ -1035,10 +1072,11 @@ static int  ftdi_sio_serial_open (struct tty_struct *tty, struct file *filp)
 static void ftdi_sio_serial_close (struct tty_struct *tty, struct file *filp)
 {
        struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
        char buf[1];
-       int port = MINOR(tty->device) - serial->minor;
 
-       dbg("ftdi_sio_serial_close port %d", port);
+       dbg("ftdi_sio_serial_close port %d", portNumber);
        
        /* FIXME - might be able to do both simultaneously */
        if (usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
@@ -1059,9 +1097,9 @@ static void ftdi_sio_serial_close (struct tty_struct *tty, struct file *filp)
        /* FIXME Should I flush the device here? - not doing it for now */
 
        /* shutdown our bulk reads and writes */
-       usb_unlink_urb (&serial->write_urb[port]);
-       usb_unlink_urb (&serial->read_urb[port]);
-       serial->active[port] = 0;
+       usb_unlink_urb (&port->write_urb);
+       usb_unlink_urb (&port->read_urb);
+       port->active = 0;
 }
 
 
@@ -1075,42 +1113,44 @@ static int ftdi_sio_serial_write (struct tty_struct * tty, int from_user,
                                  const unsigned char *buf, int count)
 {
        struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
        const int data_offset = 1;
 
-       dbg("ftdi_sio_serial_write port %d, %d bytes", port, count);
+       dbg("ftdi_sio_serial_write port %d, %d bytes", portNumber, count);
 
        if (count == 0) {
                dbg("write request of 0 bytes");
-               return (0);
+               return 0;
        }
 
        /* only do something if we have a bulk out endpoint */
        if (serial->num_bulk_out) {
-               unsigned char *first_byte = serial->write_urb[port].transfer_buffer;
+               unsigned char *first_byte = port->write_urb.transfer_buffer;
 
-               if (serial->write_urb[port].status == -EINPROGRESS) {
+               if (port->write_urb.status == -EINPROGRESS) {
                        dbg ("already writing");
-                       return (0);
+                       return 0;
                }
 
                count += data_offset;
-               count = (count > serial->bulk_out_size[port]) ? 
-                       serial->bulk_out_size[port] : count;
-
+               count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
+               if (count == 0) {
+                       return 0;
+               }
 
                /* Copy in the data to send */
                if (from_user) {
-                       copy_from_user(serial->write_urb[port].transfer_buffer + data_offset , 
+                       copy_from_user(port->write_urb.transfer_buffer + data_offset , 
                                       buf, count - data_offset );
                }
                else {
-                       memcpy(serial->write_urb[port].transfer_buffer + data_offset,
+                       memcpy(port->write_urb.transfer_buffer + data_offset,
                               buf, count - data_offset );
                }  
 
                /* Write the control byte at the front of the packet*/
-               first_byte = serial->write_urb[port].transfer_buffer;
+               first_byte = port->write_urb.transfer_buffer;
                *first_byte = 1 | ((count-data_offset) << 2) ; 
 
 #ifdef DEBUG
@@ -1133,20 +1173,18 @@ static int ftdi_sio_serial_write (struct tty_struct * tty, int from_user,
                }
 
 #endif
-
-
                /* send the data out the bulk port */
-               serial->write_urb[port].transfer_buffer_length = count;
+               port->write_urb.transfer_buffer_length = count;
 
-               if (usb_submit_urb(&serial->write_urb[port]))
+               if (usb_submit_urb(&port->write_urb))
                        dbg("usb_submit_urb(write bulk) failed");
 
-               dbg("write returning: %d",count - data_offset);
+               dbg("write returning: %d", count - data_offset);
                return (count - data_offset);
        }
        
        /* no bulk out, so return 0 bytes written */
-       return (0);
+       return 0;
 } 
 
 
@@ -1195,6 +1233,7 @@ static void ftdi_sio_read_bulk_callback (struct urb *urb)
        return;
 } /* ftdi_sio_serial_read_bulk_callback */
 
+
 static void ftdi_sio_set_termios (struct tty_struct *tty, struct termios *old_termios)
 {
        struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
@@ -1264,6 +1303,7 @@ static void ftdi_sio_set_termios (struct tty_struct *tty, struct termios *old_te
        return;
 }
 
+
 /*FIXME - the beginnings of this implementation - not even hooked into the driver yet */
 static int ftdi_sio_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
 {
@@ -1358,57 +1398,597 @@ static int ftdi_sio_ioctl (struct tty_struct *tty, struct file * file, unsigned
 /*****************************************************************************
  * Keyspan PDA specific driver functions
  *****************************************************************************/
-static int keyspan_pda_serial_open (struct tty_struct *tty, struct file *filp)
+
+static void keyspan_pda_rx_interrupt (struct urb *urb)
+{
+       struct usb_serial *serial = (struct usb_serial *) urb->context;
+       struct tty_struct *tty = serial->tty;
+       unsigned char *data = urb->transfer_buffer;
+       int i;
+
+       /* the urb might have been killed. */
+       if (urb->status)
+               return;
+       
+       /* see if the message is data or a status interrupt */
+       switch (data[0]) {
+       case 0:
+               /* rest of message is rx data */
+               if (urb->actual_length) {
+                       for (i = 1; i < urb->actual_length ; ++i) {
+                               tty_insert_flip_char(tty, data[i], 0);
+                       }
+                       tty_flip_buffer_push(tty);
+               }
+               break;
+       case 1:
+               /* status interrupt */
+               dbg(" rx int, d1=%d, d2=%d", data[1], data[2]);
+               switch (data[1]) {
+               case 1: /* modemline change */
+                       break;
+               case 2: /* tx unthrottle interrupt */
+                       serial->tx_throttled = 0;
+                       wake_up(&serial->write_wait); /* wake up writer */
+                       break;
+               default:
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+
+       /* INT urbs are automatically re-submitted */
+}
+
+
+static void keyspan_pda_rx_throttle (struct tty_struct *tty)
 {
        struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
        int port = MINOR(tty->device) - serial->minor;
 
-       dbg("keyspan_pda_serial_open port %d", port);
+       /* stop receiving characters. We just turn off the URB request, and
+          let chars pile up in the device. If we're doing hardware
+          flowcontrol, the device will signal the other end when its buffer
+          fills up. If we're doing XON/XOFF, this would be a good time to
+          send an XOFF, although it might make sense to foist that off
+          upon the device too. */
 
-       if (serial->active[port]) {
-               dbg ("device already open");
+       dbg("keyspan_pda_rx_throttle port %d", port);
+       usb_unlink_urb(&serial->port[port].read_urb);
+}
+
+
+static void keyspan_pda_rx_unthrottle (struct tty_struct *tty)
+{
+       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+       int port = MINOR(tty->device) - serial->minor;
+
+       /* just restart the receive interrupt URB */
+       dbg("keyspan_pda_rx_unthrottle port %d", port);
+       if (usb_submit_urb(&serial->port[port].read_urb))
+               dbg(" usb_submit_urb(read urb) failed");
+       return;
+}
+
+
+static int keyspan_pda_setbaud (struct usb_serial *serial, int baud)
+{
+       int rc;
+       int bindex;
+
+       switch(baud) {
+               case 110: bindex = 0; break;
+               case 300: bindex = 1; break;
+               case 1200: bindex = 2; break;
+               case 2400: bindex = 3; break;
+               case 4800: bindex = 4; break;
+               case 9600: bindex = 5; break;
+               case 19200: bindex = 6; break;
+               case 38400: bindex = 7; break;
+               case 57600: bindex = 8; break;
+               case 115200: bindex = 9; break;
+               default: return -EINVAL;
+       }
+
+       /* rather than figure out how to sleep while waiting for this
+          to complete, I just use the "legacy" API. */
+       rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+                            0, /* set baud */
+                            USB_TYPE_VENDOR 
+                            | USB_RECIP_INTERFACE
+                            | USB_DIR_OUT, /* type */
+                            bindex, /* value */
+                            0, /* index */
+                            NULL, /* &data */
+                            0, /* size */
+                            2*HZ); /* timeout */
+       return(rc);
+}
+
+
+static void keyspan_pda_break_ctl (struct tty_struct *tty, int break_state)
+{
+       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
+       int value;
+       if (break_state == -1)
+               value = 1; /* start break */
+       else
+               value = 0; /* clear break */
+       usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+                       4, /* set break */
+                       USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+                       value, 0, NULL, 0, 2*HZ);
+       /* there is something funky about this.. the TCSBRK that 'cu' performs
+          ought to translate into a break_ctl(-1),break_ctl(0) pair HZ/4
+          seconds apart, but it feels like the break sent isn't as long as it
+          is on /dev/ttyS0 */
+}
+
+
+static void keyspan_pda_set_termios (struct tty_struct *tty,
+                                    struct termios *old_termios)
+{
+       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+       unsigned int cflag = tty->termios->c_cflag;
+
+       /* cflag specifies lots of stuff: number of stop bits, parity, number
+          of data bits, baud. What can the device actually handle?:
+          CSTOPB (1 stop bit or 2)
+          PARENB (parity)
+          CSIZE (5bit .. 8bit)
+          There is minimal hw support for parity (a PSW bit seems to hold the
+          parity of whatever is in the accumulator). The UART either deals
+          with 10 bits (start, 8 data, stop) or 11 bits (start, 8 data,
+          1 special, stop). So, with firmware changes, we could do:
+          8N1: 10 bit
+          8N2: 11 bit, extra bit always (mark?)
+          8[EOMS]1: 11 bit, extra bit is parity
+          7[EOMS]1: 10 bit, b0/b7 is parity
+          7[EOMS]2: 11 bit, b0/b7 is parity, extra bit always (mark?)
+
+          HW flow control is dictated by the tty->termios->c_cflags & CRTSCTS
+          bit.
+
+          For now, just do baud. */
+
+       switch (cflag & CBAUD) {
+               /* we could support more values here, just need to calculate
+                  the necessary divisors in the firmware. <asm/termbits.h>
+                  has the Bnnn constants. */
+               case B110: keyspan_pda_setbaud(serial, 110); break;
+               case B300: keyspan_pda_setbaud(serial, 300); break;
+               case B1200: keyspan_pda_setbaud(serial, 1200); break;
+               case B2400: keyspan_pda_setbaud(serial, 2400); break;
+               case B4800: keyspan_pda_setbaud(serial, 4800); break;
+               case B9600: keyspan_pda_setbaud(serial, 9600); break;
+               case B19200: keyspan_pda_setbaud(serial, 19200); break;
+               case B38400: keyspan_pda_setbaud(serial, 38400); break;
+               case B57600: keyspan_pda_setbaud(serial, 57600); break;
+               case B115200: keyspan_pda_setbaud(serial, 115200); break;
+               default: dbg("can't handle requested baud rate"); break;
+       }
+}
+
+
+/* modem control pins: DTR and RTS are outputs and can be controlled.
+   DCD, RI, DSR, CTS are inputs and can be read. All outputs can also be
+   read. The byte passed is: DTR(b7) DCD RI DSR CTS RTS(b2) unused unused */
+
+static int keyspan_pda_get_modem_info(struct usb_serial *serial,
+                                     unsigned char *value)
+{
+       int rc;
+       unsigned char data;
+       rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                            3, /* get pins */
+                            USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN,
+                            0, 0, &data, 1, 2*HZ);
+       if (rc > 0)
+               *value = data;
+       return rc;
+}
+
+
+static int keyspan_pda_set_modem_info(struct usb_serial *serial,
+                                     unsigned char value)
+{
+       int rc;
+       rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+                            3, /* set pins */
+                            USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_OUT,
+                            value, 0, NULL, 0, 2*HZ);
+       return rc;
+}
+
+
+static int keyspan_pda_ioctl(struct tty_struct *tty, struct file *file,
+                            unsigned int cmd, unsigned long arg)
+{
+       struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
+       int rc;
+       unsigned int value;
+       unsigned char status, mask;
+
+       switch (cmd) {
+       case TIOCMGET: /* get modem pins state */
+               rc = keyspan_pda_get_modem_info(serial, &status);
+               if (rc < 0)
+                       return rc;
+               value =
+                       ((status & (1<<7)) ? TIOCM_DTR : 0) |
+                       ((status & (1<<6)) ? TIOCM_CAR : 0) |
+                       ((status & (1<<5)) ? TIOCM_RNG : 0) |
+                       ((status & (1<<4)) ? TIOCM_DSR : 0) |
+                       ((status & (1<<3)) ? TIOCM_CTS : 0) |
+                       ((status & (1<<2)) ? TIOCM_RTS : 0);
+               if (copy_to_user((unsigned int *)arg, &value, sizeof(int)))
+                       return -EFAULT;
+               return 0;
+       case TIOCMSET: /* set a state as returned by MGET */
+               if (copy_from_user(&value, (unsigned int *)arg, sizeof(int)))
+                       return -EFAULT;
+               status =
+                       ((value & TIOCM_DTR) ? (1<<7) : 0) |
+                       ((value & TIOCM_CAR) ? (1<<6) : 0) |
+                       ((value & TIOCM_RNG) ? (1<<5) : 0) |
+                       ((value & TIOCM_DSR) ? (1<<4) : 0) |
+                       ((value & TIOCM_CTS) ? (1<<3) : 0) |
+                       ((value & TIOCM_RTS) ? (1<<2) : 0);
+               rc = keyspan_pda_set_modem_info(serial, status);
+               if (rc < 0)
+                       return rc;
+               return 0;
+       case TIOCMBIS: /* set bits in bitmask <arg> */
+       case TIOCMBIC: /* clear bits from bitmask <arg> */
+               if (copy_from_user(&value, (unsigned int *)arg, sizeof(int)))
+                       return -EFAULT;
+               rc = keyspan_pda_get_modem_info(serial, &status);
+               if (rc < 0)
+                       return rc;
+               mask =
+                       ((value & TIOCM_RTS) ? (1<<2) : 0) |
+                       ((value & TIOCM_DTR) ? (1<<7) : 0);
+               if (cmd == TIOCMBIS)
+                       status |= mask;
+               else
+                       status &= ~mask;
+               rc = keyspan_pda_set_modem_info(serial, status);
+               if (rc < 0)
+                       return rc;
+               return 0;
+       case TIOCMIWAIT:
+               /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
+               /* TODO */
+       case TIOCGICOUNT:
+               /* return count of modemline transitions */
+               return 0; /* TODO */
+       }
+       
+       return -ENOIOCTLCMD;
+}
+
+static int keyspan_pda_write(struct tty_struct * tty, int from_user, 
+                            const unsigned char *buf, int count)
+{
+       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+       int port = MINOR(tty->device) - serial->minor;
+       int request_unthrottle = 0;
+       int rc = 0;
+       DECLARE_WAITQUEUE(wait, current);
+
+       /* guess how much room is left in the device's ring buffer, and if we
+          want to send more than that, check first, updating our notion of
+          what is left. If our write will result in no room left, ask the
+          device to give us an interrupt when the room available rises above
+          a threshold, and hold off all writers (eventually, those using
+          select() or poll() too) until we receive that unthrottle interrupt.
+          Block if we can't write anything at all, otherwise write as much as
+          we can. */
+
+       if (count == 0) {
+               dbg(" write request of 0 bytes");
+               return (0);
+       }
+
+       /* we might block because of:
+          the TX urb is in-flight (wait until it completes)
+          the device is full (wait until it says there is room)
+       */
+       while (serial->port[port].write_urb.status == -EINPROGRESS) {
+               if (0 /* file->f_flags & O_NONBLOCK */) {
+                       rc = -EAGAIN;
+                       goto err;
+               }
+               interruptible_sleep_on(&serial->write_wait);
+               if (signal_pending(current)) {
+                       rc = -ERESTARTSYS;
+                       goto err;
+               }
+       }
+
+       /* at this point the URB is in our control, nobody else can submit it
+          again (the only sudden transition was the one from EINPROGRESS to
+          finished) */
+
+       /* the next potential block is that our TX process might be throttled.
+          The transition from throttled->not happens because of an Rx
+          interrupt, and the wake_up occurs during the same interrupt, so we
+          have to be careful to avoid a race that would cause us to sleep
+          forever. */
+
+       add_wait_queue(&serial->write_wait, &wait);
+       set_current_state(TASK_INTERRUPTIBLE);
+       while (serial->tx_throttled) {
+               /* device can't accomodate any more characters. Sleep until it
+                  can. Woken up by an Rx interrupt message, which clears
+                  tx_throttled first. */
+               dbg(" tx_throttled, going to sleep");
+               if (signal_pending(current)) {
+                       current->state = TASK_RUNNING;
+                       remove_wait_queue(&serial->write_wait, &wait);
+                       dbg(" woke up because of signal");
+                       rc = -ERESTARTSYS;
+                       goto err;
+               }
+               schedule();
+               dbg(" woke up");
+       }
+       remove_wait_queue(&serial->write_wait, &wait);
+       set_current_state(TASK_RUNNING);
+
+       count = (count > serial->port[port].bulk_out_size) ? 
+               serial->port[port].bulk_out_size : count;
+       if (count > serial->tx_room) {
+               unsigned char room;
+               /* Looks like we might overrun the Tx buffer. Ask the device
+                  how much room it really has */
+               rc = usb_control_msg(serial->dev, 
+                                    usb_rcvctrlpipe(serial->dev, 0),
+                                    6, /* write_room */
+                                    USB_TYPE_VENDOR | USB_RECIP_INTERFACE
+                                    | USB_DIR_IN,
+                                    0, /* value: 0 means "remaining room" */
+                                    0, /* index */
+                                    &room,
+                                    1,
+                                    2*HZ);
+               if (rc < 0) {
+                       dbg(" roomquery failed");
+                       return rc; /* failed */
+               }
+               if (rc == 0) {
+                       dbg(" roomquery returned 0 bytes");
+                       return -EIO; /* device didn't return any data */
+               }
+               dbg(" roomquery says %d", room);
+               serial->tx_room = room;
+               if (count > serial->tx_room) {
+                       /* we're about to completely fill the Tx buffer, so
+                          we'll be throttled afterwards. */
+                       count = serial->tx_room;
+                       request_unthrottle = 1;
+               }
+       }
+       serial->tx_room -= count;
+
+       if (count) {
+               /* now transfer data */
+               if (from_user) {
+                       copy_from_user(serial->port[port].write_urb.transfer_buffer,
+                                      buf, count);
+               }
+               else {
+                       memcpy (serial->port[port].write_urb.transfer_buffer, 
+                               buf, count);
+               }  
+               /* send the data out the bulk port */
+               serial->port[port].write_urb.transfer_buffer_length = count;
+               
+               if (usb_submit_urb(&serial->port[port].write_urb))
+                       dbg(" usb_submit_urb(write bulk) failed");
+       }
+       else {
+               /* There wasn't any room left, so we are throttled until
+                  the buffer empties a bit */
+               request_unthrottle = 1;
+       }
+
+       if (request_unthrottle) {
+               dbg(" request_unthrottle");
+               /* ask the device to tell us when the tx buffer becomes
+                  sufficiently empty */
+               serial->tx_throttled = 1; /* block writers */
+               rc = usb_control_msg(serial->dev, 
+                                    usb_sndctrlpipe(serial->dev, 0),
+                                    7, /* request_unthrottle */
+                                    USB_TYPE_VENDOR | USB_RECIP_INTERFACE
+                                    | USB_DIR_OUT,
+                                    16, /* value: threshold */
+                                    0, /* index */
+                                    NULL,
+                                    0,
+                                    2*HZ);
+       }
+
+       return (count);
+ err:
+       return (rc);
+}
+
+
+static void keyspan_pda_write_bulk_callback (struct urb *urb)
+{
+       struct usb_serial *serial = (struct usb_serial *) urb->context;
+       struct tty_struct *tty = serial->tty; 
+
+       wake_up_interruptible(&serial->write_wait);
+
+       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && 
+           tty->ldisc.write_wakeup)
+               (tty->ldisc.write_wakeup)(tty);
+
+       wake_up_interruptible(&tty->write_wait);
+}
+
+
+static int keyspan_pda_write_room (struct tty_struct *tty)
+{
+       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
+
+       /* used by n_tty.c for processing of tabs and such. Giving it our
+          conservative guess is probably good enough, but needs testing by
+          running a console through the device. */
+
+       return (serial->tx_room);
+}
+
+
+static int keyspan_pda_chars_in_buffer (struct tty_struct *tty) 
+{
+       struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
+       unsigned char count;
+       int rc;
+
+       /* used by tty stuff to wait for output to drain. Go ask the
+          device how much is still queued in the tx ring */
+       rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                            6, /* write_room */
+                            USB_TYPE_VENDOR | USB_RECIP_INTERFACE
+                            | USB_DIR_IN,
+                            1, /* value: 1 means chars_in_buffer */
+                            0, /* index */
+                            &count,
+                            1,
+                            2*HZ);
+       if (rc < 0)
+               return rc; /* failed */
+       if (rc == 0)
+               return -EIO; /* device didn't return any data */
+       return (count);
+}
+
+
+static int keyspan_pda_serial_open (struct tty_struct *tty, struct file *filp)
+{
+       struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
+       unsigned char room;
+       int rc;
+
+       if (port->active) {
                return -EINVAL;
        }
-       serial->active[port] = 1;
+       port->active = 1;
  
-       /*Start reading from the device*/
-       if (usb_submit_urb(&serial->read_urb[port]))
-               dbg("usb_submit_urb(read bulk) failed");
+       /* find out how much room is in the Tx ring */
+       rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                            6, /* write_room */
+                            USB_TYPE_VENDOR | USB_RECIP_INTERFACE
+                            | USB_DIR_IN,
+                            0, /* value */
+                            0, /* index */
+                            &room,
+                            1,
+                            2*HZ);
+       if (rc < 0) {
+               dbg(" roomquery failed");
+               return rc; /* failed */
+       }
+       if (rc == 0) {
+               dbg(" roomquery returned 0 bytes");
+               return -EIO; /* device didn't return any data */
+       }
+       serial->tx_room = room;
+       serial->tx_throttled = room ? 0 : 1;
+
+       /* the normal serial device seems to always turn on DTR and RTS here,
+          so do the same */
+       if (tty->termios->c_cflag & CBAUD)
+               keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2) );
+       else
+               keyspan_pda_set_modem_info(serial, 0);
 
-       /* Need to do device specific setup here (control lines, baud rate, etc.) */
-       /* FIXME */
+       /*Start reading from the device*/
+       if (usb_submit_urb(&port->read_urb))
+               dbg(" usb_submit_urb(read int) failed");
 
        return (0);
 }
 
 
-static void keyspan_pda_serial_close(struct tty_struct *tty, struct file * filp)
+static void keyspan_pda_serial_close(struct tty_struct *tty, 
+                                    struct file *filp)
 {
        struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
+
+       /* the normal serial device seems to always shut off DTR and RTS now */
+       if (tty->termios->c_cflag & HUPCL)
+               keyspan_pda_set_modem_info(serial, 0);
 
-       dbg("keyspan_pda_serial_close port %d", port);
-       
-       /* Need to change the control lines here */
-       /* FIXME */
-       
        /* shutdown our bulk reads and writes */
-       usb_unlink_urb (&serial->write_urb[port]);
-       usb_unlink_urb (&serial->read_urb[port]);
-       serial->active[port] = 0;
+       usb_unlink_urb (&port->write_urb);
+       usb_unlink_urb (&port->read_urb);
+       port->active = 0;
 }
 
 
-static int  keyspan_pda_startup (struct usb_serial *serial)
+/* download the firmware to a "fake" device (pre-renumeration) */
+static int keyspan_pda_fake_startup (struct usb_serial *serial)
 {
-       dbg("keyspan_pda_startup");
+       int response;
+       const struct ezusb_hex_record *record;
 
        /* download the firmware here ... */
-       /* FIXME */
+       response = ezusb_set_reset(serial, 1);
+
+       record = &keyspan_pda_firmware[0];
+       while(record->address != 0xffff) {
+               response = ezusb_writememory(serial, record->address,
+                                            (unsigned char *)record->data,
+                                            record->data_size, 0xa0);
+               if (response < 0) {
+                       err("ezusb_writememory failed for Keyspan PDA "
+                           "firmware (%d %04X %p %d)",
+                           response, 
+                           record->address, record->data, record->data_size);
+                       break;
+               }
+               record++;
+       }
+       /* bring device out of reset. Renumeration will occur in a moment
+          and the new device will bind to the real driver */
+       response = ezusb_set_reset(serial, 0);
 
        /* we want this device to fail to have a driver assigned to it. */
        return (1);
 }
+
+
+/* do some startup allocations not currently performed by usb_serial_probe() */
+static int keyspan_pda_startup (struct usb_serial *serial)
+{
+       struct usb_endpoint_descriptor *intin;
+       intin = serial->port[0].interrupt_in_endpoint;
+
+       /* set up the receive interrupt urb */
+       FILL_INT_URB(&serial->port[0].read_urb, serial->dev,
+                    usb_rcvintpipe(serial->dev, intin->bEndpointAddress),
+                    serial->port[0].interrupt_in_buffer,
+                    intin->wMaxPacketSize,
+                    keyspan_pda_rx_interrupt,
+                    serial,
+                    intin->bInterval);
+
+       init_waitqueue_head(&serial->write_wait);
+       
+       return (0);
+}
+
 #endif /* CONFIG_USB_SERIAL_KEYSPAN_PDA */
 
 
@@ -1418,20 +1998,21 @@ static int  keyspan_pda_startup (struct usb_serial *serial)
 static int generic_serial_open (struct tty_struct *tty, struct file *filp)
 {
        struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
 
-       dbg("generic_serial_open port %d", port);
+       dbg("generic_serial_open port %d", portNumber);
 
-       if (serial->active[port]) {
+       if (port->active) {
                dbg ("device already open");
                return -EINVAL;
        }
-       serial->active[port] = 1;
+       port->active = 1;
  
        /* if we have a bulk interrupt, start reading from it */
        if (serial->num_bulk_in) {
                /*Start reading from the device*/
-               if (usb_submit_urb(&serial->read_urb[port]))
+               if (usb_submit_urb(&port->read_urb))
                        dbg("usb_submit_urb(read bulk) failed");
        }
 
@@ -1442,28 +2023,30 @@ static int generic_serial_open (struct tty_struct *tty, struct file *filp)
 static void generic_serial_close(struct tty_struct *tty, struct file * filp)
 {
        struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
 
-       dbg("generic_serial_close port %d", port);
+       dbg("generic_serial_close port %d", portNumber);
        
        /* shutdown any bulk reads that might be going on */
        if (serial->num_bulk_out) {
-               usb_unlink_urb (&serial->write_urb[port]);
+               usb_unlink_urb (&port->write_urb);
        }
        if (serial->num_bulk_in) {
-               usb_unlink_urb (&serial->read_urb[port]);
+               usb_unlink_urb (&port->read_urb);
        }
 
-       serial->active[port] = 0;
+       port->active = 0;
 }
 
 
 static int generic_serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count)
 {
        struct usb_serial *serial = (struct usb_serial *) tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
 
-       dbg("generic_serial_write port %d", port);
+       dbg("generic_serial_write port %d", portNumber);
 
        if (count == 0) {
                dbg("write request of 0 bytes");
@@ -1472,24 +2055,24 @@ static int generic_serial_write (struct tty_struct * tty, int from_user, const u
 
        /* only do something if we have a bulk out endpoint */
        if (serial->num_bulk_out) {
-               if (serial->write_urb[port].status == -EINPROGRESS) {
+               if (port->write_urb.status == -EINPROGRESS) {
                        dbg ("already writing");
                        return (0);
                }
 
-               count = (count > serial->bulk_out_size[port]) ? serial->bulk_out_size[port] : count;
+               count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
 
                if (from_user) {
-                       copy_from_user(serial->write_urb[port].transfer_buffer, buf, count);
+                       copy_from_user(port->write_urb.transfer_buffer, buf, count);
                }
                else {
-                       memcpy (serial->write_urb[port].transfer_buffer, buf, count);
+                       memcpy (port->write_urb.transfer_buffer, buf, count);
                }  
 
                /* send the data out the bulk port */
-               serial->write_urb[port].transfer_buffer_length = count;
+               port->write_urb.transfer_buffer_length = count;
 
-               if (usb_submit_urb(&serial->write_urb[port]))
+               if (usb_submit_urb(&port->write_urb))
                        dbg("usb_submit_urb(write bulk) failed");
 
                return (count);
@@ -1503,16 +2086,17 @@ static int generic_serial_write (struct tty_struct * tty, int from_user, const u
 static int generic_write_room (struct tty_struct *tty) 
 {
        struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
        int room;
 
-       dbg("generic_write_room port %d", port);
+       dbg("generic_write_room port %d", portNumber);
        
        if (serial->num_bulk_out) {
-               if (serial->write_urb[port].status == -EINPROGRESS)
+               if (port->write_urb.status == -EINPROGRESS)
                        room = 0;
                else
-                       room = serial->bulk_out_size[port];
+                       room = port->bulk_out_size;
                dbg("generic_write_room returns %d", room);
                return (room);
        }
@@ -1524,13 +2108,14 @@ static int generic_write_room (struct tty_struct *tty)
 static int generic_chars_in_buffer (struct tty_struct *tty) 
 {
        struct usb_serial *serial = (struct usb_serial *)tty->driver_data; 
-       int port = MINOR(tty->device) - serial->minor;
+       int portNumber = MINOR(tty->device) - serial->minor;
+       struct usb_serial_port *port = &serial->port[portNumber];
 
-       dbg("generic_chars_in_buffer port %d", port);
+       dbg("generic_chars_in_buffer port %d", portNumber);
        
        if (serial->num_bulk_out) {
-               if (serial->write_urb[port].status == -EINPROGRESS) {
-                       return (serial->bulk_out_size[port]);
+               if (port->write_urb.status == -EINPROGRESS) {
+                       return (port->bulk_out_size);
                }
        }
 
@@ -1630,6 +2215,7 @@ static void generic_write_bulk_callback (struct urb *urb)
 static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
 {
        struct usb_serial *serial = NULL;
+       struct usb_serial_port *port;
        struct usb_interface_descriptor *interface;
        struct usb_endpoint_descriptor *endpoint;
        struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
@@ -1725,6 +2311,20 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                                serial->num_bulk_out = num_bulk_out;
                                serial->num_interrupt_in = num_interrupt_in;
 
+                               /* collect interrupt_in endpoints now, because
+                                  the keyspan_pda startup function needs
+                                  to know about them */
+                               for (i = 0; i < num_interrupt_in; ++i) {
+                                       port = &serial->port[i];
+                                       buffer_size = interrupt_in_endpoint[i]->wMaxPacketSize;
+                                       port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
+                                       if (!port->interrupt_in_buffer) {
+                                               err("Couldn't allocate interrupt_in_buffer");
+                                               goto probe_error;
+                                       }
+                                       port->interrupt_in_endpoint = interrupt_in_endpoint[i];
+                               }
+
                                /* if this device type has a startup function, call it */
                                if (type->startup) {
                                        if (type->startup (serial)) {
@@ -1735,34 +2335,36 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
 
                                /* set up the endpoint information */
                                for (i = 0; i < num_bulk_in; ++i) {
+                                       port = &serial->port[i];
                                        buffer_size = bulk_in_endpoint[i]->wMaxPacketSize;
-                                       serial->bulk_in_buffer[i] = kmalloc (buffer_size, GFP_KERNEL);
-                                       if (!serial->bulk_in_buffer[i]) {
+                                       port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
+                                       if (!port->bulk_in_buffer) {
                                                err("Couldn't allocate bulk_in_buffer");
                                                goto probe_error;
                                        }
                                        if (serial->type->read_bulk_callback) {
-                                               FILL_BULK_URB(&serial->read_urb[i], dev, usb_rcvbulkpipe (dev, bulk_in_endpoint[i]->bEndpointAddress),
-                                                               serial->bulk_in_buffer[i], buffer_size, serial->type->read_bulk_callback, serial);
+                                               FILL_BULK_URB(&port->read_urb, dev, usb_rcvbulkpipe (dev, bulk_in_endpoint[i]->bEndpointAddress),
+                                                               port->bulk_in_buffer, buffer_size, serial->type->read_bulk_callback, serial);
                                        } else {
-                                               FILL_BULK_URB(&serial->read_urb[i], dev, usb_rcvbulkpipe (dev, bulk_in_endpoint[i]->bEndpointAddress),
-                                                               serial->bulk_in_buffer[i], buffer_size, generic_read_bulk_callback, serial);
+                                               FILL_BULK_URB(&port->read_urb, dev, usb_rcvbulkpipe (dev, bulk_in_endpoint[i]->bEndpointAddress),
+                                                               port->bulk_in_buffer, buffer_size, generic_read_bulk_callback, serial);
                                        }
                                }
 
                                for (i = 0; i < num_bulk_out; ++i) {
-                                       serial->bulk_out_size[i] = bulk_out_endpoint[i]->wMaxPacketSize;
-                                       serial->bulk_out_buffer[i] = kmalloc (serial->bulk_out_size[i], GFP_KERNEL);
-                                       if (!serial->bulk_out_buffer[i]) {
+                                       port = &serial->port[i];
+                                       port->bulk_out_size = bulk_out_endpoint[i]->wMaxPacketSize;
+                                       port->bulk_out_buffer = kmalloc (port->bulk_out_size, GFP_KERNEL);
+                                       if (!port->bulk_out_buffer) {
                                                err("Couldn't allocate bulk_out_buffer");
                                                goto probe_error;
                                        }
                                        if (serial->type->write_bulk_callback) {
-                                               FILL_BULK_URB(&serial->write_urb[i], dev, usb_sndbulkpipe (dev, bulk_out_endpoint[i]->bEndpointAddress),
-                                                               serial->bulk_out_buffer[i], serial->bulk_out_size[i], serial->type->write_bulk_callback, serial);
+                                               FILL_BULK_URB(&port->write_urb, dev, usb_sndbulkpipe (dev, bulk_out_endpoint[i]->bEndpointAddress),
+                                                               port->bulk_out_buffer, port->bulk_out_size, serial->type->write_bulk_callback, serial);
                                        } else {
-                                               FILL_BULK_URB(&serial->write_urb[i], dev, usb_sndbulkpipe (dev, bulk_out_endpoint[i]->bEndpointAddress),
-                                                               serial->bulk_out_buffer[i], serial->bulk_out_size[i], generic_write_bulk_callback, serial);
+                                               FILL_BULK_URB(&port->write_urb, dev, usb_sndbulkpipe (dev, bulk_out_endpoint[i]->bEndpointAddress),
+                                                               port->bulk_out_buffer, port->bulk_out_size, generic_write_bulk_callback, serial);
                                        }
                                }
 
@@ -1799,14 +2401,20 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
 probe_error:
        if (serial) {
                for (i = 0; i < num_bulk_in; ++i)
-                       if (serial->bulk_in_buffer[i])
-                               kfree (serial->bulk_in_buffer[i]);
+                       if (serial->port[i].bulk_in_buffer[i])
+                               kfree (serial->port[i].bulk_in_buffer);
                for (i = 0; i < num_bulk_out; ++i)
-                       if (serial->bulk_out_buffer[i])
-                               kfree (serial->bulk_out_buffer[i]);
+                       if (serial->port[i].bulk_out_buffer)
+                               kfree (serial->port[i].bulk_out_buffer);
                for (i = 0; i < num_interrupt_in; ++i)
-                       if (serial->interrupt_in_buffer[i])
-                               kfree (serial->interrupt_in_buffer[i]);
+                       if (serial->port[i].interrupt_in_buffer)
+                               kfree (serial->port[i].interrupt_in_buffer);
+               
+               /* return the minor range that this device had */
+               return_serial (serial);
+
+               /* free up any memory that we allocated */
+               kfree (serial);
        }
        return NULL;
 }
@@ -1815,26 +2423,34 @@ probe_error:
 static void usb_serial_disconnect(struct usb_device *dev, void *ptr)
 {
        struct usb_serial *serial = (struct usb_serial *) ptr;
+       struct usb_serial_port *port;
        int i;
 
        if (serial) {
                /* need to stop any transfers...*/
                for (i = 0; i < serial->num_ports; ++i) {
-                       usb_unlink_urb (&serial->write_urb[i]);
-                       usb_unlink_urb (&serial->read_urb[i]);
-                       serial->active[i] = 0;
+                       port = &serial->port[i];
+                       usb_unlink_urb (&port->write_urb);
+                       usb_unlink_urb (&port->read_urb);
+                       port->active = 0;
                }
 
                /* free up any memory that we allocated */
-               for (i = 0; i < serial->num_bulk_in; ++i)
-                       if (serial->bulk_in_buffer[i])
-                               kfree (serial->bulk_in_buffer[i]);
-               for (i = 0; i < serial->num_bulk_out; ++i)
-                       if (serial->bulk_out_buffer[i])
-                               kfree (serial->bulk_out_buffer[i]);
-               for (i = 0; i < serial->num_interrupt_in; ++i)
-                       if (serial->interrupt_in_buffer[i])
-                               kfree (serial->interrupt_in_buffer[i]);
+               for (i = 0; i < serial->num_bulk_in; ++i) {
+                       port = &serial->port[i];
+                       if (port->bulk_in_buffer)
+                               kfree (port->bulk_in_buffer);
+               }
+               for (i = 0; i < serial->num_bulk_out; ++i) {
+                       port = &serial->port[i];
+                       if (port->bulk_out_buffer)
+                               kfree (port->bulk_out_buffer);
+               }
+               for (i = 0; i < serial->num_interrupt_in; ++i) {
+                       port = &serial->port[i];
+                       if (port->interrupt_in_buffer)
+                               kfree (port->interrupt_in_buffer);
+               }
 
                for (i = 0; i < serial->num_ports; ++i) {
                        info("%s converter now disconnected from ttyUSB%d", serial->type->name, serial->minor + i);
@@ -1885,7 +2501,7 @@ static struct tty_driver serial_tty_driver = {
        stop:                   NULL,
        start:                  NULL,
        hangup:                 NULL,
-       break_ctl:              NULL,
+       break_ctl:              serial_break,
        wait_until_sent:        NULL,
        send_xchar:             NULL,
        read_proc:              NULL,
index c62bae569286868bc1c5c380eed1df1403182ea3..f02eeedf59f72ec50ee33d0aaf40a9a00dc45448 100644 (file)
@@ -44,7 +44,7 @@ MODULE_PARM_DESC(product, "User specified USB idProduct");
 #define FTDI_SIO_SERIAL_CONVERTER_ID   0x8372
 #define KEYSPAN_VENDOR_ID              0x06cd
 #define KEYSPAN_PDA_FAKE_ID            0x0103
-#define KEYSPAN_PDA_ID                 0x0103
+#define KEYSPAN_PDA_ID                 0x0104 /* no clue */
 
 #define SERIAL_TTY_MAJOR       188     /* Nice legal number now */
 #define SERIAL_TTY_MINORS      16      /* Actually we are allowed 255, but this is good for now */
@@ -52,29 +52,45 @@ MODULE_PARM_DESC(product, "User specified USB idProduct");
 
 #define MAX_NUM_PORTS  8       /* The maximum number of ports one device can grab at once */
 
+
+struct usb_serial_port {
+       struct usb_serial       *serial;        /* pointer back to the owner of this port */
+       struct tty_struct *     tty;            /* the coresponding tty for this device */
+       unsigned char           minor;
+       unsigned char           number;
+       char                    active;         /* someone has this device open */
+
+       struct usb_endpoint_descriptor * interrupt_in_endpoint;
+       __u8                    interrupt_in_interval;
+       unsigned char *         interrupt_in_buffer;
+       struct urb              control_urb;
+
+       unsigned char *         bulk_in_buffer;
+       struct urb              read_urb;
+
+       unsigned char *         bulk_out_buffer;
+       int                     bulk_out_size;
+       struct urb              write_urb;
+       void *                  private;        /* data private to the specific driver */
+};
+
 struct usb_serial {
        struct usb_device *             dev;
        struct usb_serial_device_type * type;
-       void *                          irq_handle;
-       unsigned int                    irqpipe;
        struct tty_struct *             tty;                    /* the coresponding tty for this device */
        unsigned char                   minor;
        unsigned char                   num_ports;              /* the number of ports this device has */
-       char                            active[MAX_NUM_PORTS];  /* someone has this device open */
+       char                            num_interrupt_in;       /* number of interrupt in endpoints we have */
+       char                            num_bulk_in;            /* number of bulk in endpoints we have */
+       char                            num_bulk_out;           /* number of bulk out endpoints we have */
+       struct usb_serial_port          port[MAX_NUM_PORTS];
 
-       char                    num_interrupt_in;               /* number of interrupt in endpoints we have */
-       __u8                    interrupt_in_interval[MAX_NUM_PORTS];
-       unsigned char *         interrupt_in_buffer[MAX_NUM_PORTS];
-       struct urb              control_urb[MAX_NUM_PORTS];
+       /* FIXME! These should move to the private area of the keyspan driver */
+       int                     tx_room;
+       int                     tx_throttled;
+       wait_queue_head_t       write_wait;
 
-       char                    num_bulk_in;                    /* number of bulk in endpoints we have */
-       unsigned char *         bulk_in_buffer[MAX_NUM_PORTS];
-       struct urb              read_urb[MAX_NUM_PORTS];
-
-       char                    num_bulk_out;                   /* number of bulk out endpoints we have */
-       unsigned char *         bulk_out_buffer[MAX_NUM_PORTS];
-       int                     bulk_out_size[MAX_NUM_PORTS];
-       struct urb              write_urb[MAX_NUM_PORTS];
+       void *                  private;                /* data private to the specific driver */
 };
 
 
@@ -101,8 +117,6 @@ struct usb_serial_device_type {
        char    num_bulk_out;
        char    num_ports;              /* number of serial ports this device has */
 
-       void    *private;               /* data private to the specific driver */
-       
        /* function call to make before accepting driver */
        int (*startup) (struct usb_serial *serial);     /* return 0 to continue initialization, anything else to abort */
        
@@ -113,13 +127,13 @@ struct usb_serial_device_type {
        int  (*write_room)(struct tty_struct *tty);
        int  (*ioctl)(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
        void (*set_termios)(struct tty_struct *tty, struct termios * old);
+       void (*break_ctl)(struct tty_struct *tty, int break_state);
        int  (*chars_in_buffer)(struct tty_struct *tty);
        void (*throttle)(struct tty_struct * tty);
        void (*unthrottle)(struct tty_struct * tty);
        
        void (*read_bulk_callback)(struct urb *urb);
        void (*write_bulk_callback)(struct urb *urb);
-
 };
 
 
@@ -317,10 +331,31 @@ static struct usb_serial_device_type ftdi_sio_device = {
 
 
 #ifdef CONFIG_USB_SERIAL_KEYSPAN_PDA
-/* function prototypes for a FTDI serial converter */
-static int  keyspan_pda_serial_open    (struct tty_struct *tty, struct file *filp);
-static void keyspan_pda_serial_close   (struct tty_struct *tty, struct file *filp);
+/* function prototypes for a Keyspan PDA serial converter */
+static int  keyspan_pda_serial_open    (struct tty_struct *tty, 
+                                        struct file *filp);
+static void keyspan_pda_serial_close   (struct tty_struct *tty, 
+                                        struct file *filp);
 static int  keyspan_pda_startup                (struct usb_serial *serial);
+static void keyspan_pda_rx_throttle    (struct tty_struct *tty);
+static void keyspan_pda_rx_unthrottle  (struct tty_struct *tty);
+static int  keyspan_pda_setbaud                (struct usb_serial *serial, int baud);
+static int  keyspan_pda_write_room     (struct tty_struct *tty);
+static int  keyspan_pda_write          (struct tty_struct *tty,
+                                        int from_user,
+                                        const unsigned char *buf,
+                                        int count);
+static void keyspan_pda_write_bulk_callback (struct urb *urb);
+static int  keyspan_pda_chars_in_buffer (struct tty_struct *tty);
+static int  keyspan_pda_ioctl          (struct tty_struct *tty,
+                                        struct file *file,
+                                        unsigned int cmd,
+                                        unsigned long arg);
+static void keyspan_pda_set_termios    (struct tty_struct *tty,
+                                        struct termios *old);
+static void keyspan_pda_break_ctl      (struct tty_struct *tty,
+                                        int break_state);
+static int  keyspan_pda_fake_startup   (struct usb_serial *serial);
 
 /* All of the device info needed for the Keyspan PDA serial converter */
 static __u16   keyspan_vendor_id               = KEYSPAN_VENDOR_ID;
@@ -336,24 +371,35 @@ static struct usb_serial_device_type keyspan_pda_fake_device = {
        num_interrupt_in:       NUM_DONT_CARE,
        num_bulk_in:            NUM_DONT_CARE,
        num_bulk_out:           NUM_DONT_CARE,
-       startup:                keyspan_pda_startup     
+       startup:                keyspan_pda_fake_startup
 };
 static struct usb_serial_device_type keyspan_pda_device = {
        name:                   "Keyspan PDA",
        idVendor:               &keyspan_vendor_id,             /* the Keyspan PDA vendor ID */
        idProduct:              &keyspan_pda_product_id,        /* the Keyspan PDA product id */
-       needs_interrupt_in:     MUST_HAVE_NOT,                  /* this device must not have an interrupt in endpoint */
-       needs_bulk_in:          MUST_HAVE,                      /* this device must have a bulk in endpoint */
-       needs_bulk_out:         MUST_HAVE,                      /* this device must have a bulk out endpoint */
-       num_interrupt_in:       0,
-       num_bulk_in:            1,
+       needs_interrupt_in:     MUST_HAVE,
+       needs_bulk_in:          DONT_CARE,
+       needs_bulk_out:         MUST_HAVE,
+       num_interrupt_in:       1,
+       num_bulk_in:            0,
        num_bulk_out:           1,
        num_ports:              1,
        open:                   keyspan_pda_serial_open,
        close:                  keyspan_pda_serial_close,
+       write:                  keyspan_pda_write,
+       write_room:             keyspan_pda_write_room,
+       write_bulk_callback:    keyspan_pda_write_bulk_callback,
+       chars_in_buffer:        keyspan_pda_chars_in_buffer,
+       throttle:               keyspan_pda_rx_throttle,
+       unthrottle:             keyspan_pda_rx_unthrottle,
+       startup:                keyspan_pda_startup,
+       ioctl:                  keyspan_pda_ioctl,
+       set_termios:            keyspan_pda_set_termios,
+       break_ctl:              keyspan_pda_break_ctl,
 };
 #endif
 
+
 /* To add support for another serial converter, create a usb_serial_device_type
    structure for that device, and add it to this list, making sure that the
    last  entry is NULL. */
@@ -386,10 +432,5 @@ static struct usb_serial_device_type *usb_serial_devices[] = {
        #undef  USES_EZUSB_FUNCTIONS
 #endif
 
-
-/* used to mark that a pointer is empty (and not NULL) */
-#define SERIAL_PTR_EMPTY ((void *)(-1))
-
-
 #endif /* ifdef __LINUX_USB_SERIAL_H */
 
index 1dfdc92c0e787148a562d9a393f6614fa51b68fc..a8dc538902ba767684287dfe7cdd1b499f95f57b 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -309,7 +309,7 @@ static void update_queue (struct sem_array * sma)
        for (q = sma->sem_pending; q; q = q->next) {
                        
                if (q->status == 1)
-                       return; /* wait for other process */
+                       continue;       /* this one was woken up before */
 
                error = try_atomic_semop(sma, q->sops, q->nsops,
                                         q->undo, q->pid, q->alter);
index c3da1e840731d2197c63d588b55b218cc0a596d1..08af7c6377c25c4a805627bd54d2d98b1b7af738 100644 (file)
@@ -182,6 +182,7 @@ EXPORT_SYMBOL(notify_change);
 EXPORT_SYMBOL(get_hardblocksize);
 EXPORT_SYMBOL(set_blocksize);
 EXPORT_SYMBOL(getblk);
+EXPORT_SYMBOL(bdget);
 EXPORT_SYMBOL(bread);
 EXPORT_SYMBOL(breada);
 EXPORT_SYMBOL(__brelse);