summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@penguin.transmeta.com>2002-11-25 03:16:12 -0800
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-11-25 03:16:12 -0800
commit9eb7fd948c161b9002628177cf19da39c66637ea (patch)
tree8a1c6b2ba2c8345ad389cf1f57ac0b02a77c68f1
parent40cfa05d8d293abf41e523cc9853c045b2469952 (diff)
parentf81179746d7249e10148ecd0ace4e1b9f1e49550 (diff)
Merge
-rw-r--r--Documentation/DocBook/journal-api.tmpl6
-rw-r--r--Documentation/DocBook/mousedrivers.tmpl24
-rw-r--r--Documentation/kernel-parameters.txt2
-rw-r--r--Documentation/magic-number.txt92
-rw-r--r--Documentation/networking/00-INDEX2
-rw-r--r--Documentation/networking/soundmodem.txt90
-rw-r--r--Documentation/sysctl/kernel.txt68
-rw-r--r--arch/i386/kernel/cpu/cyrix.c88
-rw-r--r--arch/i386/kernel/cpu/mcheck/non-fatal.c4
-rw-r--r--arch/i386/kernel/io_apic.c20
-rw-r--r--arch/i386/pci/direct.c1
-rw-r--r--arch/m68k/lib/checksum.c2
-rw-r--r--arch/mips64/Kconfig2
-rw-r--r--drivers/Makefile4
-rw-r--r--drivers/acpi/namespace/nsxfobj.c2
-rw-r--r--drivers/block/DAC960.c2849
-rw-r--r--drivers/block/DAC960.h285
-rw-r--r--drivers/block/nbd.c69
-rw-r--r--drivers/char/agp/agp.h9
-rw-r--r--drivers/char/ftape/lowlevel/ftape-init.h11
-rw-r--r--drivers/char/ftape/zftape/zftape-ctl.c44
-rw-r--r--drivers/char/ftape/zftape/zftape-init.c25
-rw-r--r--drivers/char/ftape/zftape/zftape-init.h7
-rw-r--r--drivers/char/ip2main.c4
-rw-r--r--drivers/char/keyboard.c4
-rw-r--r--drivers/char/mem.c3
-rw-r--r--drivers/char/sx.c17
-rw-r--r--drivers/char/tpqic02.c12
-rw-r--r--drivers/char/watchdog/scx200_wdt.c7
-rw-r--r--drivers/hotplug/cpqphp_nvram.c12
-rw-r--r--drivers/ide/Kconfig26
-rw-r--r--drivers/ide/Makefile4
-rw-r--r--drivers/ide/ide-cd.c2
-rw-r--r--drivers/ide/ide-disk.c71
-rw-r--r--drivers/ide/ide-dma.c211
-rw-r--r--drivers/ide/ide-floppy.c97
-rw-r--r--drivers/ide/ide-io.c1320
-rw-r--r--drivers/ide/ide-iops.c25
-rw-r--r--drivers/ide/ide-lib.c36
-rw-r--r--drivers/ide/ide-probe.c39
-rw-r--r--drivers/ide/ide-tape.c13
-rw-r--r--drivers/ide/ide-taskfile.c10
-rw-r--r--drivers/ide/ide-tcq.c32
-rw-r--r--drivers/ide/ide.c1328
-rw-r--r--drivers/ide/legacy/ide-cs.c2
-rw-r--r--drivers/ide/pci/Makefile2
-rw-r--r--drivers/ide/pci/aec62xx.c6
-rw-r--r--drivers/ide/pci/aec62xx.h4
-rw-r--r--drivers/ide/pci/alim15x3.c12
-rw-r--r--drivers/ide/pci/amd74xx.c14
-rw-r--r--drivers/ide/pci/cmd640.c4
-rw-r--r--drivers/ide/pci/cmd64x.c20
-rw-r--r--drivers/ide/pci/cs5520.c323
-rw-r--r--drivers/ide/pci/cs5520.h66
-rw-r--r--drivers/ide/pci/cs5530.c5
-rw-r--r--drivers/ide/pci/cy82c693.c5
-rw-r--r--drivers/ide/pci/generic.c2
-rw-r--r--drivers/ide/pci/hpt34x.c5
-rw-r--r--drivers/ide/pci/hpt366.c10
-rw-r--r--drivers/ide/pci/it8172.c6
-rw-r--r--drivers/ide/pci/ns87415.c4
-rw-r--r--drivers/ide/pci/nvidia.c12
-rw-r--r--drivers/ide/pci/opti621.c3
-rw-r--r--drivers/ide/pci/pdc202xx_new.c30
-rw-r--r--drivers/ide/pci/pdc202xx_new.h35
-rw-r--r--drivers/ide/pci/pdc202xx_old.c30
-rw-r--r--drivers/ide/pci/pdcadma.c3
-rw-r--r--drivers/ide/pci/piix.c11
-rw-r--r--drivers/ide/pci/sc1200.c593
-rw-r--r--drivers/ide/pci/sc1200.h54
-rw-r--r--drivers/ide/pci/serverworks.c24
-rw-r--r--drivers/ide/pci/siimage.c8
-rw-r--r--drivers/ide/pci/siimage.h12
-rw-r--r--drivers/ide/pci/sis5513.c7
-rw-r--r--drivers/ide/pci/trm290.c4
-rw-r--r--drivers/ide/pci/via82cxxx.c6
-rw-r--r--drivers/ide/setup-pci.c255
-rw-r--r--drivers/input/gameport/fm801-gp.c2
-rw-r--r--drivers/input/gameport/ns558.c2
-rw-r--r--drivers/input/gameport/vortex.c4
-rw-r--r--drivers/isdn/hardware/eicon/mi_pc.h2
-rw-r--r--drivers/md/dm-ioctl.c10
-rw-r--r--drivers/md/dm-table.c26
-rw-r--r--drivers/md/dm.c61
-rw-r--r--drivers/media/dvb/av7110/Makefile2
-rw-r--r--drivers/media/dvb/av7110/av7110.c290
-rw-r--r--drivers/media/dvb/av7110/av7110.h18
-rw-r--r--drivers/media/dvb/av7110/saa7146.c2
-rw-r--r--drivers/media/dvb/av7110/saa7146_core.c62
-rw-r--r--drivers/media/dvb/av7110/saa7146_core.h27
-rw-r--r--drivers/media/dvb/av7110/saa7146_v4l.c1
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c237
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.h10
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c154
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.h42
-rw-r--r--drivers/media/dvb/dvb-core/dvb_filter.c1045
-rw-r--r--drivers/media/dvb/dvb-core/dvb_filter.h41
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c68
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h8
-rw-r--r--drivers/media/dvb/dvb-core/dvb_i2c.c6
-rw-r--r--drivers/media/dvb/dvb-core/dvb_i2c.h6
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ksyms.c28
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c27
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.h4
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c133
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h45
-rw-r--r--drivers/media/dvb/frontends/Kconfig24
-rw-r--r--drivers/media/dvb/frontends/Makefile2
-rw-r--r--drivers/media/dvb/frontends/alps_bsru6.c117
-rw-r--r--drivers/media/dvb/frontends/alps_bsrv2.c2
-rw-r--r--drivers/media/dvb/frontends/alps_tdlb7.c437
-rw-r--r--drivers/media/dvb/frontends/alps_tdmb7.c468
-rw-r--r--drivers/media/dvb/frontends/ves1820.c13
-rw-r--r--drivers/media/video/bttv-cards.c2
-rw-r--r--drivers/media/video/saa7111.c190
-rw-r--r--drivers/media/video/saa7185.c172
-rw-r--r--drivers/message/fusion/mptbase.c67
-rw-r--r--drivers/message/fusion/mptbase.h12
-rw-r--r--drivers/message/fusion/mptctl.c802
-rw-r--r--drivers/message/fusion/mptctl.h166
-rw-r--r--drivers/message/fusion/mptlan.c2
-rw-r--r--drivers/message/fusion/mptlan.h1
-rw-r--r--drivers/message/fusion/mptscsih.c316
-rw-r--r--drivers/message/fusion/mptscsih.h20
-rw-r--r--drivers/message/i2o/i2o_block.c4
-rw-r--r--drivers/message/i2o/i2o_core.c3
-rw-r--r--drivers/message/i2o/i2o_scsi.c62
-rw-r--r--drivers/net/arcnet/com20020-pci.c2
-rw-r--r--drivers/net/depca.c2
-rw-r--r--drivers/net/ewrk3.c43
-rw-r--r--drivers/net/hamradio/Kconfig114
-rw-r--r--drivers/net/hamradio/Makefile1
-rw-r--r--drivers/net/hamradio/baycom_epp.c24
-rw-r--r--drivers/net/hamradio/dmascc.c67
-rw-r--r--drivers/net/hamradio/soundmodem/Makefile42
-rw-r--r--drivers/net/hamradio/soundmodem/gentbl.c689
-rw-r--r--drivers/net/hamradio/soundmodem/sm.c759
-rw-r--r--drivers/net/hamradio/soundmodem/sm.h383
-rw-r--r--drivers/net/hamradio/soundmodem/sm_afsk1200.c272
-rw-r--r--drivers/net/hamradio/soundmodem/sm_afsk2400_7.c296
-rw-r--r--drivers/net/hamradio/soundmodem/sm_afsk2400_8.c296
-rw-r--r--drivers/net/hamradio/soundmodem/sm_afsk2666.c356
-rw-r--r--drivers/net/hamradio/soundmodem/sm_fsk9600.c391
-rw-r--r--drivers/net/hamradio/soundmodem/sm_hapn4800.c560
-rw-r--r--drivers/net/hamradio/soundmodem/sm_psk4800.c418
-rw-r--r--drivers/net/hamradio/soundmodem/sm_sbc.c942
-rw-r--r--drivers/net/hamradio/soundmodem/sm_wss.c968
-rw-r--r--drivers/net/hamradio/soundmodem/smdma.h217
-rw-r--r--drivers/net/irda/vlsi_ir.c20
-rw-r--r--drivers/net/pcmcia/aironet4500_cs.c5
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c3
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c1
-rw-r--r--drivers/net/sk98lin/h/skgehw.h2
-rw-r--r--drivers/net/skfp/h/skfbi.h4
-rw-r--r--drivers/net/slip.c26
-rw-r--r--drivers/net/tokenring/3c359.c2
-rw-r--r--drivers/net/tokenring/olympic.c6
-rw-r--r--drivers/net/wan/hostess_sv11.c16
-rw-r--r--drivers/net/wan/pc300_drv.c6
-rw-r--r--drivers/net/wan/sealevel.c11
-rw-r--r--drivers/pci/pci.c1
-rw-r--r--drivers/pci/pci.ids16
-rw-r--r--drivers/pci/quirks.c90
-rw-r--r--drivers/pnp/core.c2
-rw-r--r--drivers/pnp/isapnp/core.c2
-rw-r--r--drivers/pnp/system.c2
-rw-r--r--drivers/sbus/char/bpp.c2
-rw-r--r--drivers/scsi/3w-xxxx.c1
-rw-r--r--drivers/scsi/dmx3191d.c1
-rw-r--r--drivers/scsi/dtc.c7
-rw-r--r--drivers/scsi/eata.c13
-rw-r--r--drivers/scsi/eata_pio.c5
-rw-r--r--drivers/scsi/i60uscsi.c24
-rw-r--r--drivers/scsi/in2000.c4
-rw-r--r--drivers/scsi/inia100.c63
-rw-r--r--drivers/scsi/inia100.h19
-rw-r--r--drivers/scsi/ips.c12
-rw-r--r--drivers/scsi/pas16.c6
-rw-r--r--drivers/scsi/scsi.h6
-rw-r--r--drivers/scsi/t128.c12
-rw-r--r--drivers/scsi/ultrastor.c2
-rw-r--r--drivers/video/68328fb.c986
-rw-r--r--drivers/video/vga16fb.c185
-rw-r--r--fs/ncpfs/inode.c1
-rw-r--r--fs/proc/array.c4
-rw-r--r--include/asm-i386/io_apic.h7
-rw-r--r--include/asm-i386/processor.h4
-rw-r--r--include/linux/dvb/ca.h14
-rw-r--r--include/linux/dvb/osd.h3
-rw-r--r--include/linux/ide.h23
-rw-r--r--include/linux/pci_ids.h27
-rw-r--r--include/linux/serio.h1
-rw-r--r--include/linux/soundmodem.h90
-rw-r--r--include/net/irda/vlsi_ir.h20
-rw-r--r--net/atm/common.c2
-rw-r--r--net/wanrouter/wanmain.c8
-rw-r--r--scripts/lxdialog/util.c2
-rw-r--r--sound/oss/Kconfig78
-rw-r--r--sound/oss/i810_audio.c9
-rw-r--r--sound/pci/cs4281.c4
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c5
201 files changed, 9568 insertions, 12940 deletions
diff --git a/Documentation/DocBook/journal-api.tmpl b/Documentation/DocBook/journal-api.tmpl
index ecd49b7e8033..3df30534a4bd 100644
--- a/Documentation/DocBook/journal-api.tmpl
+++ b/Documentation/DocBook/journal-api.tmpl
@@ -196,6 +196,8 @@ listed against them. Ext3 does this in ext3_test_allocatable().
Lock is also providing through journal_{un,}lock_updates(),
ext3 uses this when it wants a window with a clean and stable fs for a moment.
eg.
+</para>
+
<programlisting>
journal_lock_updates() //stop new stuff happening..
@@ -216,9 +218,13 @@ calls.
Using the journal is a matter of wrapping the different context changes,
being each mount, each modification (transaction) and each changed buffer
to tell the journalling layer about them.
+</para>
+<para>
Here is a some pseudo code to give you an idea of how it works, as
an example.
+</para>
+
<programlisting>
journal_t* my_jnrl = journal_create();
journal_init_{dev,inode}(jnrl,...)
diff --git a/Documentation/DocBook/mousedrivers.tmpl b/Documentation/DocBook/mousedrivers.tmpl
index d5d19703068b..72946b2ddaa5 100644
--- a/Documentation/DocBook/mousedrivers.tmpl
+++ b/Documentation/DocBook/mousedrivers.tmpl
@@ -153,11 +153,17 @@ static struct miscdevice our_mouse = {
__init ourmouse_init(void)
{
- if(check_region(OURMOUSE_BASE, 3))
+ if (request_region(OURMOUSE_BASE, 3, "ourmouse") < 0) {
+ printk(KERN_ERR "ourmouse: request_region failed.\n");
return -ENODEV;
- request_region(OURMOUSE_BASE, 3, "ourmouse");
+ }
+
+ if (misc_register(&amp;our_mouse) < 0) {
+ printk(KERN_ERR "ourmouse: cannot register misc device.\n");
+ release_region(OURMOUSE_BASE, 3);
+ return -EBUSY;
+ }
- misc_register(&amp;our_mouse);
return 0;
}
</programlisting>
@@ -177,18 +183,20 @@ __init ourmouse_init(void)
so it is a good idea to obtain a current copy of this file first.
</para>
<para>
- Our code then is fairly simple. We check nobody else has taken our
- address space. Having done so we reserve it to ensure nobody stamps
- on our device while probing for other ISA bus devices. Such a probe
- might confuse our device.
+ Our code then is fairly simple. We reserve our I/O address space with
+ request_region, checking to make sure that it succeeded (i.e. the
+ space wasn't reserved by anyone else).
</para>
<para>
- Then we tell the misc driver that we wish to own a minor number. We also
+ Then we ask the misc driver to allocate our minor device number. We also
hand it our name (which is used in
<filename class="directory">/proc/misc</filename>) and a set of file
operations that are to be used. The file operations work exactly like the
file operations you would register for a normal character device. The misc
device itself is simply acting as a redirector for requests.
+ Since misc_register can fail, it is important to check for failure
+ and act accordingly (which in the case of a mouse driver is to abort,
+ since you can't use the mouse without a working device node).
</para>
<para>
Next, in order to be able to use and test our code we need to add some
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 54668d2be0d2..6749d3665e3c 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -584,8 +584,6 @@ running once the system is up.
sound= [SOUND]
- soundmodem= [HW,AX25,SOUND] Use sound card as packet radio modem.
-
specialix= [HW,SERIAL] Specialix multi-serial port adapter.
sscape= [HW,SOUND]
diff --git a/Documentation/magic-number.txt b/Documentation/magic-number.txt
index fa3361fb461d..9755756036f4 100644
--- a/Documentation/magic-number.txt
+++ b/Documentation/magic-number.txt
@@ -43,57 +43,115 @@ sorted by number field.
<mailto: kgb@knm.org.pl>
29 Jul 1998
+Updated the magic table to Linux 2.5.45. Right over the feature freeze,
+but it is possible that some new magic numbers will sneak into the
+kernel before 2.6.x yet.
+
+ Petr Baudis
+ <pasky@ucw.cz>
+ 03 Nov 2002
+
Magic Name Number Structure File
===========================================================================
-PG_MAGIC 'P' pg_{read,write}_hdr include/linux/pg.h
+PG_MAGIC 'P' pg_{read,write}_hdr include/linux/pg.h
+CMAGIC 0x0111 user include/linux/a.out.h
MKISS_DRIVER_MAGIC 0x04bf mkiss_channel drivers/net/mkiss.h
RISCOM8_MAGIC 0x0907 riscom_port drivers/char/riscom8.h
+SPECIALIX_MAGIC 0x0907 specialix_port drivers/char/specialix_io8.h
+AURORA_MAGIC 0x0A18 Aurora_port drivers/sbus/char/aurora.h
+HDLC_MAGIC 0x239e n_hdlc drivers/char/n_hdlc.c
APM_BIOS_MAGIC 0x4101 apm_user arch/i386/kernel/apm.c
CYCLADES_MAGIC 0x4359 cyclades_port include/linux/cyclades.h
FASYNC_MAGIC 0x4601 fasync_struct include/linux/fs.h
-PTY_MAGIC 0x5001 (none at the moment)
- drivers/char/pty.c
-PPP_MAGIC 0x5002 ppp include/linux/if_ppp.h
+ISICOM_MAGIC 0x4d54 isi_port include/linux/isicom.h
+PTY_MAGIC 0x5001 (none at the moment)
+ drivers/char/pty.c
+PPP_MAGIC 0x5002 ppp include/linux/if_pppvar.h
SERIAL_MAGIC 0x5301 async_struct include/linux/serial.h
SSTATE_MAGIC 0x5302 serial_state include/linux/serial.h
SLIP_MAGIC 0x5302 slip drivers/net/slip.h
STRIP_MAGIC 0x5303 strip drivers/net/strip.c
X25_ASY_MAGIC 0x5303 x25_asy drivers/net/x25_asy.h
-SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h
+SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h
AX25_MAGIC 0x5316 ax_disp drivers/net/mkiss.h
ESP_MAGIC 0x53ee esp_struct drivers/char/esp.h
TTY_MAGIC 0x5401 tty_struct include/linux/tty.h
+MGSL_MAGIC 0x5401 mgsl_info drivers/char/synclink.c
TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h
+MGSLPC_MAGIC 0x5402 mgslpc_info drivers/char/pcmcia/synclink_cs.c
TTY_LDISC_MAGIC 0x5403 tty_ldisc include/linux/tty_ldisc.h
-SPECIALIX_MAGIC 0x0907 specialix_port drivers/char/specialix_io8.h
-CG_MAGIC 0x090255 ufs_cylinder_group include/linux/ufs_fs.h
-RPORT_MAGIC 0x525001 r_port drivers/char/rocket_int.h
-GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h
+USB_SERIAL_MAGIC 0x6702 usb_serial drivers/usb/serial/usb-serial.h
+USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth drivers/usb/class/bluetty.c
+RFCOMM_TTY_MAGIC 0x6d02 (note at the moment)
+ net/bluetooth/rfcomm/tty.c
+USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h
+CG_MAGIC 0x00090255 ufs_cylinder_group include/linux/ufs_fs.h
+A2232_MAGIC 0x000a2232 gs_port drivers/char/ser_a2232.h
+SOLARIS_SOCKET_MAGIC 0x000ADDED sol_socket_struct arch/sparc64/solaris/socksys.h
+RPORT_MAGIC 0x00525001 r_port drivers/char/rocket_int.h
+LSEMAGIC 0x05091998 lse drivers/fc4/fc.c
+GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h
+RIO_MAGIC 0x12345678 gs_port drivers/char/rio/rio_linux.c
+SX_MAGIC 0x12345678 gs_port drivers/char/sx.h
NBD_REQUEST_MAGIC 0x12560953 nbd_request include/linux/nbd.h
-SLAB_RED_MAGIC2 0x170fc2a5 (any) mm/slab.c
+RED_MAGIC2 0x170fc2a5 (any) mm/slab.c
BAYCOM_MAGIC 0x19730510 baycom_state drivers/net/baycom_epp.c
ISDN_X25IFACE_MAGIC 0x1e75a2b9 isdn_x25iface_proto_data
drivers/isdn/isdn_x25iface.h
ECP_MAGIC 0x21504345 cdkecpsig include/linux/cdk.h
+LSOMAGIC 0x27091997 lso drivers/fc4/fc.c
LSMAGIC 0x2a3b4d2a ls drivers/fc4/fc.c
-LSOMAGIC 0x2a3c4e3c lso drivers/fc4/fc.c
WANPIPE_MAGIC 0x414C4453 sdla_{dump,exec} include/linux/wanpipe.h
-CODA_CNODE_MAGIC 0x47114711 coda_inode_info include/linux/coda_fs_i.h
+CS_CARD_MAGIC 0x43525553 cs_card sound/oss/cs46xx.c
+LABELCL_MAGIC 0x4857434c labelcl_info_s include/asm/ia64/sn/labelcl.h
ISDN_ASYNC_MAGIC 0x49344C01 modem_info include/linux/isdn.h
-ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s include/linux/isdn.h
+CTC_ASYNC_MAGIC 0x49344C01 ctc_tty_info drivers/s390/net/ctctty.c
+ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s drivers/isdn/i4l/isdn_net_lib.h
+SAVEKMSG_MAGIC2 0x4B4D5347 savekmsg arch/*/amiga/config.c
STLI_BOARDMAGIC 0x4bc6c825 stlibrd include/linux/istallion.h
+CS_STATE_MAGIC 0x4c4f4749 cs_state sound/oss/cs46xx.c
SLAB_C_MAGIC 0x4f17a36d kmem_cache_s mm/slab.c
+COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.c
+I810_CARD_MAGIC 0x5072696E i810_card sound/oss/i810_audio.c
+TRIDENT_CARD_MAGIC 0x5072696E trident_card sound/oss/trident.c
ROUTER_MAGIC 0x524d4157 wan_device include/linux/wanrouter.h
-SLAB_RED_MAGIC1 0x5a2cf071 (any) mm/slab.c
+SCC_MAGIC 0x52696368 gs_port drivers/char/scc.h
+SAVEKMSG_MAGIC1 0x53415645 savekmsg arch/*/amiga/config.c
+GDA_MAGIC 0x58464552 gda include/asm-mips64/sn/gda.h
+RED_MAGIC1 0x5a2cf071 (any) mm/slab.c
STL_PORTMAGIC 0x5a7182c9 stlport include/linux/stallion.h
HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state include/linux/hdlcdrv.h
-EPCA_MAGIC 0x5c6df104 channel include/linux/epca.h
+EPCA_MAGIC 0x5c6df104 channel include/linux/epca.h
PCXX_MAGIC 0x5c6df104 channel drivers/char/pcxx.h
+KV_MAGIC 0x5f4b565f kernel_vars_s include/asm-mips64/sn/klkernvars.h
+I810_STATE_MAGIC 0x63657373 i810_state sound/oss/i810_audio.c
+TRIDENT_STATE_MAGIC 0x63657373 trient_state sound/oss/trident.c
+M3_CARD_MAGIC 0x646e6f50 m3_card sound/oss/maestro3.c
+SLOT_MAGIC 0x67267321 slot drivers/hotplug/cpqphp.h
+SLOT_MAGIC 0x67267322 slot drivers/hotplug/acpiphp.h
LO_MAGIC 0x68797548 nbd_device include/linux/nbd.h
+M3_STATE_MAGIC 0x734d724d m3_state sound/oss/maestro3.c
STL_PANELMAGIC 0x7ef621a1 stlpanel include/linux/stallion.h
+VMALLOC_MAGIC 0x87654320 snd_alloc_track sound/core/memory.c
+KMALLOC_MAGIC 0x87654321 snd_alloc_track sound/core/memory.c
+PWC_MAGIC 0x89DC10AB pwc_device drivers/usb/media/pwc.h
NBD_REPLY_MAGIC 0x96744668 nbd_reply include/linux/nbd.h
STL_BOARDMAGIC 0xa2267f52 stlbrd include/linux/stallion.h
-SLAB_MAGIC_ALLOC 0xa5c32f2b kmem_slab_s mm/slab.c
-SLAB_MAGIC_DESTROYED 0xb2f23c5a kmem_slab_s mm/slab.c
+SCI_MAGIC 0xbabeface gs_port drivers/char/sh-sci.h
+CODA_MAGIC 0xC0DAC0DA coda_file_info include/linux/coda_fs_i.h
STLI_PORTMAGIC 0xe671c7a1 stliport include/linux/istallion.h
+YAM_MAGIC 0xF10A7654 yam_port drivers/net/hamradio/yam.c
CCB_MAGIC 0xf2691ad2 ccb drivers/scsi/ncr53c8xx.c
+HTB_CMAGIC 0xFEFAFEF1 htb_class net/sched/sch_htb.c
+NMI_MAGIC 0x48414d4d455201 nmi_s include/asm-mips64/sn/nmi.h
+
+Note that there are also defined special per-driver magic numbers in sound
+memory managment. See include/sound/sndmagic.h for complete list of them. Many
+OSS sound drivers have their magic numbers constructed from the soundcard PCI
+ID - these are not listed here as well.
+
+IrDA subsystem also uses large number of own magic numbers, see
+include/net/irda/irda.h for a complete list of them.
+
+HFS is another larger user of magic numbers - you can find them in
+fs/hfs/hfs.h.
diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX
index 3105a937ec77..9431cf58e904 100644
--- a/Documentation/networking/00-INDEX
+++ b/Documentation/networking/00-INDEX
@@ -104,8 +104,6 @@ smc9.txt
- the driver for SMC's 9000 series of Ethernet cards
smctr.txt
- SMC TokenCard TokenRing Linux driver info.
-soundmodem.txt
- - Linux driver for sound cards as AX.25 modems
tcp.txt
- short blurb on how TCP output takes place.
tlan.txt
diff --git a/Documentation/networking/soundmodem.txt b/Documentation/networking/soundmodem.txt
deleted file mode 100644
index f6d49e9af01b..000000000000
--- a/Documentation/networking/soundmodem.txt
+++ /dev/null
@@ -1,90 +0,0 @@
- LINUX DRIVER FOR SOUNDCARDS AS AX.25 MODEMS
-
- Thomas M. Sailer, HB9JNX/AE4WA, <sailer@ife.ee.ethz.ch>
-
-This driver allows either SoundBlaster (sbc) or Windows Sound System (wss)
-compatible soundcards to be used as either 1200 baud AFSK or 9600 baud FSK
-AX.25 packet radio modems. Only half duplex operation is supported; an
-attempt to include full duplex support failed because the hardware did
-not support it (it appeared that the card only provides one DMA channel,
-although the codec chip would support two channels). The driver needs
-some processing power! A 66 MHz 486 DX2 is a minimum requirement. Otherwise
-interactive performance of the computer may become sluggish. This driver
-does *not* support telephone modem standards, it is intended for radio
-use only.
-
-
-The Interface of the driver
-
-The driver provides kernel network drivers named sm[0-3]. sethdlc
-from the ax25 utilities may be used to set driver states etc. Users
-of userland AX.25 stacks may use the net2kiss utility (also available
-in the ax25 utilities package) to convert packets of a network interface
-to a KISS stream on a pseudo tty. There's also a patch available from
-me for WAMPES which allows attaching a kernel network interface directly.
-
-
-Configuring the driver
-
-Some sound cards need to be initialized before they operate in either
-SoundBlaster or WSS compatibility mode. The driver does _NOT_ do this;
-you may use the standard linux sound driver to initialize the soundcard;
-compile it as a module, and do
- insmod sound
- rmmod sound
-The soundcard should then be initialized correctly. If this does not help,
-you'll have to write your own initialization utility.
-
-Every time the driver is inserted into the kernel, it has to know which
-modems it should access at which ports. This can be done with the setbaycom
-utility. If you are only using one modem, you can also configure the
-driver from the insmod command line (or by means of an option line in
-/etc/modules.conf).
-
-Examples:
- insmod soundmodem mode="sbc:afsk1200" iobase=0x220 irq=5 dma=1
- sethdlc -i sm0 -p mode "sbc:afsk1200" io 0x220 irq 5 dma 1
-
-Both lines configure the first port to drive a soundblaster card
-in 1200 baud AFSK mode.
-
-The channel access parameters can be set with sethdlc -a or kissparms.
-Note that both utilities interpret the values slightly different.
-
-
-Input and output levels
-
-It is important that the input and output levels are adjusted properly.
-There are two utilities, available in the ax25 utilities distribution,
-to facilitate this: smmixer and smdiag. smdiag allows you to display
-the input signal in an oscilloscope like display or an eye diagram.
-smmixer allows you to adjust input/output levels. See the respective
-man pages.
-
-
-Transmitter keying
-
-Since soundcards do not have a DC coupled output; PTT keying options include
-the following:
-* VOX circuitry
-* Serial port pin
-* Parallel port pin
-* MPU401 MIDI output via a retriggerable monoflop.
-Circuit schematics may be found at
-http://www.ife.ee.ethz.ch/~sailer/pcf/ptt_circ/ptt.html.
-
-
-Compatibility with the rest of the Linux kernel
-
-The sound driver and the soundcard modem driver compete for the same
-hardware resources. Of course only one driver can access a given
-interface at a time. Worse yet, the sound driver grabs the soundcard
-at startup time. Therefore the soundcard modem driver subsequently won't
-be able to access the soundcard. You might therefore find it necessary to
-unload the sound driver before using the soundcard modem driver.
-
-
-
-vy 73s de
-Tom Sailer, sailer@ife.ee.ethz.ch
-hb9jnx @ hb9w.ampr.org
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index fdff7a57850e..d75397d5a262 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -17,29 +17,42 @@ before actually making adjustments.
Currently, these files might (depending on your configuration)
show up in /proc/sys/kernel:
- acct
+- core_pattern
+- core_uses_pid
- ctrl-alt-del
- dentry-state
- domainname
- hostname
- htab-reclaim [ PPC only ]
+- hotplug
- java-appletviewer [ binfmt_java, obsolete ]
- java-interpreter [ binfmt_java, obsolete ]
- l2cr [ PPC only ]
- modprobe ==> Documentation/kmod.txt
+- msgmax
+- msgmnb
+- msgmni
- osrelease
- ostype
- overflowgid
- overflowuid
- panic
+- pid_max
- powersave-nap [ PPC only ]
- printk
- real-root-dev ==> Documentation/initrd.txt
- reboot-cmd [ SPARC only ]
-- rtsig-nr
- rtsig-max
+- rtsig-nr
+- sem
- sg-big-buff [ generic SCSI device (sg) ]
+- shmall
- shmmax [ sysv ipc ]
+- shmmni
+- stop-a [ SPARC only ]
+- sysrq ==> Documentation/sysrq.txt
- tainted
+- threads-max
- version
- zero-paged [ PPC only ]
@@ -62,6 +75,41 @@ valid for 30 seconds.
==============================================================
+core_pattern:
+
+core_pattern is used to specify a core dumpfile pattern name.
+. max length 64 characters; default value is "core"
+. core_pattern is used as a pattern template for the output filename;
+ certain string patterns (beginning with '%') are substituted with
+ their actual values.
+. backward compatibility with core_uses_pid:
+ If core_pattern does not include "%p" (default does not)
+ and core_uses_pid is set, then .PID will be appended to
+ the filename.
+. corename format specifiers:
+ %<NUL> '%' is dropped
+ %% output one '%'
+ %p pid
+ %u uid
+ %g gid
+ %s signal number
+ %t UNIX time of dump
+ %h hostname
+ %e executable filename
+ %<OTHER> both are dropped
+
+==============================================================
+
+core_uses_pid:
+
+The default coredump filename is "core". By setting
+core_uses_pid to 1, the coredump filename becomes core.PID.
+If core_pattern does not include "%p" (default does not)
+and core_uses_pid is set, then .PID will be appended to
+the filename.
+
+==============================================================
+
ctrl-alt-del:
When the value in this file is 0, ctrl-alt-del is trapped and
@@ -105,6 +153,13 @@ each time the system hits the idle loop.
==============================================================
+hotplug:
+
+Path for the hotplug policy agent.
+Default value is "/sbin/hotplug".
+
+==============================================================
+
l2cr: (PPC only)
This flag controls the L2 cache of G3 processor boards. If
@@ -149,6 +204,14 @@ software watchdog, the recommended setting is 60.
==============================================================
+pid_max:
+
+PID allocation wrap value. When the kenrel's next PID value
+reaches this value, it wraps back to a minimum PID value.
+PIDs of value pid_max or larger are not allocated.
+
+==============================================================
+
powersave-nap: (PPC only)
If set, Linux-PPC will use the 'nap' mode of powersaving,
@@ -195,7 +258,7 @@ The file rtsig-max can be used to tune the maximum number
of POSIX realtime (queued) signals that can be outstanding
in the system.
-Rtsig-nr shows the number of RT signals currently queued.
+rtsig-nr shows the number of RT signals currently queued.
==============================================================
@@ -231,6 +294,7 @@ can be ORed together:
Set by modutils >= 2.4.9.
2 - A module was force loaded by insmod -f.
Set by modutils >= 2.4.9.
+ 4 - Unsafe SMP processors: SMP with CPUs not designed for SMP.
==============================================================
diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c
index 9c996d15e55a..9709711c5689 100644
--- a/arch/i386/kernel/cpu/cyrix.c
+++ b/arch/i386/kernel/cpu/cyrix.c
@@ -106,6 +106,89 @@ static void __init check_cx686_slop(struct cpuinfo_x86 *c)
}
}
+
+static void __init set_cx86_reorder(void)
+{
+#ifdef CONFIG_OOSTORE
+ u8 ccr3;
+
+ printk(KERN_INFO "Enable Memory access reorder on Cyrix/NSC processor.\n");
+ ccr3 = getCx86(CX86_CCR3);
+ setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN  */
+
+ /* Load/Store Serialize to mem access disable (=reorder it)  */
+ setCx86(CX86_PCR0, getCx86(CX86_PCR0) & ~0x80);
+#ifdef CONFIG_NOHIGHMEM
+ /* set load/store serialize from 1GB to 4GB */
+ ccr3 |= 0xe0;
+#endif
+ setCx86(CX86_CCR3, ccr3);
+#endif
+}
+
+static void __init set_cx86_memwb(void)
+{
+ u32 cr0;
+
+ printk(KERN_INFO "Enable Memory-Write-back mode on Cyrix/NSC processor.\n");
+
+ /* CCR2 bit 2: unlock NW bit */
+ setCx86(CX86_CCR2, getCx86(CX86_CCR2) & ~0x04);
+ /* set 'Not Write-through' */
+ cr0 = 0x20000000;
+ __asm__("movl %%cr0,%%eax\n\t"
+ "orl %0,%%eax\n\t"
+ "movl %%eax,%%cr0\n"
+ : : "r" (cr0)
+ :"ax");
+ /* CCR2 bit 2: lock NW bit and set WT1 */
+ setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14 );
+}
+
+static void __init set_cx86_inc(void)
+{
+ unsigned char ccr3;
+
+ printk(KERN_INFO "Enable Incrementor on Cyrix/NSC processor.\n");
+
+ ccr3 = getCx86(CX86_CCR3);
+ setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN  */
+ /* PCR1 -- Performance Control */
+ /* Incrementor on, whatever that is */
+ setCx86(CX86_PCR1, getCx86(CX86_PCR1) | 0x02);
+ /* PCR0 -- Performance Control */
+ /* Incrementor Margin 10 */
+ setCx86(CX86_PCR0, getCx86(CX86_PCR0) | 0x04);
+ setCx86(CX86_CCR3, ccr3); /* disable MAPEN */
+}
+
+/*
+ * Configure later MediaGX and/or Geode processor.
+ */
+
+static void __init geode_configure(void)
+{
+ unsigned long flags;
+ u8 ccr3, ccr4;
+ unsigned long cr0;
+ local_irq_save(flags);
+
+ ccr3 = getCx86(CX86_CCR3);
+ setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* Enable */
+
+ ccr4 = getCx86(CX86_CCR4);
+ ccr4 |= 0x38; /* FPU fast, DTE cache, Mem bypass */
+
+ setCx86(CX86_CCR3, ccr3);
+
+ set_cx86_memwb();
+ set_cx86_reorder();
+ set_cx86_inc();
+
+ local_irq_restore(flags);
+}
+
+
static void __init init_cyrix(struct cpuinfo_x86 *c)
{
unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0;
@@ -201,7 +284,10 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
if (c->cpuid_level == 2) {
/* Enable cxMMX extensions (GX1 Datasheet 54) */
setCx86(CX86_CCR7, getCx86(CX86_CCR7)|1);
-
+
+ /* GXlv/GXm/GX1 */
+ if((dir1 >= 0x50 && dir1 <= 0x54) || dir1 >= 0x63)
+ geode_configure();
get_model_name(c); /* get CPU marketing name */
return;
}
diff --git a/arch/i386/kernel/cpu/mcheck/non-fatal.c b/arch/i386/kernel/cpu/mcheck/non-fatal.c
index f60162c85c46..57035340e783 100644
--- a/arch/i386/kernel/cpu/mcheck/non-fatal.c
+++ b/arch/i386/kernel/cpu/mcheck/non-fatal.c
@@ -49,7 +49,6 @@ static void mce_checkregs (void *info)
static void do_mce_timer(void *data)
{
- mce_checkregs (NULL);
smp_call_function (mce_checkregs, NULL, 1, 1);
}
@@ -57,11 +56,10 @@ static DECLARE_WORK(mce_work, do_mce_timer, NULL);
static void mce_timerfunc (unsigned long data)
{
+ mce_checkregs (NULL);
#ifdef CONFIG_SMP
if (num_online_cpus() > 1)
schedule_work (&mce_work);
-#else
- mce_checkregs (NULL);
#endif
mce_timer.expires = jiffies + MCE_RATE;
add_timer (&mce_timer);
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 4bb71d80fb1f..1953c872340f 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -44,6 +44,12 @@
static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
/*
+ * Is the SiS APIC rmw bug present ?
+ * -1 = dont know, 0 = no, 1 = yes
+ */
+int sis_apic_bug = -1;
+
+/*
* # of IRQ routing registers
*/
int nr_ioapic_registers[MAX_IO_APICS];
@@ -122,7 +128,7 @@ static void __init replace_pin_at_irq(unsigned int irq,
break; \
reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \
reg ACTION; \
- io_apic_modify(entry->apic, reg); \
+ io_apic_modify(entry->apic, 0x10 + R + pin*2, reg); \
if (!entry->next) \
break; \
entry = irq_2_pin + entry->next; \
@@ -1738,6 +1744,18 @@ void __init setup_IO_APIC(void)
print_IO_APIC();
}
+/*
+ * Called after all the initialization is done. If we didnt find any
+ * APIC bugs then we can allow the modify fast path
+ */
+
+static void __init io_apic_bug_finalize(void)
+{
+ if(sis_apic_bug == -1)
+ sis_apic_bug = 0;
+}
+
+late_initcall(io_apic_bug_finalize);
/* --------------------------------------------------------------------------
ACPI-based IOAPIC Configuration
diff --git a/arch/i386/pci/direct.c b/arch/i386/pci/direct.c
index 69fd22258831..be3ae9dd70e7 100644
--- a/arch/i386/pci/direct.c
+++ b/arch/i386/pci/direct.c
@@ -261,7 +261,6 @@ static int __init pci_direct_init(void)
}
local_irq_restore(flags);
- pci_root_ops = NULL;
return 0;
}
diff --git a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c
index fb7ba6defbc4..de88091e4646 100644
--- a/arch/m68k/lib/checksum.c
+++ b/arch/m68k/lib/checksum.c
@@ -243,7 +243,7 @@ csum_partial_copy_from_user(const char *src, char *dst, int len,
"8:\n"
".section .fixup,\"ax\"\n"
".even\n"
- /* If any execption occurs zero out the rest.
+ /* If any exception occurs zero out the rest.
Similarities with the code above are intentional :-) */
"90:\t"
"clrw %3@+\n\t"
diff --git a/arch/mips64/Kconfig b/arch/mips64/Kconfig
index 90682d90e7c5..40620ceced66 100644
--- a/arch/mips64/Kconfig
+++ b/arch/mips64/Kconfig
@@ -693,7 +693,7 @@ config CROSSCOMPILE
architecture than the one it is intended to run on.
config MIPS_FPE_MODULE
- bool "Build fp execption handler module"
+ bool "Build fp exception handler module"
depends on MODULES
help
Build the floating point exception handler module. This option is
diff --git a/drivers/Makefile b/drivers/Makefile
index 3d0d038eb6ad..2d983c7d9271 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -8,6 +8,9 @@
obj-$(CONFIG_PCI) += pci/
obj-$(CONFIG_PARISC) += parisc/
obj-$(CONFIG_ACPI) += acpi/
+# PnP must come after ACPI since it will eventually need to check if acpi
+# was used and do nothing if so
+obj-$(CONFIG_PNP) += pnp/
obj-y += serial/
obj-$(CONFIG_PARPORT) += parport/
obj-y += base/ char/ block/ misc/ net/ media/
@@ -26,7 +29,6 @@ obj-$(CONFIG_SBUS) += sbus/
obj-$(CONFIG_ZORRO) += zorro/
obj-$(CONFIG_ALL_PPC) += macintosh/
obj-$(CONFIG_MAC) += macintosh/
-obj-$(CONFIG_PNP) += pnp/
obj-$(CONFIG_SGI) += sgi/
obj-$(CONFIG_VT) += video/
obj-$(CONFIG_PARIDE) += block/paride/
diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c
index d9e3ab77df00..32e4dbc070c2 100644
--- a/drivers/acpi/namespace/nsxfobj.c
+++ b/drivers/acpi/namespace/nsxfobj.c
@@ -141,7 +141,7 @@ acpi_get_parent (
*ret_handle =
acpi_ns_convert_entry_to_handle (acpi_ns_get_parent_node (node));
- /* Return exeption if parent is null */
+ /* Return exception if parent is null */
if (!acpi_ns_get_parent_node (node)) {
status = AE_NULL_ENTRY;
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index b64c7facfd4f..c28072cbb910 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -19,8 +19,8 @@
*/
-#define DAC960_DriverVersion "2.4.11"
-#define DAC960_DriverDate "11 October 2001"
+#define DAC960_DriverVersion "2.5.47"
+#define DAC960_DriverDate "14 November 2002"
#include <linux/version.h>
@@ -56,16 +56,6 @@
static int
DAC960_ControllerCount = 0;
-
-/*
- DAC960_ActiveControllerCount is the number of active DAC960 Controllers
- detected.
-*/
-
-static int
- DAC960_ActiveControllerCount = 0;
-
-
/*
DAC960_Controllers is an array of pointers to the DAC960 Controller
structures.
@@ -82,11 +72,11 @@ static int DAC960_revalidate(struct gendisk *);
*/
static struct block_device_operations DAC960_BlockDeviceOperations = {
- .owner = THIS_MODULE,
- .open = DAC960_Open,
- .release = DAC960_Release,
- .ioctl = DAC960_IOCTL,
- .revalidate_disk= DAC960_revalidate,
+ .owner =THIS_MODULE,
+ .open =DAC960_Open,
+ .release =DAC960_Release,
+ .ioctl =DAC960_IOCTL,
+ .revalidate_disk=DAC960_revalidate,
};
@@ -99,14 +89,6 @@ static PROC_DirectoryEntry_T
/*
- DAC960_NotifierBlock is the Notifier Block structure for DAC960 Driver.
-*/
-
-static NotifierBlock_T
- DAC960_NotifierBlock = { DAC960_Notifier, NULL, 0 };
-
-
-/*
DAC960_AnnounceDriver announces the Driver Version and Date, Author's Name,
Copyright Notice, and Electronic Mail Address.
*/
@@ -144,6 +126,54 @@ static boolean DAC960_Failure(DAC960_Controller_T *Controller,
return false;
}
+/*
+ init_dma_loaf() and slice_dma_loaf() are helper functions for
+ aggregating the dma-mapped memory for a well-known collection of
+ data structures that are of different lengths.
+
+ These routines don't guarantee any alignment. The caller must
+ include any space needed for alignment in the sizes of the structures
+ that are passed in.
+ */
+
+static boolean init_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf,
+ size_t len)
+{
+ void *cpu_addr;
+ dma_addr_t dma_handle;
+
+ cpu_addr = pci_alloc_consistent(dev, len, &dma_handle);
+ if (cpu_addr == NULL)
+ return false;
+
+ loaf->cpu_free = loaf->cpu_base = cpu_addr;
+ loaf->dma_free =loaf->dma_base = dma_handle;
+ loaf->length = len;
+ memset(cpu_addr, 0, len);
+ return true;
+}
+
+static void *slice_dma_loaf(struct dma_loaf *loaf, size_t len,
+ dma_addr_t *dma_handle)
+{
+ void *cpu_end = loaf->cpu_free + len;
+ void *cpu_addr = loaf->cpu_free;
+
+ if (cpu_end > loaf->cpu_base + loaf->length)
+ BUG();
+ *dma_handle = loaf->dma_free;
+ loaf->cpu_free = cpu_end;
+ loaf->dma_free += len;
+ return cpu_addr;
+}
+
+static void free_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf_handle)
+{
+ if (loaf_handle->cpu_base != NULL)
+ pci_free_consistent(dev, loaf_handle->length,
+ loaf_handle->cpu_base, loaf_handle->dma_base);
+}
+
/*
DAC960_CreateAuxiliaryStructures allocates and initializes the auxiliary
@@ -156,15 +186,42 @@ static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
int CommandAllocationLength, CommandAllocationGroupSize;
int CommandsRemaining = 0, CommandIdentifier, CommandGroupByteCount;
void *AllocationPointer = NULL;
+ void *ScatterGatherCPU = NULL;
+ dma_addr_t ScatterGatherDMA;
+ struct pci_pool *ScatterGatherPool;
+ void *RequestSenseCPU = NULL;
+ dma_addr_t RequestSenseDMA;
+ struct pci_pool *RequestSensePool = NULL;
+
if (Controller->FirmwareType == DAC960_V1_Controller)
{
CommandAllocationLength = offsetof(DAC960_Command_T, V1.EndMarker);
CommandAllocationGroupSize = DAC960_V1_CommandAllocationGroupSize;
+ ScatterGatherPool = pci_pool_create("DAC960_V1_ScatterGather",
+ Controller->PCIDevice,
+ DAC960_V1_ScatterGatherLimit * sizeof(DAC960_V1_ScatterGatherSegment_T),
+ sizeof(DAC960_V1_ScatterGatherSegment_T), 0);
+ if (ScatterGatherPool == NULL)
+ return DAC960_Failure(Controller,
+ "AUXILIARY STRUCTURE CREATION (SG)");
+ Controller->ScatterGatherPool = ScatterGatherPool;
}
else
{
CommandAllocationLength = offsetof(DAC960_Command_T, V2.EndMarker);
CommandAllocationGroupSize = DAC960_V2_CommandAllocationGroupSize;
+ ScatterGatherPool = pci_pool_create("DAC960_V2_ScatterGather",
+ Controller->PCIDevice,
+ DAC960_V2_ScatterGatherLimit * sizeof(DAC960_V2_ScatterGatherSegment_T),
+ sizeof(DAC960_V2_ScatterGatherSegment_T), 0);
+ RequestSensePool = pci_pool_create("DAC960_V2_RequestSense",
+ Controller->PCIDevice, sizeof(DAC960_SCSI_RequestSense_T),
+ sizeof(int), 0);
+ if (ScatterGatherPool == NULL || RequestSensePool == NULL)
+ return DAC960_Failure(Controller,
+ "AUXILIARY STRUCTURE CREATION (SG)");
+ Controller->ScatterGatherPool = ScatterGatherPool;
+ Controller->V2.RequestSensePool = RequestSensePool;
}
Controller->CommandAllocationGroupSize = CommandAllocationGroupSize;
Controller->FreeCommands = NULL;
@@ -176,16 +233,17 @@ static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
if (--CommandsRemaining <= 0)
{
CommandsRemaining =
- Controller->DriverQueueDepth - CommandIdentifier + 1;
+ Controller->DriverQueueDepth - CommandIdentifier + 1;
if (CommandsRemaining > CommandAllocationGroupSize)
- CommandsRemaining = CommandAllocationGroupSize;
+ CommandsRemaining = CommandAllocationGroupSize;
CommandGroupByteCount =
- CommandsRemaining * CommandAllocationLength;
+ CommandsRemaining * CommandAllocationLength;
AllocationPointer = kmalloc(CommandGroupByteCount, GFP_ATOMIC);
if (AllocationPointer == NULL)
- return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION");
+ return DAC960_Failure(Controller,
+ "AUXILIARY STRUCTURE CREATION");
memset(AllocationPointer, 0, CommandGroupByteCount);
- }
+ }
Command = (DAC960_Command_T *) AllocationPointer;
AllocationPointer += CommandAllocationLength;
Command->CommandIdentifier = CommandIdentifier;
@@ -193,6 +251,33 @@ static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
Command->Next = Controller->FreeCommands;
Controller->FreeCommands = Command;
Controller->Commands[CommandIdentifier-1] = Command;
+ ScatterGatherCPU = pci_pool_alloc(ScatterGatherPool, SLAB_ATOMIC,
+ &ScatterGatherDMA);
+ if (ScatterGatherCPU == NULL)
+ return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION");
+
+ if (RequestSensePool != NULL) {
+ RequestSenseCPU = pci_pool_alloc(RequestSensePool, SLAB_ATOMIC,
+ &RequestSenseDMA);
+ if (RequestSenseCPU == NULL) {
+ pci_pool_free(ScatterGatherPool, ScatterGatherCPU,
+ ScatterGatherDMA);
+ return DAC960_Failure(Controller,
+ "AUXILIARY STRUCTURE CREATION");
+ }
+ }
+ if (Controller->FirmwareType == DAC960_V1_Controller) {
+ Command->V1.ScatterGatherList =
+ (DAC960_V1_ScatterGatherSegment_T *)ScatterGatherCPU;
+ Command->V1.ScatterGatherListDMA = ScatterGatherDMA;
+ } else {
+ Command->V2.ScatterGatherList =
+ (DAC960_V2_ScatterGatherSegment_T *)ScatterGatherCPU;
+ Command->V2.ScatterGatherListDMA = ScatterGatherDMA;
+ Command->V2.RequestSense =
+ (DAC960_SCSI_RequestSense_T *)RequestSenseCPU;
+ Command->V2.RequestSenseDMA = RequestSenseDMA;
+ }
}
return true;
}
@@ -206,29 +291,80 @@ static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
{
int i;
+ struct pci_pool *ScatterGatherPool = Controller->ScatterGatherPool;
+ struct pci_pool *RequestSensePool = NULL;
+ void *ScatterGatherCPU;
+ dma_addr_t ScatterGatherDMA;
+ void *RequestSenseCPU;
+ dma_addr_t RequestSenseDMA;
+ DAC960_Command_T *CommandGroup = NULL;
+
+
+ if (Controller->FirmwareType == DAC960_V2_Controller)
+ RequestSensePool = Controller->V2.RequestSensePool;
+
Controller->FreeCommands = NULL;
for (i = 0; i < Controller->DriverQueueDepth; i++)
{
DAC960_Command_T *Command = Controller->Commands[i];
- if (Command != NULL &&
- (Command->CommandIdentifier
- % Controller->CommandAllocationGroupSize) == 1)
- kfree(Command);
+
+ if (Command == NULL)
+ continue;
+
+ if (Controller->FirmwareType == DAC960_V1_Controller) {
+ ScatterGatherCPU = (void *)Command->V1.ScatterGatherList;
+ ScatterGatherDMA = Command->V1.ScatterGatherListDMA;
+ RequestSenseCPU = NULL;
+ RequestSenseDMA = (dma_addr_t)0;
+ } else {
+ ScatterGatherCPU = (void *)Command->V2.ScatterGatherList;
+ ScatterGatherDMA = Command->V2.ScatterGatherListDMA;
+ RequestSenseCPU = (void *)Command->V2.RequestSense;
+ RequestSenseDMA = Command->V2.RequestSenseDMA;
+ }
+ if (ScatterGatherCPU != NULL)
+ pci_pool_free(ScatterGatherPool, ScatterGatherCPU, ScatterGatherDMA);
+ if (RequestSenseCPU != NULL)
+ pci_pool_free(RequestSensePool, RequestSenseCPU, RequestSenseDMA);
+
+ if ((Command->CommandIdentifier
+ % Controller->CommandAllocationGroupSize) == 1) {
+ /*
+ * We can't free the group of commands until all of the
+ * request sense and scatter gather dma structures are free.
+ * Remember the beginning of the group, but don't free it
+ * until we've reached the beginning of the next group.
+ */
+ if (CommandGroup != NULL)
+ kfree(CommandGroup);
+ CommandGroup = Command;
+ }
Controller->Commands[i] = NULL;
}
+ if (CommandGroup != NULL)
+ kfree(CommandGroup);
+
if (Controller->CombinedStatusBuffer != NULL)
{
kfree(Controller->CombinedStatusBuffer);
Controller->CombinedStatusBuffer = NULL;
Controller->CurrentStatusBuffer = NULL;
}
+
+ if (ScatterGatherPool != NULL)
+ pci_pool_destroy(ScatterGatherPool);
if (Controller->FirmwareType == DAC960_V1_Controller) return;
+
+ if (RequestSensePool != NULL)
+ pci_pool_destroy(RequestSensePool);
+
for (i = 0; i < DAC960_MaxLogicalDrives; i++)
if (Controller->V2.LogicalDeviceInformation[i] != NULL)
{
kfree(Controller->V2.LogicalDeviceInformation[i]);
Controller->V2.LogicalDeviceInformation[i] = NULL;
}
+
for (i = 0; i < DAC960_V2_MaxPhysicalDevices; i++)
{
if (Controller->V2.PhysicalDeviceInformation[i] != NULL)
@@ -297,6 +433,8 @@ static inline DAC960_Command_T *DAC960_AllocateCommand(DAC960_Controller_T
static inline void DAC960_DeallocateCommand(DAC960_Command_T *Command)
{
DAC960_Controller_T *Controller = Command->Controller;
+
+ Command->Request = NULL;
Command->Next = Controller->FreeCommands;
Controller->FreeCommands = Command;
}
@@ -308,9 +446,9 @@ static inline void DAC960_DeallocateCommand(DAC960_Command_T *Command)
static void DAC960_WaitForCommand(DAC960_Controller_T *Controller)
{
- spin_unlock_irq(Controller->RequestQueue.queue_lock);
+ spin_unlock_irq(&Controller->queue_lock);
__wait_event(Controller->CommandWaitQueue, Controller->FreeCommands);
- spin_lock_irq(Controller->RequestQueue.queue_lock);
+ spin_lock_irq(&Controller->queue_lock);
}
@@ -557,7 +695,7 @@ static void DAC960_ExecuteCommand(DAC960_Command_T *Command)
static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
DAC960_V1_CommandOpcode_T CommandOpcode,
- void *DataPointer)
+ dma_addr_t DataDMA)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
@@ -565,7 +703,7 @@ static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
DAC960_V1_ClearCommand(Command);
Command->CommandType = DAC960_ImmediateCommand;
CommandMailbox->Type3.CommandOpcode = CommandOpcode;
- CommandMailbox->Type3.BusAddress = Virtual_to_Bus32(DataPointer);
+ CommandMailbox->Type3.BusAddress = DataDMA;
DAC960_ExecuteCommand(Command);
CommandStatus = Command->V1.CommandStatus;
DAC960_DeallocateCommand(Command);
@@ -582,7 +720,7 @@ static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
static boolean DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller,
DAC960_V1_CommandOpcode_T CommandOpcode,
unsigned char CommandOpcode2,
- void *DataPointer)
+ dma_addr_t DataDMA)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
@@ -591,7 +729,7 @@ static boolean DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller,
Command->CommandType = DAC960_ImmediateCommand;
CommandMailbox->Type3B.CommandOpcode = CommandOpcode;
CommandMailbox->Type3B.CommandOpcode2 = CommandOpcode2;
- CommandMailbox->Type3B.BusAddress = Virtual_to_Bus32(DataPointer);
+ CommandMailbox->Type3B.BusAddress = DataDMA;
DAC960_ExecuteCommand(Command);
CommandStatus = Command->V1.CommandStatus;
DAC960_DeallocateCommand(Command);
@@ -609,7 +747,7 @@ static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
DAC960_V1_CommandOpcode_T CommandOpcode,
unsigned char Channel,
unsigned char TargetID,
- void *DataPointer)
+ dma_addr_t DataDMA)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
@@ -619,7 +757,7 @@ static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
CommandMailbox->Type3D.CommandOpcode = CommandOpcode;
CommandMailbox->Type3D.Channel = Channel;
CommandMailbox->Type3D.TargetID = TargetID;
- CommandMailbox->Type3D.BusAddress = Virtual_to_Bus32(DataPointer);
+ CommandMailbox->Type3D.BusAddress = DataDMA;
DAC960_ExecuteCommand(Command);
CommandStatus = Command->V1.CommandStatus;
DAC960_DeallocateCommand(Command);
@@ -631,12 +769,11 @@ static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
DAC960_V2_GeneralInfo executes a DAC960 V2 Firmware General Information
Reading IOCTL Command and waits for completion. It returns true on success
and false on failure.
+
+ Return data in The controller's HealthStatusBuffer, which is dma-able memory
*/
-static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller,
- DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
- void *DataPointer,
- unsigned int DataByteCount)
+static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
@@ -648,12 +785,12 @@ static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller,
.DataTransferControllerToHost = true;
CommandMailbox->Common.CommandControlBits
.NoAutoRequestSense = true;
- CommandMailbox->Common.DataTransferSize = DataByteCount;
- CommandMailbox->Common.IOCTL_Opcode = IOCTL_Opcode;
+ CommandMailbox->Common.DataTransferSize = sizeof(DAC960_V2_HealthStatusBuffer_T);
+ CommandMailbox->Common.IOCTL_Opcode = DAC960_V2_GetHealthStatus;
CommandMailbox->Common.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentDataPointer =
- Virtual_to_Bus64(DataPointer);
+ Controller->V2.HealthStatusBufferDMA;
CommandMailbox->Common.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentByteCount =
@@ -669,12 +806,12 @@ static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller,
DAC960_V2_ControllerInfo executes a DAC960 V2 Firmware Controller
Information Reading IOCTL Command and waits for completion. It returns
true on success and false on failure.
+
+ Data is returned in the controller's V2.NewControllerInformation dma-able
+ memory buffer.
*/
-static boolean DAC960_V2_ControllerInfo(DAC960_Controller_T *Controller,
- DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
- void *DataPointer,
- unsigned int DataByteCount)
+static boolean DAC960_V2_NewControllerInfo(DAC960_Controller_T *Controller)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
@@ -686,13 +823,13 @@ static boolean DAC960_V2_ControllerInfo(DAC960_Controller_T *Controller,
.DataTransferControllerToHost = true;
CommandMailbox->ControllerInfo.CommandControlBits
.NoAutoRequestSense = true;
- CommandMailbox->ControllerInfo.DataTransferSize = DataByteCount;
+ CommandMailbox->ControllerInfo.DataTransferSize = sizeof(DAC960_V2_ControllerInfo_T);
CommandMailbox->ControllerInfo.ControllerNumber = 0;
- CommandMailbox->ControllerInfo.IOCTL_Opcode = IOCTL_Opcode;
+ CommandMailbox->ControllerInfo.IOCTL_Opcode = DAC960_V2_GetControllerInfo;
CommandMailbox->ControllerInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentDataPointer =
- Virtual_to_Bus64(DataPointer);
+ Controller->V2.NewControllerInformationDMA;
CommandMailbox->ControllerInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentByteCount =
@@ -708,34 +845,34 @@ static boolean DAC960_V2_ControllerInfo(DAC960_Controller_T *Controller,
DAC960_V2_LogicalDeviceInfo executes a DAC960 V2 Firmware Controller Logical
Device Information Reading IOCTL Command and waits for completion. It
returns true on success and false on failure.
+
+ Data is returned in the controller's V2.NewLogicalDeviceInformation
*/
-static boolean DAC960_V2_LogicalDeviceInfo(DAC960_Controller_T *Controller,
- DAC960_V2_IOCTL_Opcode_T
- IOCTL_Opcode,
- unsigned short
- LogicalDeviceNumber,
- void *DataPointer,
- unsigned int DataByteCount)
+static boolean DAC960_V2_NewLogicalDeviceInfo(DAC960_Controller_T *Controller,
+ unsigned short LogicalDeviceNumber)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
DAC960_V2_CommandStatus_T CommandStatus;
+
DAC960_V2_ClearCommand(Command);
Command->CommandType = DAC960_ImmediateCommand;
- CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox->LogicalDeviceInfo.CommandOpcode =
+ DAC960_V2_IOCTL;
CommandMailbox->LogicalDeviceInfo.CommandControlBits
.DataTransferControllerToHost = true;
CommandMailbox->LogicalDeviceInfo.CommandControlBits
.NoAutoRequestSense = true;
- CommandMailbox->LogicalDeviceInfo.DataTransferSize = DataByteCount;
+ CommandMailbox->LogicalDeviceInfo.DataTransferSize =
+ sizeof(DAC960_V2_LogicalDeviceInfo_T);
CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
LogicalDeviceNumber;
- CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
+ CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode = DAC960_V2_GetLogicalDeviceInfoValid;
CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentDataPointer =
- Virtual_to_Bus64(DataPointer);
+ Controller->V2.NewLogicalDeviceInformationDMA;
CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentByteCount =
@@ -748,23 +885,30 @@ static boolean DAC960_V2_LogicalDeviceInfo(DAC960_Controller_T *Controller,
/*
- DAC960_V2_PhysicalDeviceInfo executes a DAC960 V2 Firmware Controller Physical
- Device Information Reading IOCTL Command and waits for completion. It
+ DAC960_V2_PhysicalDeviceInfo executes a DAC960 V2 Firmware Controller "Read
+ Physical Device Information" IOCTL Command and waits for completion. It
returns true on success and false on failure.
+
+ The Channel, TargetID, LogicalUnit arguments should be 0 the first time
+ this function is called for a given controller. This will return data
+ for the "first" device on that controller. The returned data includes a
+ Channel, TargetID, LogicalUnit that can be passed in to this routine to
+ get data for the NEXT device on that controller.
+
+ Data is stored in the controller's V2.NewPhysicalDeviceInfo dma-able
+ memory buffer.
+
*/
-static boolean DAC960_V2_PhysicalDeviceInfo(DAC960_Controller_T *Controller,
- DAC960_V2_IOCTL_Opcode_T
- IOCTL_Opcode,
+static boolean DAC960_V2_NewPhysicalDeviceInfo(DAC960_Controller_T *Controller,
unsigned char Channel,
unsigned char TargetID,
- unsigned char LogicalUnit,
- void *DataPointer,
- unsigned int DataByteCount)
+ unsigned char LogicalUnit)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
DAC960_V2_CommandStatus_T CommandStatus;
+
DAC960_V2_ClearCommand(Command);
Command->CommandType = DAC960_ImmediateCommand;
CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
@@ -772,15 +916,17 @@ static boolean DAC960_V2_PhysicalDeviceInfo(DAC960_Controller_T *Controller,
.DataTransferControllerToHost = true;
CommandMailbox->PhysicalDeviceInfo.CommandControlBits
.NoAutoRequestSense = true;
- CommandMailbox->PhysicalDeviceInfo.DataTransferSize = DataByteCount;
+ CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
+ sizeof(DAC960_V2_PhysicalDeviceInfo_T);
CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit = LogicalUnit;
CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
- CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
+ CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
+ DAC960_V2_GetPhysicalDeviceInfoValid;
CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentDataPointer =
- Virtual_to_Bus64(DataPointer);
+ Controller->V2.NewPhysicalDeviceInformationDMA;
CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentByteCount =
@@ -792,6 +938,75 @@ static boolean DAC960_V2_PhysicalDeviceInfo(DAC960_Controller_T *Controller,
}
+static void DAC960_V2_ConstructNewUnitSerialNumber(
+ DAC960_Controller_T *Controller,
+ DAC960_V2_CommandMailbox_T *CommandMailbox, int Channel, int TargetID,
+ int LogicalUnit)
+{
+ CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10_Passthru;
+ CommandMailbox->SCSI_10.CommandControlBits
+ .DataTransferControllerToHost = true;
+ CommandMailbox->SCSI_10.CommandControlBits
+ .NoAutoRequestSense = true;
+ CommandMailbox->SCSI_10.DataTransferSize =
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+ CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit = LogicalUnit;
+ CommandMailbox->SCSI_10.PhysicalDevice.TargetID = TargetID;
+ CommandMailbox->SCSI_10.PhysicalDevice.Channel = Channel;
+ CommandMailbox->SCSI_10.CDBLength = 6;
+ CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
+ CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
+ CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
+ CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
+ CommandMailbox->SCSI_10.SCSI_CDB[4] =
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+ CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentDataPointer =
+ Controller->V2.NewInquiryUnitSerialNumberDMA;
+ CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ .ScatterGatherSegments[0]
+ .SegmentByteCount =
+ CommandMailbox->SCSI_10.DataTransferSize;
+}
+
+
+/*
+ DAC960_V2_NewUnitSerialNumber executes an SCSI pass-through
+ Inquiry command to a SCSI device identified by Channel number,
+ Target id, Logical Unit Number. This function Waits for completion
+ of the command.
+
+ The return data includes Unit Serial Number information for the
+ specified device.
+
+ Data is stored in the controller's V2.NewPhysicalDeviceInfo dma-able
+ memory buffer.
+*/
+
+static boolean DAC960_V2_NewInquiryUnitSerialNumber(DAC960_Controller_T *Controller,
+ int Channel, int TargetID, int LogicalUnit)
+{
+ DAC960_Command_T *Command;
+ DAC960_V2_CommandMailbox_T *CommandMailbox;
+ DAC960_V2_CommandStatus_T CommandStatus;
+
+ Command = DAC960_AllocateCommand(Controller);
+ CommandMailbox = &Command->V2.CommandMailbox;
+ DAC960_V2_ClearCommand(Command);
+ Command->CommandType = DAC960_ImmediateCommand;
+
+ DAC960_V2_ConstructNewUnitSerialNumber(Controller, CommandMailbox,
+ Channel, TargetID, LogicalUnit);
+
+ DAC960_ExecuteCommand(Command);
+ CommandStatus = Command->V2.CommandStatus;
+ DAC960_DeallocateCommand(Command);
+ return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
/*
DAC960_V2_DeviceOperation executes a DAC960 V2 Firmware Controller Device
Operation IOCTL Command and waits for completion. It returns true on
@@ -825,84 +1040,144 @@ static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller,
/*
DAC960_V1_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
for DAC960 V1 Firmware Controllers.
+
+ PD and P controller types have no memory mailbox, but still need the
+ other dma mapped memory.
*/
static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
*Controller)
{
void *ControllerBaseAddress = Controller->BaseAddress;
+ DAC960_HardwareType_T hw_type = Controller->HardwareType;
+ PCI_Device_T *PCI_Device = Controller->PCIDevice;
+ struct dma_loaf *DmaPages = &Controller->DmaPages;
+ size_t DmaPagesSize;
+ size_t CommandMailboxesSize;
+ size_t StatusMailboxesSize;
+
DAC960_V1_CommandMailbox_T *CommandMailboxesMemory;
+ dma_addr_t CommandMailboxesMemoryDMA;
+
DAC960_V1_StatusMailbox_T *StatusMailboxesMemory;
+ dma_addr_t StatusMailboxesMemoryDMA;
+
DAC960_V1_CommandMailbox_T CommandMailbox;
DAC960_V1_CommandStatus_T CommandStatus;
- unsigned long MemoryMailboxPagesAddress;
- unsigned long MemoryMailboxPagesOrder;
- unsigned long MemoryMailboxPagesSize;
- void *SavedMemoryMailboxesAddress = NULL;
- short NextCommandMailboxIndex = 0;
- short NextStatusMailboxIndex = 0;
- int TimeoutCounter = 1000000, i;
- MemoryMailboxPagesOrder = 0;
- MemoryMailboxPagesSize =
- DAC960_V1_CommandMailboxCount * sizeof(DAC960_V1_CommandMailbox_T) +
- DAC960_V1_StatusMailboxCount * sizeof(DAC960_V1_StatusMailbox_T);
- while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
- MemoryMailboxPagesOrder++;
- if (Controller->HardwareType == DAC960_LA_Controller)
- DAC960_LA_RestoreMemoryMailboxInfo(Controller,
- &SavedMemoryMailboxesAddress,
- &NextCommandMailboxIndex,
- &NextStatusMailboxIndex);
- else DAC960_PG_RestoreMemoryMailboxInfo(Controller,
- &SavedMemoryMailboxesAddress,
- &NextCommandMailboxIndex,
- &NextStatusMailboxIndex);
- if (SavedMemoryMailboxesAddress == NULL)
- {
- MemoryMailboxPagesAddress =
- __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
- Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
- CommandMailboxesMemory =
- (DAC960_V1_CommandMailbox_T *) MemoryMailboxPagesAddress;
- }
- else CommandMailboxesMemory = SavedMemoryMailboxesAddress;
- if (CommandMailboxesMemory == NULL) return false;
- Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
- memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
+ int TimeoutCounter;
+ int i;
+
+
+ if (pci_set_dma_mask(Controller->PCIDevice, DAC690_V1_PciDmaMask))
+ return DAC960_Failure(Controller, "DMA mask out of range");
+
+ if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller)) {
+ CommandMailboxesSize = 0;
+ StatusMailboxesSize = 0;
+ } else {
+ CommandMailboxesSize = DAC960_V1_CommandMailboxCount * sizeof(DAC960_V1_CommandMailbox_T);
+ StatusMailboxesSize = DAC960_V1_StatusMailboxCount * sizeof(DAC960_V1_StatusMailbox_T);
+ }
+ DmaPagesSize = CommandMailboxesSize + StatusMailboxesSize +
+ sizeof(DAC960_V1_DCDB_T) + sizeof(DAC960_V1_Enquiry_T) +
+ sizeof(DAC960_V1_ErrorTable_T) + sizeof(DAC960_V1_EventLogEntry_T) +
+ sizeof(DAC960_V1_RebuildProgress_T) +
+ sizeof(DAC960_V1_LogicalDriveInformationArray_T) +
+ sizeof(DAC960_V1_BackgroundInitializationStatus_T) +
+ sizeof(DAC960_V1_DeviceState_T) + sizeof(DAC960_SCSI_Inquiry_T) +
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+
+ if (!init_dma_loaf(PCI_Device, DmaPages, DmaPagesSize))
+ return false;
+
+
+ if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller))
+ goto skip_mailboxes;
+
+ CommandMailboxesMemory = slice_dma_loaf(DmaPages,
+ CommandMailboxesSize, &CommandMailboxesMemoryDMA);
+
+ /* These are the base addresses for the command memory mailbox array */
Controller->V1.FirstCommandMailbox = CommandMailboxesMemory;
+ Controller->V1.FirstCommandMailboxDMA = CommandMailboxesMemoryDMA;
+
CommandMailboxesMemory += DAC960_V1_CommandMailboxCount - 1;
Controller->V1.LastCommandMailbox = CommandMailboxesMemory;
- Controller->V1.NextCommandMailbox =
- &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
- if (--NextCommandMailboxIndex < 0)
- NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
- Controller->V1.PreviousCommandMailbox1 =
- &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
- if (--NextCommandMailboxIndex < 0)
- NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
+ Controller->V1.NextCommandMailbox = Controller->V1.FirstCommandMailbox;
+ Controller->V1.PreviousCommandMailbox1 = Controller->V1.LastCommandMailbox;
Controller->V1.PreviousCommandMailbox2 =
- &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
- StatusMailboxesMemory =
- (DAC960_V1_StatusMailbox_T *) (CommandMailboxesMemory + 1);
+ Controller->V1.LastCommandMailbox - 1;
+
+ /* These are the base addresses for the status memory mailbox array */
+ StatusMailboxesMemory = slice_dma_loaf(DmaPages,
+ StatusMailboxesSize, &StatusMailboxesMemoryDMA);
+
Controller->V1.FirstStatusMailbox = StatusMailboxesMemory;
+ Controller->V1.FirstStatusMailboxDMA = StatusMailboxesMemoryDMA;
StatusMailboxesMemory += DAC960_V1_StatusMailboxCount - 1;
Controller->V1.LastStatusMailbox = StatusMailboxesMemory;
- Controller->V1.NextStatusMailbox =
- &Controller->V1.FirstStatusMailbox[NextStatusMailboxIndex];
- if (SavedMemoryMailboxesAddress != NULL) return true;
+ Controller->V1.NextStatusMailbox = Controller->V1.FirstStatusMailbox;
+
+skip_mailboxes:
+ Controller->V1.MonitoringDCDB = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V1_DCDB_T),
+ &Controller->V1.MonitoringDCDB_DMA);
+
+ Controller->V1.NewEnquiry = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V1_Enquiry_T),
+ &Controller->V1.NewEnquiryDMA);
+
+ Controller->V1.NewErrorTable = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V1_ErrorTable_T),
+ &Controller->V1.NewErrorTableDMA);
+
+ Controller->V1.EventLogEntry = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V1_EventLogEntry_T),
+ &Controller->V1.EventLogEntryDMA);
+
+ Controller->V1.RebuildProgress = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V1_RebuildProgress_T),
+ &Controller->V1.RebuildProgressDMA);
+
+ Controller->V1.NewLogicalDriveInformation = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V1_LogicalDriveInformationArray_T),
+ &Controller->V1.NewLogicalDriveInformationDMA);
+
+ Controller->V1.BackgroundInitializationStatus = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V1_BackgroundInitializationStatus_T),
+ &Controller->V1.BackgroundInitializationStatusDMA);
+
+ Controller->V1.NewDeviceState = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V1_DeviceState_T),
+ &Controller->V1.NewDeviceStateDMA);
+
+ Controller->V1.NewInquiryStandardData = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_SCSI_Inquiry_T),
+ &Controller->V1.NewInquiryStandardDataDMA);
+
+ Controller->V1.NewInquiryUnitSerialNumber = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T),
+ &Controller->V1.NewInquiryUnitSerialNumberDMA);
+
+ if ((hw_type == DAC960_PD_Controller) || (hw_type == DAC960_P_Controller))
+ return true;
+
/* Enable the Memory Mailbox Interface. */
Controller->V1.DualModeMemoryMailboxInterface = true;
CommandMailbox.TypeX.CommandOpcode = 0x2B;
CommandMailbox.TypeX.CommandIdentifier = 0;
CommandMailbox.TypeX.CommandOpcode2 = 0x14;
CommandMailbox.TypeX.CommandMailboxesBusAddress =
- Virtual_to_Bus32(Controller->V1.FirstCommandMailbox);
+ Controller->V1.FirstCommandMailboxDMA;
CommandMailbox.TypeX.StatusMailboxesBusAddress =
- Virtual_to_Bus32(Controller->V1.FirstStatusMailbox);
+ Controller->V1.FirstStatusMailboxDMA;
+#define TIMEOUT_COUNT 1000000
+
for (i = 0; i < 2; i++)
switch (Controller->HardwareType)
{
case DAC960_LA_Controller:
+ TimeoutCounter = TIMEOUT_COUNT;
while (--TimeoutCounter >= 0)
{
if (!DAC960_LA_HardwareMailboxFullP(ControllerBaseAddress))
@@ -912,6 +1187,7 @@ static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
if (TimeoutCounter < 0) return false;
DAC960_LA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
+ TimeoutCounter = TIMEOUT_COUNT;
while (--TimeoutCounter >= 0)
{
if (DAC960_LA_HardwareMailboxStatusAvailableP(
@@ -928,6 +1204,7 @@ static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
CommandMailbox.TypeX.CommandOpcode2 = 0x10;
break;
case DAC960_PG_Controller:
+ TimeoutCounter = TIMEOUT_COUNT;
while (--TimeoutCounter >= 0)
{
if (!DAC960_PG_HardwareMailboxFullP(ControllerBaseAddress))
@@ -937,6 +1214,8 @@ static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
if (TimeoutCounter < 0) return false;
DAC960_PG_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
+
+ TimeoutCounter = TIMEOUT_COUNT;
while (--TimeoutCounter >= 0)
{
if (DAC960_PG_HardwareMailboxStatusAvailableP(
@@ -953,6 +1232,7 @@ static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
CommandMailbox.TypeX.CommandOpcode2 = 0x10;
break;
default:
+ DAC960_Failure(Controller, "Unknown Controller Type\n");
break;
}
return false;
@@ -962,75 +1242,146 @@ static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
/*
DAC960_V2_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
for DAC960 V2 Firmware Controllers.
+
+ Aggregate the space needed for the controller's memory mailbox and
+ the other data structures that will be targets of dma transfers with
+ the controller. Allocate a dma-mapped region of memory to hold these
+ structures. Then, save CPU pointers and dma_addr_t values to reference
+ the structures that are contained in that region.
*/
static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
*Controller)
{
void *ControllerBaseAddress = Controller->BaseAddress;
+ PCI_Device_T *PCI_Device = Controller->PCIDevice;
+ struct dma_loaf *DmaPages = &Controller->DmaPages;
+ size_t DmaPagesSize;
+ size_t CommandMailboxesSize;
+ size_t StatusMailboxesSize;
+
DAC960_V2_CommandMailbox_T *CommandMailboxesMemory;
+ dma_addr_t CommandMailboxesMemoryDMA;
+
DAC960_V2_StatusMailbox_T *StatusMailboxesMemory;
- DAC960_V2_CommandMailbox_T CommandMailbox;
- DAC960_V2_CommandStatus_T CommandStatus = 0;
- unsigned long MemoryMailboxPagesAddress;
- unsigned long MemoryMailboxPagesOrder;
- unsigned long MemoryMailboxPagesSize;
- MemoryMailboxPagesOrder = 0;
- MemoryMailboxPagesSize =
- DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T) +
- DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T) +
- sizeof(DAC960_V2_HealthStatusBuffer_T);
- while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
- MemoryMailboxPagesOrder++;
- MemoryMailboxPagesAddress =
- __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
- Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
- CommandMailboxesMemory =
- (DAC960_V2_CommandMailbox_T *) MemoryMailboxPagesAddress;
- if (CommandMailboxesMemory == NULL) return false;
- Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
- memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
+ dma_addr_t StatusMailboxesMemoryDMA;
+
+ DAC960_V2_CommandMailbox_T *CommandMailbox;
+ dma_addr_t CommandMailboxDMA;
+ DAC960_V2_CommandStatus_T CommandStatus;
+
+ if (pci_set_dma_mask(Controller->PCIDevice, DAC690_V2_PciDmaMask))
+ return DAC960_Failure(Controller, "DMA mask out of range");
+
+ /* This is a temporary dma mapping, used only in the scope of this function */
+ CommandMailbox =
+ (DAC960_V2_CommandMailbox_T *)pci_alloc_consistent( PCI_Device,
+ sizeof(DAC960_V2_CommandMailbox_T), &CommandMailboxDMA);
+ if (CommandMailbox == NULL)
+ return false;
+
+ CommandMailboxesSize = DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T);
+ StatusMailboxesSize = DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T);
+ DmaPagesSize =
+ CommandMailboxesSize + StatusMailboxesSize +
+ sizeof(DAC960_V2_HealthStatusBuffer_T) +
+ sizeof(DAC960_V2_ControllerInfo_T) +
+ sizeof(DAC960_V2_LogicalDeviceInfo_T) +
+ sizeof(DAC960_V2_PhysicalDeviceInfo_T) +
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T) +
+ sizeof(DAC960_V2_Event_T) +
+ sizeof(DAC960_V2_PhysicalToLogicalDevice_T);
+
+ if (!init_dma_loaf(PCI_Device, DmaPages, DmaPagesSize)) {
+ pci_free_consistent(PCI_Device, sizeof(DAC960_V2_CommandMailbox_T),
+ CommandMailbox, CommandMailboxDMA);
+ return false;
+ }
+
+ CommandMailboxesMemory = slice_dma_loaf(DmaPages,
+ CommandMailboxesSize, &CommandMailboxesMemoryDMA);
+
+ /* These are the base addresses for the command memory mailbox array */
Controller->V2.FirstCommandMailbox = CommandMailboxesMemory;
+ Controller->V2.FirstCommandMailboxDMA = CommandMailboxesMemoryDMA;
+
CommandMailboxesMemory += DAC960_V2_CommandMailboxCount - 1;
Controller->V2.LastCommandMailbox = CommandMailboxesMemory;
Controller->V2.NextCommandMailbox = Controller->V2.FirstCommandMailbox;
Controller->V2.PreviousCommandMailbox1 = Controller->V2.LastCommandMailbox;
Controller->V2.PreviousCommandMailbox2 =
- Controller->V2.LastCommandMailbox - 1;
- StatusMailboxesMemory =
- (DAC960_V2_StatusMailbox_T *) (CommandMailboxesMemory + 1);
+ Controller->V2.LastCommandMailbox - 1;
+
+ /* These are the base addresses for the status memory mailbox array */
+ StatusMailboxesMemory = slice_dma_loaf(DmaPages,
+ StatusMailboxesSize, &StatusMailboxesMemoryDMA);
+
Controller->V2.FirstStatusMailbox = StatusMailboxesMemory;
+ Controller->V2.FirstStatusMailboxDMA = StatusMailboxesMemoryDMA;
StatusMailboxesMemory += DAC960_V2_StatusMailboxCount - 1;
Controller->V2.LastStatusMailbox = StatusMailboxesMemory;
Controller->V2.NextStatusMailbox = Controller->V2.FirstStatusMailbox;
- Controller->V2.HealthStatusBuffer =
- (DAC960_V2_HealthStatusBuffer_T *) (StatusMailboxesMemory + 1);
- /* Enable the Memory Mailbox Interface. */
- memset(&CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));
- CommandMailbox.SetMemoryMailbox.CommandIdentifier = 1;
- CommandMailbox.SetMemoryMailbox.CommandOpcode = DAC960_V2_IOCTL;
- CommandMailbox.SetMemoryMailbox.CommandControlBits.NoAutoRequestSense = true;
- CommandMailbox.SetMemoryMailbox.FirstCommandMailboxSizeKB =
+
+ Controller->V2.HealthStatusBuffer = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V2_HealthStatusBuffer_T),
+ &Controller->V2.HealthStatusBufferDMA);
+
+ Controller->V2.NewControllerInformation = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V2_ControllerInfo_T),
+ &Controller->V2.NewControllerInformationDMA);
+
+ Controller->V2.NewLogicalDeviceInformation = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V2_LogicalDeviceInfo_T),
+ &Controller->V2.NewLogicalDeviceInformationDMA);
+
+ Controller->V2.NewPhysicalDeviceInformation = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V2_PhysicalDeviceInfo_T),
+ &Controller->V2.NewPhysicalDeviceInformationDMA);
+
+ Controller->V2.NewInquiryUnitSerialNumber = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T),
+ &Controller->V2.NewInquiryUnitSerialNumberDMA);
+
+ Controller->V2.Event = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V2_Event_T),
+ &Controller->V2.EventDMA);
+
+ Controller->V2.PhysicalToLogicalDevice = slice_dma_loaf(DmaPages,
+ sizeof(DAC960_V2_PhysicalToLogicalDevice_T),
+ &Controller->V2.PhysicalToLogicalDeviceDMA);
+
+ /*
+ Enable the Memory Mailbox Interface.
+
+ I don't know why we can't just use one of the memory mailboxes
+ we just allocated to do this, instead of using this temporary one.
+ Try this change later.
+ */
+ memset(CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));
+ CommandMailbox->SetMemoryMailbox.CommandIdentifier = 1;
+ CommandMailbox->SetMemoryMailbox.CommandOpcode = DAC960_V2_IOCTL;
+ CommandMailbox->SetMemoryMailbox.CommandControlBits.NoAutoRequestSense = true;
+ CommandMailbox->SetMemoryMailbox.FirstCommandMailboxSizeKB =
(DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T)) >> 10;
- CommandMailbox.SetMemoryMailbox.FirstStatusMailboxSizeKB =
+ CommandMailbox->SetMemoryMailbox.FirstStatusMailboxSizeKB =
(DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T)) >> 10;
- CommandMailbox.SetMemoryMailbox.SecondCommandMailboxSizeKB = 0;
- CommandMailbox.SetMemoryMailbox.SecondStatusMailboxSizeKB = 0;
- CommandMailbox.SetMemoryMailbox.RequestSenseSize = 0;
- CommandMailbox.SetMemoryMailbox.IOCTL_Opcode = DAC960_V2_SetMemoryMailbox;
- CommandMailbox.SetMemoryMailbox.HealthStatusBufferSizeKB = 1;
- CommandMailbox.SetMemoryMailbox.HealthStatusBufferBusAddress =
- Virtual_to_Bus64(Controller->V2.HealthStatusBuffer);
- CommandMailbox.SetMemoryMailbox.FirstCommandMailboxBusAddress =
- Virtual_to_Bus64(Controller->V2.FirstCommandMailbox);
- CommandMailbox.SetMemoryMailbox.FirstStatusMailboxBusAddress =
- Virtual_to_Bus64(Controller->V2.FirstStatusMailbox);
+ CommandMailbox->SetMemoryMailbox.SecondCommandMailboxSizeKB = 0;
+ CommandMailbox->SetMemoryMailbox.SecondStatusMailboxSizeKB = 0;
+ CommandMailbox->SetMemoryMailbox.RequestSenseSize = 0;
+ CommandMailbox->SetMemoryMailbox.IOCTL_Opcode = DAC960_V2_SetMemoryMailbox;
+ CommandMailbox->SetMemoryMailbox.HealthStatusBufferSizeKB = 1;
+ CommandMailbox->SetMemoryMailbox.HealthStatusBufferBusAddress =
+ Controller->V2.HealthStatusBufferDMA;
+ CommandMailbox->SetMemoryMailbox.FirstCommandMailboxBusAddress =
+ Controller->V2.FirstCommandMailboxDMA;
+ CommandMailbox->SetMemoryMailbox.FirstStatusMailboxBusAddress =
+ Controller->V2.FirstStatusMailboxDMA;
switch (Controller->HardwareType)
{
case DAC960_BA_Controller:
while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress))
udelay(1);
- DAC960_BA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+ DAC960_BA_WriteHardwareMailbox(ControllerBaseAddress, CommandMailboxDMA);
DAC960_BA_HardwareMailboxNewCommand(ControllerBaseAddress);
while (!DAC960_BA_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
udelay(1);
@@ -1041,7 +1392,7 @@ static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
case DAC960_LP_Controller:
while (DAC960_LP_HardwareMailboxFullP(ControllerBaseAddress))
udelay(1);
- DAC960_LP_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+ DAC960_LP_WriteHardwareMailbox(ControllerBaseAddress, CommandMailboxDMA);
DAC960_LP_HardwareMailboxNewCommand(ControllerBaseAddress);
while (!DAC960_LP_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
udelay(1);
@@ -1050,8 +1401,12 @@ static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
DAC960_LP_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
break;
default:
+ DAC960_Failure(Controller, "Unknown Controller Type\n");
+ CommandStatus = DAC960_V2_AbormalCompletion;
break;
}
+ pci_free_consistent(PCI_Device, sizeof(DAC960_V2_CommandMailbox_T),
+ CommandMailbox, CommandMailboxDMA);
return (CommandStatus == DAC960_V2_NormalCompletion);
}
@@ -1064,33 +1419,65 @@ static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
*Controller)
{
- DAC960_V1_Enquiry2_T Enquiry2;
- DAC960_V1_Config2_T Config2;
+ DAC960_V1_Enquiry2_T *Enquiry2;
+ dma_addr_t Enquiry2DMA;
+ DAC960_V1_Config2_T *Config2;
+ dma_addr_t Config2DMA;
int LogicalDriveNumber, Channel, TargetID;
+ struct dma_loaf local_dma;
+
+ if (!init_dma_loaf(Controller->PCIDevice, &local_dma,
+ sizeof(DAC960_V1_Enquiry2_T) + sizeof(DAC960_V1_Config2_T)))
+ return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION");
+
+ Enquiry2 = slice_dma_loaf(&local_dma, sizeof(DAC960_V1_Enquiry2_T), &Enquiry2DMA);
+ Config2 = slice_dma_loaf(&local_dma, sizeof(DAC960_V1_Config2_T), &Config2DMA);
+
if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry,
- &Controller->V1.Enquiry))
+ Controller->V1.NewEnquiryDMA)) {
+ free_dma_loaf(Controller->PCIDevice, &local_dma);
return DAC960_Failure(Controller, "ENQUIRY");
- if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry2, &Enquiry2))
+ }
+ memcpy(&Controller->V1.Enquiry, Controller->V1.NewEnquiry,
+ sizeof(DAC960_V1_Enquiry_T));
+
+ if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry2, Enquiry2DMA)) {
+ free_dma_loaf(Controller->PCIDevice, &local_dma);
return DAC960_Failure(Controller, "ENQUIRY2");
- if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_ReadConfig2, &Config2))
+ }
+
+ if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_ReadConfig2, Config2DMA)) {
+ free_dma_loaf(Controller->PCIDevice, &local_dma);
return DAC960_Failure(Controller, "READ CONFIG2");
+ }
+
if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_GetLogicalDriveInformation,
- &Controller->V1.LogicalDriveInformation))
+ Controller->V1.NewLogicalDriveInformationDMA)) {
+ free_dma_loaf(Controller->PCIDevice, &local_dma);
return DAC960_Failure(Controller, "GET LOGICAL DRIVE INFORMATION");
- for (Channel = 0; Channel < Enquiry2.ActualChannels; Channel++)
- for (TargetID = 0; TargetID < Enquiry2.MaxTargets; TargetID++)
+ }
+ memcpy(&Controller->V1.LogicalDriveInformation,
+ Controller->V1.NewLogicalDriveInformation,
+ sizeof(DAC960_V1_LogicalDriveInformationArray_T));
+
+ for (Channel = 0; Channel < Enquiry2->ActualChannels; Channel++)
+ for (TargetID = 0; TargetID < Enquiry2->MaxTargets; TargetID++) {
if (!DAC960_V1_ExecuteType3D(Controller, DAC960_V1_GetDeviceState,
Channel, TargetID,
- &Controller->V1.DeviceState
- [Channel][TargetID]))
- return DAC960_Failure(Controller, "GET DEVICE STATE");
+ Controller->V1.NewDeviceStateDMA)) {
+ free_dma_loaf(Controller->PCIDevice, &local_dma);
+ return DAC960_Failure(Controller, "GET DEVICE STATE");
+ }
+ memcpy(&Controller->V1.DeviceState[Channel][TargetID],
+ Controller->V1.NewDeviceState, sizeof(DAC960_V1_DeviceState_T));
+ }
/*
Initialize the Controller Model Name and Full Model Name fields.
*/
- switch (Enquiry2.HardwareID.SubModel)
+ switch (Enquiry2->HardwareID.SubModel)
{
case DAC960_V1_P_PD_PU:
- if (Enquiry2.SCSICapability.BusSpeed == DAC960_V1_Ultra)
+ if (Enquiry2->SCSICapability.BusSpeed == DAC960_V1_Ultra)
strcpy(Controller->ModelName, "DAC960PU");
else strcpy(Controller->ModelName, "DAC960PD");
break;
@@ -1122,6 +1509,7 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
strcpy(Controller->ModelName, "DAC1164P");
break;
default:
+ free_dma_loaf(Controller->PCIDevice, &local_dma);
return DAC960_Failure(Controller, "MODEL VERIFICATION");
}
strcpy(Controller->FullModelName, "Mylex ");
@@ -1135,18 +1523,18 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
DAC960PU/PD/PL 3.51 and above
DAC960PU/PD/PL/P 2.73 and above
*/
- if (Enquiry2.FirmwareID.MajorVersion == 0)
+ if (Enquiry2->FirmwareID.MajorVersion == 0)
{
- Enquiry2.FirmwareID.MajorVersion =
+ Enquiry2->FirmwareID.MajorVersion =
Controller->V1.Enquiry.MajorFirmwareVersion;
- Enquiry2.FirmwareID.MinorVersion =
+ Enquiry2->FirmwareID.MinorVersion =
Controller->V1.Enquiry.MinorFirmwareVersion;
- Enquiry2.FirmwareID.FirmwareType = '0';
- Enquiry2.FirmwareID.TurnID = 0;
+ Enquiry2->FirmwareID.FirmwareType = '0';
+ Enquiry2->FirmwareID.TurnID = 0;
}
sprintf(Controller->FirmwareVersion, "%d.%02d-%c-%02d",
- Enquiry2.FirmwareID.MajorVersion, Enquiry2.FirmwareID.MinorVersion,
- Enquiry2.FirmwareID.FirmwareType, Enquiry2.FirmwareID.TurnID);
+ Enquiry2->FirmwareID.MajorVersion, Enquiry2->FirmwareID.MinorVersion,
+ Enquiry2->FirmwareID.FirmwareType, Enquiry2->FirmwareID.TurnID);
if (!((Controller->FirmwareVersion[0] == '5' &&
strcmp(Controller->FirmwareVersion, "5.06") >= 0) ||
(Controller->FirmwareVersion[0] == '4' &&
@@ -1159,17 +1547,18 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
DAC960_Failure(Controller, "FIRMWARE VERSION VERIFICATION");
DAC960_Error("Firmware Version = '%s'\n", Controller,
Controller->FirmwareVersion);
+ free_dma_loaf(Controller->PCIDevice, &local_dma);
return false;
}
/*
Initialize the Controller Channels, Targets, Memory Size, and SAF-TE
Enclosure Management Enabled fields.
*/
- Controller->Channels = Enquiry2.ActualChannels;
- Controller->Targets = Enquiry2.MaxTargets;
- Controller->MemorySize = Enquiry2.MemorySize >> 20;
+ Controller->Channels = Enquiry2->ActualChannels;
+ Controller->Targets = Enquiry2->MaxTargets;
+ Controller->MemorySize = Enquiry2->MemorySize >> 20;
Controller->V1.SAFTE_EnclosureManagementEnabled =
- (Enquiry2.FaultManagementType == DAC960_V1_SAFTE);
+ (Enquiry2->FaultManagementType == DAC960_V1_SAFTE);
/*
Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and
@@ -1183,8 +1572,8 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
Controller->LogicalDriveCount =
Controller->V1.Enquiry.NumberOfLogicalDrives;
- Controller->MaxBlocksPerCommand = Enquiry2.MaxBlocksPerCommand;
- Controller->ControllerScatterGatherLimit = Enquiry2.MaxScatterGatherEntries;
+ Controller->MaxBlocksPerCommand = Enquiry2->MaxBlocksPerCommand;
+ Controller->ControllerScatterGatherLimit = Enquiry2->MaxScatterGatherEntries;
Controller->DriverScatterGatherLimit =
Controller->ControllerScatterGatherLimit;
if (Controller->DriverScatterGatherLimit > DAC960_V1_ScatterGatherLimit)
@@ -1192,11 +1581,11 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
/*
Initialize the Stripe Size, Segment Size, and Geometry Translation.
*/
- Controller->V1.StripeSize = Config2.BlocksPerStripe * Config2.BlockFactor
+ Controller->V1.StripeSize = Config2->BlocksPerStripe * Config2->BlockFactor
>> (10 - DAC960_BlockSizeBits);
- Controller->V1.SegmentSize = Config2.BlocksPerCacheLine * Config2.BlockFactor
+ Controller->V1.SegmentSize = Config2->BlocksPerCacheLine * Config2->BlockFactor
>> (10 - DAC960_BlockSizeBits);
- switch (Config2.DriveGeometry)
+ switch (Config2->DriveGeometry)
{
case DAC960_V1_Geometry_128_32:
Controller->V1.GeometryTranslationHeads = 128;
@@ -1207,6 +1596,7 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
Controller->V1.GeometryTranslationSectors = 63;
break;
default:
+ free_dma_loaf(Controller->PCIDevice, &local_dma);
return DAC960_Failure(Controller, "CONFIG2 DRIVE GEOMETRY");
}
/*
@@ -1220,8 +1610,11 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
Controller->V1.BackgroundInitializationStatusSupported = true;
DAC960_V1_ExecuteType3B(Controller,
DAC960_V1_BackgroundInitializationControl, 0x20,
- &Controller->
- V1.LastBackgroundInitializationStatus);
+ Controller->
+ V1.BackgroundInitializationStatusDMA);
+ memcpy(&Controller->V1.LastBackgroundInitializationStatus,
+ Controller->V1.BackgroundInitializationStatus,
+ sizeof(DAC960_V1_BackgroundInitializationStatus_T));
}
/*
Initialize the Logical Drive Initially Accessible flag.
@@ -1234,6 +1627,7 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
DAC960_V1_LogicalDrive_Offline)
Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
Controller->V1.LastRebuildStatus = DAC960_V1_NoRebuildOrCheckInProgress;
+ free_dma_loaf(Controller->PCIDevice, &local_dma);
return true;
}
@@ -1247,17 +1641,20 @@ static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
*Controller)
{
DAC960_V2_ControllerInfo_T *ControllerInfo =
- &Controller->V2.ControllerInformation;
+ &Controller->V2.ControllerInformation;
unsigned short LogicalDeviceNumber = 0;
int ModelNameLength;
- if (!DAC960_V2_ControllerInfo(Controller, DAC960_V2_GetControllerInfo,
- ControllerInfo,
- sizeof(DAC960_V2_ControllerInfo_T)))
+
+ /* Get data into dma-able area, then copy into permanant location */
+ if (!DAC960_V2_NewControllerInfo(Controller))
return DAC960_Failure(Controller, "GET CONTROLLER INFO");
- if (!DAC960_V2_GeneralInfo(Controller, DAC960_V2_GetHealthStatus,
- Controller->V2.HealthStatusBuffer,
- sizeof(DAC960_V2_HealthStatusBuffer_T)))
+ memcpy(ControllerInfo, Controller->V2.NewControllerInformation,
+ sizeof(DAC960_V2_ControllerInfo_T));
+
+
+ if (!DAC960_V2_GeneralInfo(Controller))
return DAC960_Failure(Controller, "GET HEALTH STATUS");
+
/*
Initialize the Controller Model Name and Full Model Name fields.
*/
@@ -1325,14 +1722,11 @@ static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
while (true)
{
DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
- &Controller->V2.NewLogicalDeviceInformation;
+ Controller->V2.NewLogicalDeviceInformation;
DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo;
DAC960_V2_PhysicalDevice_T PhysicalDevice;
- if (!DAC960_V2_LogicalDeviceInfo(Controller,
- DAC960_V2_GetLogicalDeviceInfoValid,
- LogicalDeviceNumber,
- NewLogicalDeviceInfo,
- sizeof(DAC960_V2_LogicalDeviceInfo_T)))
+
+ if (!DAC960_V2_NewLogicalDeviceInfo(Controller, LogicalDeviceNumber))
break;
LogicalDeviceNumber = NewLogicalDeviceInfo->LogicalDeviceNumber;
if (LogicalDeviceNumber > DAC960_MaxLogicalDrives)
@@ -1421,26 +1815,61 @@ static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T
static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
*Controller)
{
- DAC960_V1_DCDB_T DCDBs[DAC960_V1_MaxChannels], *DCDB;
- Completion_T Completions[DAC960_V1_MaxChannels], *Completion;
+ struct dma_loaf local_dma;
+
+ dma_addr_t DCDBs_dma[DAC960_V1_MaxChannels];
+ DAC960_V1_DCDB_T *DCDBs_cpu[DAC960_V1_MaxChannels];
+
+ dma_addr_t SCSI_Inquiry_dma[DAC960_V1_MaxChannels];
+ DAC960_SCSI_Inquiry_T *SCSI_Inquiry_cpu[DAC960_V1_MaxChannels];
+
+ dma_addr_t SCSI_NewInquiryUnitSerialNumberDMA[DAC960_V1_MaxChannels];
+ DAC960_SCSI_Inquiry_UnitSerialNumber_T *SCSI_NewInquiryUnitSerialNumberCPU[DAC960_V1_MaxChannels];
+
+ Completion_T Completions[DAC960_V1_MaxChannels];
unsigned long ProcessorFlags;
int Channel, TargetID;
+
+ if (!init_dma_loaf(Controller->PCIDevice, &local_dma,
+ DAC960_V1_MaxChannels*(sizeof(DAC960_V1_DCDB_T) +
+ sizeof(DAC960_SCSI_Inquiry_T) +
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T))))
+ return DAC960_Failure(Controller,
+ "DMA ALLOCATION FAILED IN ReadDeviceConfiguration");
+
+ for (Channel = 0; Channel < Controller->Channels; Channel++) {
+ DCDBs_cpu[Channel] = slice_dma_loaf(&local_dma,
+ sizeof(DAC960_V1_DCDB_T), DCDBs_dma + Channel);
+ SCSI_Inquiry_cpu[Channel] = slice_dma_loaf(&local_dma,
+ sizeof(DAC960_SCSI_Inquiry_T),
+ SCSI_Inquiry_dma + Channel);
+ SCSI_NewInquiryUnitSerialNumberCPU[Channel] = slice_dma_loaf(&local_dma,
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T),
+ SCSI_NewInquiryUnitSerialNumberDMA + Channel);
+ }
+
for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
{
+ /*
+ * For each channel, submit a probe for a device on that channel.
+ * The timeout interval for a device that is present is 10 seconds.
+ * With this approach, the timeout periods can elapse in parallel
+ * on each channel.
+ */
for (Channel = 0; Channel < Controller->Channels; Channel++)
{
+ dma_addr_t NewInquiryStandardDataDMA = SCSI_Inquiry_dma[Channel];
+ DAC960_V1_DCDB_T *DCDB = DCDBs_cpu[Channel];
+ dma_addr_t DCDB_dma = DCDBs_dma[Channel];
DAC960_Command_T *Command = Controller->Commands[Channel];
- DAC960_SCSI_Inquiry_T *InquiryStandardData =
- &Controller->V1.InquiryStandardData[Channel][TargetID];
- InquiryStandardData->PeripheralDeviceType = 0x1F;
- Completion = &Completions[Channel];
+ Completion_T *Completion = &Completions[Channel];
+
init_completion(Completion);
- DCDB = &DCDBs[Channel];
DAC960_V1_ClearCommand(Command);
Command->CommandType = DAC960_ImmediateCommand;
Command->Completion = Completion;
Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
- Command->V1.CommandMailbox.Type3.BusAddress = Virtual_to_Bus32(DCDB);
+ Command->V1.CommandMailbox.Type3.BusAddress = DCDB_dma;
DCDB->Channel = Channel;
DCDB->TargetID = TargetID;
DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
@@ -1449,7 +1878,7 @@ static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
DCDB->NoAutomaticRequestSense = false;
DCDB->DisconnectPermitted = true;
DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
- DCDB->BusAddress = Virtual_to_Bus32(InquiryStandardData);
+ DCDB->BusAddress = NewInquiryStandardDataDMA;
DCDB->CDBLength = 6;
DCDB->TransferLengthHigh4 = 0;
DCDB->SenseLength = sizeof(DCDB->SenseData);
@@ -1463,20 +1892,39 @@ static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
DAC960_QueueCommand(Command);
DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
}
+ /*
+ * Wait for the problems submitted in the previous loop
+ * to complete. On the probes that are successful,
+ * get the serial number of the device that was found.
+ */
for (Channel = 0; Channel < Controller->Channels; Channel++)
{
- DAC960_Command_T *Command = Controller->Commands[Channel];
+ DAC960_SCSI_Inquiry_T *InquiryStandardData =
+ &Controller->V1.InquiryStandardData[Channel][TargetID];
+ DAC960_SCSI_Inquiry_T *NewInquiryStandardData = SCSI_Inquiry_cpu[Channel];
+ dma_addr_t NewInquiryUnitSerialNumberDMA =
+ SCSI_NewInquiryUnitSerialNumberDMA[Channel];
+ DAC960_SCSI_Inquiry_UnitSerialNumber_T *NewInquiryUnitSerialNumber =
+ SCSI_NewInquiryUnitSerialNumberCPU[Channel];
DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
&Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
- InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
- Completion = &Completions[Channel];
+ DAC960_Command_T *Command = Controller->Commands[Channel];
+ DAC960_V1_DCDB_T *DCDB = DCDBs_cpu[Channel];
+ Completion_T *Completion = &Completions[Channel];
+
wait_for_completion(Completion);
- if (Command->V1.CommandStatus != DAC960_V1_NormalCompletion)
+
+ if (Command->V1.CommandStatus != DAC960_V1_NormalCompletion) {
+ memset(InquiryStandardData, 0, sizeof(DAC960_SCSI_Inquiry_T));
+ InquiryStandardData->PeripheralDeviceType = 0x1F;
continue;
+ } else
+ memcpy(InquiryStandardData, NewInquiryStandardData, sizeof(DAC960_SCSI_Inquiry_T));
+
+ /* Preserve Channel and TargetID values from the previous loop */
Command->Completion = Completion;
- DCDB = &DCDBs[Channel];
DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
- DCDB->BusAddress = Virtual_to_Bus32(InquiryUnitSerialNumber);
+ DCDB->BusAddress = NewInquiryUnitSerialNumberDMA;
DCDB->SenseLength = sizeof(DCDB->SenseData);
DCDB->CDB[0] = 0x12; /* INQUIRY */
DCDB->CDB[1] = 1; /* EVPD = 1 */
@@ -1488,8 +1936,17 @@ static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
DAC960_QueueCommand(Command);
DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
wait_for_completion(Completion);
+
+ if (Command->V1.CommandStatus != DAC960_V1_NormalCompletion) {
+ memset(InquiryUnitSerialNumber, 0,
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
+ InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+ } else
+ memcpy(InquiryUnitSerialNumber, NewInquiryUnitSerialNumber,
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
}
}
+ free_dma_loaf(Controller->PCIDevice, &local_dma);
return true;
}
@@ -1506,74 +1963,55 @@ static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
{
unsigned char Channel = 0, TargetID = 0, LogicalUnit = 0;
unsigned short PhysicalDeviceIndex = 0;
+
while (true)
{
DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
- &Controller->V2.NewPhysicalDeviceInformation;
+ Controller->V2.NewPhysicalDeviceInformation;
DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo;
+ DAC960_SCSI_Inquiry_UnitSerialNumber_T *NewInquiryUnitSerialNumber =
+ Controller->V2.NewInquiryUnitSerialNumber;
DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber;
- DAC960_Command_T *Command;
- DAC960_V2_CommandMailbox_T *CommandMailbox;
- if (!DAC960_V2_PhysicalDeviceInfo(Controller,
- DAC960_V2_GetPhysicalDeviceInfoValid,
- Channel,
- TargetID,
- LogicalUnit,
- NewPhysicalDeviceInfo,
- sizeof(DAC960_V2_PhysicalDeviceInfo_T)))
+
+ if (!DAC960_V2_NewPhysicalDeviceInfo(Controller, Channel, TargetID, LogicalUnit))
break;
- Channel = NewPhysicalDeviceInfo->Channel;
- TargetID = NewPhysicalDeviceInfo->TargetID;
- LogicalUnit = NewPhysicalDeviceInfo->LogicalUnit;
+
PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
- kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
+ kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
if (PhysicalDeviceInfo == NULL)
- return DAC960_Failure(Controller, "PHYSICAL DEVICE ALLOCATION");
+ return DAC960_Failure(Controller, "PHYSICAL DEVICE ALLOCATION");
Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex] =
- PhysicalDeviceInfo;
+ PhysicalDeviceInfo;
memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
- sizeof(DAC960_V2_PhysicalDeviceInfo_T));
+ sizeof(DAC960_V2_PhysicalDeviceInfo_T));
+
InquiryUnitSerialNumber = (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC);
- if (InquiryUnitSerialNumber == NULL)
+ if (InquiryUnitSerialNumber == NULL) {
+ kfree(PhysicalDeviceInfo);
return DAC960_Failure(Controller, "SERIAL NUMBER ALLOCATION");
+ }
Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex] =
- InquiryUnitSerialNumber;
- memset(InquiryUnitSerialNumber, 0,
- sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
- InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
- Command = DAC960_AllocateCommand(Controller);
- CommandMailbox = &Command->V2.CommandMailbox;
- DAC960_V2_ClearCommand(Command);
- Command->CommandType = DAC960_ImmediateCommand;
- CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10_Passthru;
- CommandMailbox->SCSI_10.CommandControlBits
- .DataTransferControllerToHost = true;
- CommandMailbox->SCSI_10.CommandControlBits
- .NoAutoRequestSense = true;
- CommandMailbox->SCSI_10.DataTransferSize =
- sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
- CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit = LogicalUnit;
- CommandMailbox->SCSI_10.PhysicalDevice.TargetID = TargetID;
- CommandMailbox->SCSI_10.PhysicalDevice.Channel = Channel;
- CommandMailbox->SCSI_10.CDBLength = 6;
- CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
- CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
- CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
- CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
- CommandMailbox->SCSI_10.SCSI_CDB[4] =
- sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
- CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
- CommandMailbox->SCSI_10.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(InquiryUnitSerialNumber);
- CommandMailbox->SCSI_10.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentByteCount =
- CommandMailbox->SCSI_10.DataTransferSize;
- DAC960_ExecuteCommand(Command);
- DAC960_DeallocateCommand(Command);
+ InquiryUnitSerialNumber;
+
+ Channel = NewPhysicalDeviceInfo->Channel;
+ TargetID = NewPhysicalDeviceInfo->TargetID;
+ LogicalUnit = NewPhysicalDeviceInfo->LogicalUnit;
+
+ /*
+ Some devices do NOT have Unit Serial Numbers.
+ This command fails for them. But, we still want to
+ remember those devices are there. Construct a
+ UnitSerialNumber structure for the failure case.
+ */
+ if (!DAC960_V2_NewInquiryUnitSerialNumber(Controller, Channel, TargetID, LogicalUnit)) {
+ memset(InquiryUnitSerialNumber, 0,
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
+ InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+ } else
+ memcpy(InquiryUnitSerialNumber, NewInquiryUnitSerialNumber,
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
+
PhysicalDeviceIndex++;
LogicalUnit++;
}
@@ -1947,12 +2385,12 @@ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
Initialize the I/O Request Queue.
*/
RequestQueue = &Controller->RequestQueue;
- Controller->queue_lock = SPIN_LOCK_UNLOCKED;
blk_init_queue(RequestQueue, DAC960_RequestFunction, &Controller->queue_lock);
RequestQueue->queuedata = Controller;
blk_queue_max_hw_segments(RequestQueue,
Controller->DriverScatterGatherLimit);
- blk_queue_max_phys_segments(RequestQueue, ~0);
+ blk_queue_max_phys_segments(RequestQueue,
+ Controller->DriverScatterGatherLimit);
blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
for (n = 0; n < DAC960_MaxLogicalDrives; n++) {
@@ -1978,8 +2416,10 @@ static void DAC960_UnregisterBlockDevice(DAC960_Controller_T *Controller)
{
int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
int disk;
+
for (disk = 0; disk < DAC960_MaxLogicalDrives; disk++)
del_gendisk(Controller->disks[disk]);
+
/*
Unregister the Block Device Major Number for this DAC960 Controller.
*/
@@ -2082,159 +2522,155 @@ static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
/*
- DAC960_DetectControllers detects Mylex DAC960/AcceleRAID/eXtremeRAID
+ * DAC960_DetectCleanup releases the resources that were allocated
+ * during DAC960_DetectController(). DAC960_DetectController can
+ * has several internal failure points, so not ALL resources may
+ * have been allocated. It's important to free only
+ * resources that HAVE been allocated. The code below always
+ * tests that the resource has been allocated before attempting to
+ * free it.
+ */
+static void DAC960_DetectCleanup(DAC960_Controller_T *Controller)
+{
+ int i;
+
+ /* Free the memory mailbox, status, and related structures */
+ free_dma_loaf(Controller->PCIDevice, &Controller->DmaPages);
+ if (Controller->MemoryMappedAddress) {
+ switch(Controller->HardwareType)
+ {
+ case DAC960_BA_Controller:
+ DAC960_BA_DisableInterrupts(Controller->BaseAddress);
+ break;
+ case DAC960_LP_Controller:
+ DAC960_LP_DisableInterrupts(Controller->BaseAddress);
+ break;
+ case DAC960_LA_Controller:
+ DAC960_LA_DisableInterrupts(Controller->BaseAddress);
+ break;
+ case DAC960_PG_Controller:
+ DAC960_PG_DisableInterrupts(Controller->BaseAddress);
+ break;
+ case DAC960_PD_Controller:
+ DAC960_PD_DisableInterrupts(Controller->BaseAddress);
+ break;
+ case DAC960_P_Controller:
+ DAC960_PD_DisableInterrupts(Controller->BaseAddress);
+ break;
+ }
+ iounmap(Controller->MemoryMappedAddress);
+ }
+ if (Controller->IRQ_Channel)
+ free_irq(Controller->IRQ_Channel, Controller);
+ if (Controller->IO_Address)
+ release_region(Controller->IO_Address, 0x80);
+ pci_disable_device(Controller->PCIDevice);
+ for (i = 0; (i < DAC960_MaxLogicalDrives) && Controller->disks[i]; i++)
+ put_disk(Controller->disks[i]);
+ DAC960_Controllers[Controller->ControllerNumber] = NULL;
+ kfree(Controller);
+}
+
+
+/*
+ DAC960_DetectController detects Mylex DAC960/AcceleRAID/eXtremeRAID
PCI RAID Controllers by interrogating the PCI Configuration Space for
Controller Type.
*/
-static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
+static DAC960_Controller_T *
+DAC960_DetectController(PCI_Device_T *PCI_Device,
+ const struct pci_device_id *entry)
{
- void (*InterruptHandler)(int, void *, Registers_T *) = NULL;
+ struct DAC960_privdata *privdata = (struct DAC960_privdata *)entry->driver_data;
+ void (*InterruptHandler)(int, void *, Registers_T *) = privdata->InterruptHandler;
+ unsigned int MemoryWindowSize = privdata->MemoryWindowSize;
DAC960_Controller_T *Controller = NULL;
- DAC960_FirmwareType_T FirmwareType = 0;
- unsigned short VendorID = 0, DeviceID = 0;
- unsigned int MemoryWindowSize = 0;
- PCI_Device_T *PCI_Device = NULL;
+ unsigned char DeviceFunction = PCI_Device->devfn;
+ unsigned char ErrorStatus, Parameter0, Parameter1;
+ unsigned int IRQ_Channel = PCI_Device->irq;
+ void *BaseAddress;
int i;
- switch (HardwareType)
- {
- case DAC960_BA_Controller:
- VendorID = PCI_VENDOR_ID_MYLEX;
- DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_BA;
- FirmwareType = DAC960_V2_Controller;
- InterruptHandler = DAC960_BA_InterruptHandler;
- MemoryWindowSize = DAC960_BA_RegisterWindowSize;
- break;
- case DAC960_LP_Controller:
- VendorID = PCI_VENDOR_ID_MYLEX;
- DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_LP;
- FirmwareType = DAC960_LP_Controller;
- InterruptHandler = DAC960_LP_InterruptHandler;
- MemoryWindowSize = DAC960_LP_RegisterWindowSize;
- break;
- case DAC960_LA_Controller:
- VendorID = PCI_VENDOR_ID_DEC;
- DeviceID = PCI_DEVICE_ID_DEC_21285;
- FirmwareType = DAC960_V1_Controller;
- InterruptHandler = DAC960_LA_InterruptHandler;
- MemoryWindowSize = DAC960_LA_RegisterWindowSize;
- break;
- case DAC960_PG_Controller:
- VendorID = PCI_VENDOR_ID_MYLEX;
- DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PG;
- FirmwareType = DAC960_V1_Controller;
- InterruptHandler = DAC960_PG_InterruptHandler;
- MemoryWindowSize = DAC960_PG_RegisterWindowSize;
- break;
- case DAC960_PD_Controller:
- VendorID = PCI_VENDOR_ID_MYLEX;
- DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PD;
- FirmwareType = DAC960_V1_Controller;
- InterruptHandler = DAC960_PD_InterruptHandler;
- MemoryWindowSize = DAC960_PD_RegisterWindowSize;
- break;
- case DAC960_P_Controller:
- VendorID = PCI_VENDOR_ID_MYLEX;
- DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_P;
- FirmwareType = DAC960_V1_Controller;
- InterruptHandler = DAC960_P_InterruptHandler;
- MemoryWindowSize = DAC960_PD_RegisterWindowSize;
- break;
- }
- while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
- {
- DAC960_IO_Address_T IO_Address = 0;
- DAC960_PCI_Address_T PCI_Address = 0;
- unsigned char Bus = PCI_Device->bus->number;
- unsigned char DeviceFunction = PCI_Device->devfn;
- unsigned char Device = DeviceFunction >> 3;
- unsigned char Function = DeviceFunction & 0x7;
- unsigned char ErrorStatus, Parameter0, Parameter1;
- unsigned int IRQ_Channel = PCI_Device->irq;
- void *BaseAddress;
- Controller = NULL;
- if (pci_enable_device(PCI_Device) != 0) continue;
- switch (HardwareType)
- {
+
+ Controller = (DAC960_Controller_T *)
+ kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
+ if (Controller == NULL) {
+ DAC960_Error("Unable to allocate Controller structure for "
+ "Controller at\n", NULL);
+ return NULL;
+ }
+ memset(Controller, 0, sizeof(DAC960_Controller_T));
+ Controller->ControllerNumber = DAC960_ControllerCount;
+ DAC960_Controllers[DAC960_ControllerCount++] = Controller;
+ Controller->Bus = PCI_Device->bus->number;
+ Controller->FirmwareType = privdata->FirmwareType;
+ Controller->HardwareType = privdata->HardwareType;
+ Controller->Device = DeviceFunction >> 3;
+ Controller->Function = DeviceFunction & 0x7;
+ Controller->PCIDevice = PCI_Device;
+ strcpy(Controller->FullModelName, "DAC960");
+
+ if (pci_enable_device(PCI_Device)) {
+ kfree(Controller);
+ goto Failure;
+ }
+
+ switch (Controller->HardwareType)
+ {
case DAC960_BA_Controller:
- PCI_Address = pci_resource_start(PCI_Device, 0);
+ Controller->PCI_Address = pci_resource_start(PCI_Device, 0);
break;
case DAC960_LP_Controller:
- PCI_Address = pci_resource_start(PCI_Device, 0);
+ Controller->PCI_Address = pci_resource_start(PCI_Device, 0);
break;
case DAC960_LA_Controller:
- if (!(PCI_Device->subsystem_vendor == PCI_VENDOR_ID_MYLEX &&
- PCI_Device->subsystem_device == PCI_DEVICE_ID_MYLEX_DAC960_LA))
- continue;
- PCI_Address = pci_resource_start(PCI_Device, 0);
+ Controller->PCI_Address = pci_resource_start(PCI_Device, 0);
break;
case DAC960_PG_Controller:
- PCI_Address = pci_resource_start(PCI_Device, 0);
+ Controller->PCI_Address = pci_resource_start(PCI_Device, 0);
break;
case DAC960_PD_Controller:
- IO_Address = pci_resource_start(PCI_Device, 0);
- PCI_Address = pci_resource_start(PCI_Device, 1);
+ Controller->IO_Address = pci_resource_start(PCI_Device, 0);
+ Controller->PCI_Address = pci_resource_start(PCI_Device, 1);
break;
case DAC960_P_Controller:
- IO_Address = pci_resource_start(PCI_Device, 0);
- PCI_Address = pci_resource_start(PCI_Device, 1);
+ Controller->IO_Address = pci_resource_start(PCI_Device, 0);
+ Controller->PCI_Address = pci_resource_start(PCI_Device, 1);
break;
- }
- if (DAC960_ControllerCount == DAC960_MaxControllers)
- {
- DAC960_Error("More than %d DAC960 Controllers detected - "
- "ignoring from Controller at\n",
- NULL, DAC960_MaxControllers);
- goto Failure;
- }
- Controller = (DAC960_Controller_T *)
- kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
- if (Controller == NULL)
- {
- DAC960_Error("Unable to allocate Controller structure for "
- "Controller at\n", NULL);
- goto Failure;
- }
- memset(Controller, 0, sizeof(DAC960_Controller_T));
- for (i = 0; i < DAC960_MaxLogicalDrives; i++) {
- Controller->disks[i] = alloc_disk(1<<DAC960_MaxPartitionsBits);
- if (!Controller->disks[i])
- goto Enomem;
- Controller->disks[i]->private_data = (void*)i;
- Controller->disks[i]->queue = &Controller->RequestQueue;
- }
- Controller->ControllerNumber = DAC960_ControllerCount;
- init_waitqueue_head(&Controller->CommandWaitQueue);
- init_waitqueue_head(&Controller->HealthStatusWaitQueue);
- DAC960_Controllers[DAC960_ControllerCount++] = Controller;
- DAC960_AnnounceDriver(Controller);
- Controller->FirmwareType = FirmwareType;
- Controller->HardwareType = HardwareType;
- Controller->IO_Address = IO_Address;
- Controller->PCI_Address = PCI_Address;
- Controller->Bus = Bus;
- Controller->Device = Device;
- Controller->Function = Function;
- /*
- Map the Controller Register Window.
- */
- if (MemoryWindowSize < PAGE_SIZE)
+ }
+
+ pci_set_drvdata(PCI_Device, (void *)((int)Controller->ControllerNumber));
+ for (i = 0; i < DAC960_MaxLogicalDrives; i++) {
+ Controller->disks[i] = alloc_disk(1<<DAC960_MaxPartitionsBits);
+ if (!Controller->disks[i])
+ goto Failure;
+ Controller->disks[i]->private_data = (void *)i;
+ Controller->disks[i]->queue = &Controller->RequestQueue;
+ }
+ init_waitqueue_head(&Controller->CommandWaitQueue);
+ init_waitqueue_head(&Controller->HealthStatusWaitQueue);
+ Controller->queue_lock = SPIN_LOCK_UNLOCKED;
+ DAC960_AnnounceDriver(Controller);
+ /*
+ Map the Controller Register Window.
+ */
+ if (MemoryWindowSize < PAGE_SIZE)
MemoryWindowSize = PAGE_SIZE;
- Controller->MemoryMappedAddress =
- ioremap_nocache(PCI_Address & PAGE_MASK, MemoryWindowSize);
- Controller->BaseAddress =
- Controller->MemoryMappedAddress + (PCI_Address & ~PAGE_MASK);
- if (Controller->MemoryMappedAddress == NULL)
- {
+ Controller->MemoryMappedAddress =
+ ioremap_nocache(Controller->PCI_Address & PAGE_MASK, MemoryWindowSize);
+ Controller->BaseAddress =
+ Controller->MemoryMappedAddress + (Controller->PCI_Address & ~PAGE_MASK);
+ if (Controller->MemoryMappedAddress == NULL)
+ {
DAC960_Error("Unable to map Controller Register Window for "
"Controller at\n", Controller);
goto Failure;
- }
- BaseAddress = Controller->BaseAddress;
- switch (HardwareType)
- {
+ }
+ BaseAddress = Controller->BaseAddress;
+ switch (Controller->HardwareType)
+ {
case DAC960_BA_Controller:
- DAC960_BA_DisableInterrupts(Controller->BaseAddress);
+ DAC960_BA_DisableInterrupts(BaseAddress);
DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress);
udelay(1000);
while (DAC960_BA_InitializationInProgressP(BaseAddress))
@@ -2252,7 +2688,7 @@ static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
"for Controller at\n", Controller);
goto Failure;
}
- DAC960_BA_EnableInterrupts(Controller->BaseAddress);
+ DAC960_BA_EnableInterrupts(BaseAddress);
Controller->QueueCommand = DAC960_BA_QueueCommand;
Controller->ReadControllerConfiguration =
DAC960_V2_ReadControllerConfiguration;
@@ -2264,7 +2700,7 @@ static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
DAC960_V2_QueueReadWriteCommand;
break;
case DAC960_LP_Controller:
- DAC960_LP_DisableInterrupts(Controller->BaseAddress);
+ DAC960_LP_DisableInterrupts(BaseAddress);
DAC960_LP_AcknowledgeHardwareMailboxStatus(BaseAddress);
udelay(1000);
while (DAC960_LP_InitializationInProgressP(BaseAddress))
@@ -2282,7 +2718,7 @@ static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
"for Controller at\n", Controller);
goto Failure;
}
- DAC960_LP_EnableInterrupts(Controller->BaseAddress);
+ DAC960_LP_EnableInterrupts(BaseAddress);
Controller->QueueCommand = DAC960_LP_QueueCommand;
Controller->ReadControllerConfiguration =
DAC960_V2_ReadControllerConfiguration;
@@ -2294,7 +2730,7 @@ static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
DAC960_V2_QueueReadWriteCommand;
break;
case DAC960_LA_Controller:
- DAC960_LA_DisableInterrupts(Controller->BaseAddress);
+ DAC960_LA_DisableInterrupts(BaseAddress);
DAC960_LA_AcknowledgeHardwareMailboxStatus(BaseAddress);
udelay(1000);
while (DAC960_LA_InitializationInProgressP(BaseAddress))
@@ -2312,7 +2748,7 @@ static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
"for Controller at\n", Controller);
goto Failure;
}
- DAC960_LA_EnableInterrupts(Controller->BaseAddress);
+ DAC960_LA_EnableInterrupts(BaseAddress);
if (Controller->V1.DualModeMemoryMailboxInterface)
Controller->QueueCommand = DAC960_LA_QueueCommandDualMode;
else Controller->QueueCommand = DAC960_LA_QueueCommandSingleMode;
@@ -2326,7 +2762,7 @@ static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
DAC960_V1_QueueReadWriteCommand;
break;
case DAC960_PG_Controller:
- DAC960_PG_DisableInterrupts(Controller->BaseAddress);
+ DAC960_PG_DisableInterrupts(BaseAddress);
DAC960_PG_AcknowledgeHardwareMailboxStatus(BaseAddress);
udelay(1000);
while (DAC960_PG_InitializationInProgressP(BaseAddress))
@@ -2344,7 +2780,7 @@ static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
"for Controller at\n", Controller);
goto Failure;
}
- DAC960_PG_EnableInterrupts(Controller->BaseAddress);
+ DAC960_PG_EnableInterrupts(BaseAddress);
if (Controller->V1.DualModeMemoryMailboxInterface)
Controller->QueueCommand = DAC960_PG_QueueCommandDualMode;
else Controller->QueueCommand = DAC960_PG_QueueCommandSingleMode;
@@ -2373,10 +2809,16 @@ static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
&Parameter0, &Parameter1) &&
DAC960_ReportErrorStatus(Controller, ErrorStatus,
Parameter0, Parameter1))
- goto Failure1;
+ goto Failure;
udelay(10);
}
- DAC960_PD_EnableInterrupts(Controller->BaseAddress);
+ if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
+ {
+ DAC960_Error("Unable to allocate DMA mapped memory "
+ "for Controller at\n", Controller);
+ goto Failure;
+ }
+ DAC960_PD_EnableInterrupts(BaseAddress);
Controller->QueueCommand = DAC960_PD_QueueCommand;
Controller->ReadControllerConfiguration =
DAC960_V1_ReadControllerConfiguration;
@@ -2403,10 +2845,16 @@ static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
&Parameter0, &Parameter1) &&
DAC960_ReportErrorStatus(Controller, ErrorStatus,
Parameter0, Parameter1))
- goto Failure1;
+ goto Failure;
udelay(10);
}
- DAC960_PD_EnableInterrupts(Controller->BaseAddress);
+ if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
+ {
+ DAC960_Error("Unable to allocate DMA mapped memory"
+ "for Controller at\n", Controller);
+ goto Failure;
+ }
+ DAC960_PD_EnableInterrupts(BaseAddress);
Controller->QueueCommand = DAC960_P_QueueCommand;
Controller->ReadControllerConfiguration =
DAC960_V1_ReadControllerConfiguration;
@@ -2417,107 +2865,47 @@ static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
Controller->QueueReadWriteCommand =
DAC960_V1_QueueReadWriteCommand;
break;
- }
- /*
- Acquire shared access to the IRQ Channel.
- */
- if (IRQ_Channel == 0)
- {
- DAC960_Error("IRQ Channel %d illegal for Controller at\n",
- Controller, IRQ_Channel);
- goto Failure1;
- }
- strcpy(Controller->FullModelName, "DAC960");
- if (request_irq(IRQ_Channel, InterruptHandler, SA_SHIRQ,
+ }
+ /*
+ Acquire shared access to the IRQ Channel.
+ */
+ if (request_irq(IRQ_Channel, InterruptHandler, SA_SHIRQ,
Controller->FullModelName, Controller) < 0)
- {
- DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
- Controller, IRQ_Channel);
- goto Failure1;
- }
- Controller->IRQ_Channel = IRQ_Channel;
- DAC960_ActiveControllerCount++;
- Controller->InitialCommand.CommandIdentifier = 1;
- Controller->InitialCommand.Controller = Controller;
- Controller->Commands[0] = &Controller->InitialCommand;
- Controller->FreeCommands = &Controller->InitialCommand;
- Controller->ControllerDetectionSuccessful = true;
- continue;
- Failure1:
- if (Controller->IO_Address) release_region(Controller->IO_Address, 0x80);
- Failure:
- if (IO_Address == 0)
+ {
+ DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
+ Controller, Controller->IRQ_Channel);
+ goto Failure;
+ }
+ Controller->IRQ_Channel = IRQ_Channel;
+ Controller->InitialCommand.CommandIdentifier = 1;
+ Controller->InitialCommand.Controller = Controller;
+ Controller->Commands[0] = &Controller->InitialCommand;
+ Controller->FreeCommands = &Controller->InitialCommand;
+ return Controller;
+
+Failure:
+ if (Controller->IO_Address == 0)
DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
"PCI Address 0x%X\n", Controller,
- Bus, Device, Function, PCI_Address);
- else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
+ Controller->Bus, Controller->Device,
+ Controller->Function, Controller->PCI_Address);
+ else
+ DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
"0x%X PCI Address 0x%X\n", Controller,
- Bus, Device, Function, IO_Address, PCI_Address);
- if (Controller == NULL) break;
- if (Controller->MemoryMappedAddress != NULL)
- iounmap(Controller->MemoryMappedAddress);
- if (Controller->IRQ_Channel > 0)
- free_irq(IRQ_Channel, Controller);
- }
- return;
-Enomem:
- while (i--)
- put_disk(Controller->disks[i]);
- kfree(Controller);
- goto Failure;
-}
-
-
-/*
- DAC960_SortControllers sorts the Controllers by PCI Bus and Device Number.
-*/
-
-static void DAC960_SortControllers(void)
-{
- int ControllerNumber, LastInterchange, Bound, j;
- LastInterchange = DAC960_ControllerCount-1;
- while (LastInterchange > 0)
- {
- Bound = LastInterchange;
- LastInterchange = 0;
- for (j = 0; j < Bound; j++)
- {
- DAC960_Controller_T *Controller1 = DAC960_Controllers[j];
- DAC960_Controller_T *Controller2 = DAC960_Controllers[j+1];
- if (Controller1->Bus > Controller2->Bus ||
- (Controller1->Bus == Controller2->Bus &&
- (Controller1->Device > Controller2->Device)))
- {
- Controller2->ControllerNumber = j;
- DAC960_Controllers[j] = Controller2;
- Controller1->ControllerNumber = j+1;
- DAC960_Controllers[j+1] = Controller1;
- LastInterchange = j;
- }
- }
- }
- for (ControllerNumber = 0;
- ControllerNumber < DAC960_ControllerCount;
- ControllerNumber++)
- {
- DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
- if (!Controller->ControllerDetectionSuccessful)
- {
- int i;
- DAC960_Controllers[ControllerNumber] = NULL;
- for (i = 0; i < DAC960_MaxLogicalDrives; i++)
- put_disk(Controller->disks[i]);
- kfree(Controller);
- }
- }
+ Controller->Bus, Controller->Device,
+ Controller->Function, Controller->IO_Address,
+ Controller->PCI_Address);
+ DAC960_DetectCleanup(Controller);
+ DAC960_ControllerCount--;
+ return NULL;
}
-
/*
DAC960_InitializeController initializes Controller.
*/
-static void DAC960_InitializeController(DAC960_Controller_T *Controller)
+static boolean
+DAC960_InitializeController(DAC960_Controller_T *Controller)
{
if (DAC960_ReadControllerConfiguration(Controller) &&
DAC960_ReportControllerConfiguration(Controller) &&
@@ -2536,8 +2924,9 @@ static void DAC960_InitializeController(DAC960_Controller_T *Controller)
Controller->MonitoringTimer.function = DAC960_MonitoringTimerFunction;
add_timer(&Controller->MonitoringTimer);
Controller->ControllerInitialized = true;
+ return true;
}
- else DAC960_FinalizeController(Controller);
+ return false;
}
@@ -2547,35 +2936,38 @@ static void DAC960_InitializeController(DAC960_Controller_T *Controller)
static void DAC960_FinalizeController(DAC960_Controller_T *Controller)
{
- int i;
if (Controller->ControllerInitialized)
{
- del_timer(&Controller->MonitoringTimer);
+ unsigned long ProcessorFlags;
+
+ /*
+ * Acquiring and releasing lock here eliminates
+ * a very low probability race.
+ *
+ * The code below allocates controller command structures
+ * from the free list without holding the controller lock.
+ * This is safe assuming there is no other activity on
+ * the controller at the time.
+ *
+ * But, there might be a monitoring command still
+ * in progress. Setting the Shutdown flag while holding
+ * the lock ensures that there is no monitoring command
+ * in the interrupt handler currently, and any monitoring
+ * commands that complete from this time on will NOT return
+ * their command structure to the free list.
+ */
+ DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+ Controller->ShutdownMonitoringTimer = 1;
+ DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+ del_timer_sync(&Controller->MonitoringTimer);
if (Controller->FirmwareType == DAC960_V1_Controller)
{
DAC960_Notice("Flushing Cache...", Controller);
- DAC960_V1_ExecuteType3(Controller, DAC960_V1_Flush, NULL);
+ DAC960_V1_ExecuteType3(Controller, DAC960_V1_Flush, 0);
DAC960_Notice("done\n", Controller);
- switch (Controller->HardwareType)
- {
- case DAC960_LA_Controller:
- if (Controller->V1.DualModeMemoryMailboxInterface)
- free_pages(Controller->MemoryMailboxPagesAddress,
- Controller->MemoryMailboxPagesOrder);
- else DAC960_LA_SaveMemoryMailboxInfo(Controller);
- break;
- case DAC960_PG_Controller:
- if (Controller->V1.DualModeMemoryMailboxInterface)
- free_pages(Controller->MemoryMailboxPagesAddress,
- Controller->MemoryMailboxPagesOrder);
- else DAC960_PG_SaveMemoryMailboxInfo(Controller);
- break;
- case DAC960_PD_Controller:
+
+ if (Controller->HardwareType == DAC960_PD_Controller)
release_region(Controller->IO_Address, 0x80);
- break;
- default:
- break;
- }
}
else
{
@@ -2583,51 +2975,48 @@ static void DAC960_FinalizeController(DAC960_Controller_T *Controller)
DAC960_V2_DeviceOperation(Controller, DAC960_V2_PauseDevice,
DAC960_V2_RAID_Controller);
DAC960_Notice("done\n", Controller);
- free_pages(Controller->MemoryMailboxPagesAddress,
- Controller->MemoryMailboxPagesOrder);
}
}
- free_irq(Controller->IRQ_Channel, Controller);
- iounmap(Controller->MemoryMappedAddress);
DAC960_UnregisterBlockDevice(Controller);
DAC960_DestroyAuxiliaryStructures(Controller);
- DAC960_Controllers[Controller->ControllerNumber] = NULL;
- for (i = 0; i < DAC960_MaxLogicalDrives; i++)
- put_disk(Controller->disks[i]);
- kfree(Controller);
+ DAC960_DestroyProcEntries(Controller);
+ DAC960_DetectCleanup(Controller);
}
/*
- DAC960_Initialize initializes the DAC960 Driver.
+ DAC960_Probe verifies controller's existence and
+ initializes the DAC960 Driver for that controller.
*/
-static int DAC960_Initialize(void)
+static int
+DAC960_Probe(struct pci_dev *dev, const struct pci_device_id *entry)
{
- int ControllerNumber;
- DAC960_DetectControllers(DAC960_BA_Controller);
- DAC960_DetectControllers(DAC960_LP_Controller);
- DAC960_DetectControllers(DAC960_LA_Controller);
- DAC960_DetectControllers(DAC960_PG_Controller);
- DAC960_DetectControllers(DAC960_PD_Controller);
- DAC960_DetectControllers(DAC960_P_Controller);
- DAC960_SortControllers();
- if (DAC960_ActiveControllerCount == 0) return -ENODEV;
- for (ControllerNumber = 0;
- ControllerNumber < DAC960_ControllerCount;
- ControllerNumber++)
- {
- DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
- int disk;
- if (Controller == NULL) continue;
- DAC960_InitializeController(Controller);
- for (disk = 0; disk < DAC960_MaxLogicalDrives; disk++) {
- set_capacity(Controller->disks[disk], disk_size(Controller, disk));
- add_disk(Controller->disks[disk]);
- }
- }
- DAC960_CreateProcEntries();
- register_reboot_notifier(&DAC960_NotifierBlock);
+ int disk;
+ DAC960_Controller_T *Controller;
+
+ if (DAC960_ControllerCount == DAC960_MaxControllers)
+ {
+ DAC960_Error("More than %d DAC960 Controllers detected - "
+ "ignoring from Controller at\n",
+ NULL, DAC960_MaxControllers);
+ return -ENODEV;
+ }
+
+ Controller = DAC960_DetectController(dev, entry);
+ if (!Controller)
+ return -ENODEV;
+
+ if (!DAC960_InitializeController(Controller)) {
+ DAC960_FinalizeController(Controller);
+ return -ENODEV;
+ }
+
+ for (disk = 0; disk < DAC960_MaxLogicalDrives; disk++) {
+ set_capacity(Controller->disks[disk], disk_size(Controller, disk));
+ add_disk(Controller->disks[disk]);
+ }
+ DAC960_CreateProcEntries(Controller);
return 0;
}
@@ -2636,32 +3025,12 @@ static int DAC960_Initialize(void)
DAC960_Finalize finalizes the DAC960 Driver.
*/
-static void DAC960_Finalize(void)
+static void DAC960_Remove(PCI_Device_T *PCI_Device)
{
- int ControllerNumber;
- if (DAC960_ActiveControllerCount == 0) return;
- for (ControllerNumber = 0;
- ControllerNumber < DAC960_ControllerCount;
- ControllerNumber++)
- if (DAC960_Controllers[ControllerNumber] != NULL)
- DAC960_FinalizeController(DAC960_Controllers[ControllerNumber]);
- DAC960_DestroyProcEntries();
- unregister_reboot_notifier(&DAC960_NotifierBlock);
-}
-
-
-/*
- DAC960_Notifier is the notifier for the DAC960 Driver.
-*/
-
-static int DAC960_Notifier(NotifierBlock_T *NotifierBlock,
- unsigned long Event,
- void *Buffer)
-{
- if (!(Event == SYS_RESTART || Event == SYS_HALT || Event == SYS_POWER_OFF))
- return NOTIFY_DONE;
- DAC960_Finalize();
- return NOTIFY_OK;
+ int Controller_Number = (int)pci_get_drvdata(PCI_Device);
+ DAC960_Controller_T *Controller = DAC960_Controllers[Controller_Number];
+ if (Controller != NULL)
+ DAC960_FinalizeController(Controller);
}
@@ -2674,57 +3043,60 @@ static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command)
{
DAC960_Controller_T *Controller = Command->Controller;
DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+ DAC960_V1_ScatterGatherSegment_T *ScatterGatherList =
+ Command->V1.ScatterGatherList;
+ struct scatterlist *ScatterList = Command->V1.ScatterList;
+ int DmaDirection, SegCount;
+
DAC960_V1_ClearCommand(Command);
- if (Command->SegmentCount == 1)
+
+ if (Command->CommandType == DAC960_ReadCommand)
+ DmaDirection = PCI_DMA_FROMDEVICE;
+ else
+ DmaDirection = PCI_DMA_TODEVICE;
+
+ SegCount = blk_rq_map_sg(&Controller->RequestQueue, Command->Request,
+ ScatterList);
+ /* pci_map_sg MAY change the value of SegCount */
+ SegCount = pci_map_sg(Command->PciDevice, ScatterList, SegCount,
+ DmaDirection);
+ Command->SegmentCount = SegCount;
+
+ if (SegCount == 1)
{
if (Command->CommandType == DAC960_ReadCommand)
CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
- else CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
+ else
+ CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
+
CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
CommandMailbox->Type5.BusAddress =
- Virtual_to_Bus32(Command->RequestBuffer);
+ (DAC960_BusAddress32_T)sg_dma_address(ScatterList);
}
else
{
- DAC960_V1_ScatterGatherSegment_T
- *ScatterGatherList = Command->V1.ScatterGatherList;
- BufferHeader_T *BufferHeader = Command->BufferHeader;
- char *LastDataEndPointer = NULL;
- int SegmentNumber = 0;
+ int i;
+
if (Command->CommandType == DAC960_ReadCommand)
CommandMailbox->Type5.CommandOpcode = DAC960_V1_ReadWithScatterGather;
else
CommandMailbox->Type5.CommandOpcode = DAC960_V1_WriteWithScatterGather;
+
CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
- CommandMailbox->Type5.BusAddress = Virtual_to_Bus32(ScatterGatherList);
- CommandMailbox->Type5.ScatterGatherCount = Command->SegmentCount;
- while (BufferHeader != NULL)
- {
- if (bio_data(BufferHeader) == LastDataEndPointer)
- {
- ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
- BufferHeader->bi_size;
- LastDataEndPointer += BufferHeader->bi_size;
- }
- else
- {
- ScatterGatherList[SegmentNumber].SegmentDataPointer =
- Virtual_to_Bus32(bio_data(BufferHeader));
- ScatterGatherList[SegmentNumber].SegmentByteCount =
- BufferHeader->bi_size;
- LastDataEndPointer = bio_data(BufferHeader) +
- BufferHeader->bi_size;
- if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
- panic("DAC960: Scatter/Gather Segment Overflow\n");
- }
- BufferHeader = BufferHeader->bi_next;
- }
- if (SegmentNumber != Command->SegmentCount)
- panic("DAC960: SegmentNumber != SegmentCount\n");
+ CommandMailbox->Type5.BusAddress = Command->V1.ScatterGatherListDMA;
+
+ CommandMailbox->Type5.ScatterGatherCount = SegCount;
+
+ for (i = 0; i < SegCount; i++, ScatterList++, ScatterGatherList++) {
+ ScatterGatherList->SegmentDataPointer =
+ (DAC960_BusAddress32_T)sg_dma_address(ScatterList);
+ ScatterGatherList->SegmentByteCount =
+ (DAC960_ByteCount32_T)sg_dma_len(ScatterList);
+ }
}
DAC960_QueueCommand(Command);
}
@@ -2739,18 +3111,32 @@ static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command)
{
DAC960_Controller_T *Controller = Command->Controller;
DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+ struct scatterlist *ScatterList = Command->V2.ScatterList;
+ int DmaDirection, SegCount;
+
DAC960_V2_ClearCommand(Command);
+
+ if (Command->CommandType == DAC960_ReadCommand)
+ DmaDirection = PCI_DMA_FROMDEVICE;
+ else
+ DmaDirection = PCI_DMA_TODEVICE;
+
+ SegCount = blk_rq_map_sg(&Controller->RequestQueue, Command->Request,
+ ScatterList);
+ /* pci_map_sg MAY change the value of SegCount */
+ SegCount = pci_map_sg(Command->PciDevice, ScatterList, SegCount,
+ DmaDirection);
+ Command->SegmentCount = SegCount;
+
CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10;
CommandMailbox->SCSI_10.CommandControlBits.DataTransferControllerToHost =
(Command->CommandType == DAC960_ReadCommand);
CommandMailbox->SCSI_10.DataTransferSize =
Command->BlockCount << DAC960_BlockSizeBits;
- CommandMailbox->SCSI_10.RequestSenseBusAddress =
- Virtual_to_Bus64(&Command->V2.RequestSense);
+ CommandMailbox->SCSI_10.RequestSenseBusAddress = Command->V2.RequestSenseDMA;
CommandMailbox->SCSI_10.PhysicalDevice =
Controller->V2.LogicalDriveToVirtualDevice[Command->LogicalDriveNumber];
- CommandMailbox->SCSI_10.RequestSenseSize =
- sizeof(DAC960_SCSI_RequestSense_T);
+ CommandMailbox->SCSI_10.RequestSenseSize = sizeof(DAC960_SCSI_RequestSense_T);
CommandMailbox->SCSI_10.CDBLength = 10;
CommandMailbox->SCSI_10.SCSI_CDB[0] =
(Command->CommandType == DAC960_ReadCommand ? 0x28 : 0x2A);
@@ -2760,12 +3146,13 @@ static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command)
CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
- if (Command->SegmentCount == 1)
+
+ if (SegCount == 1)
{
CommandMailbox->SCSI_10.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentDataPointer =
- Virtual_to_Bus64(Command->RequestBuffer);
+ (DAC960_BusAddress64_T)sg_dma_address(ScatterList);
CommandMailbox->SCSI_10.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentByteCount =
@@ -2773,49 +3160,30 @@ static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command)
}
else
{
- DAC960_V2_ScatterGatherSegment_T
- *ScatterGatherList = Command->V2.ScatterGatherList;
- BufferHeader_T *BufferHeader = Command->BufferHeader;
- char *LastDataEndPointer = NULL;
- int SegmentNumber = 0;
- if (Command->SegmentCount > 2)
+ DAC960_V2_ScatterGatherSegment_T *ScatterGatherList;
+ int i;
+
+ if (SegCount > 2)
{
+ ScatterGatherList = Command->V2.ScatterGatherList;
CommandMailbox->SCSI_10.CommandControlBits
.AdditionalScatterGatherListMemory = true;
CommandMailbox->SCSI_10.DataTransferMemoryAddress
- .ExtendedScatterGather.ScatterGatherList0Length =
- Command->SegmentCount;
+ .ExtendedScatterGather.ScatterGatherList0Length = SegCount;
CommandMailbox->SCSI_10.DataTransferMemoryAddress
.ExtendedScatterGather.ScatterGatherList0Address =
- Virtual_to_Bus64(ScatterGatherList);
+ Command->V2.ScatterGatherListDMA;
}
else
- ScatterGatherList =
- CommandMailbox->SCSI_10.DataTransferMemoryAddress
+ ScatterGatherList = CommandMailbox->SCSI_10.DataTransferMemoryAddress
.ScatterGatherSegments;
- while (BufferHeader != NULL)
- {
- if (bio_data(BufferHeader) == LastDataEndPointer)
- {
- ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
- BufferHeader->bi_size;
- LastDataEndPointer += BufferHeader->bi_size;
- }
- else
- {
- ScatterGatherList[SegmentNumber].SegmentDataPointer =
- Virtual_to_Bus64(bio_data(BufferHeader));
- ScatterGatherList[SegmentNumber].SegmentByteCount =
- BufferHeader->bi_size;
- LastDataEndPointer = bio_data(BufferHeader) +
- BufferHeader->bi_size;
- if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
- panic("DAC960: Scatter/Gather Segment Overflow\n");
- }
- BufferHeader = BufferHeader->bi_next;
- }
- if (SegmentNumber != Command->SegmentCount)
- panic("DAC960: SegmentNumber != SegmentCount\n");
+
+ for (i = 0; i < SegCount; i++, ScatterList++, ScatterGatherList++) {
+ ScatterGatherList->SegmentDataPointer =
+ (DAC960_BusAddress64_T)sg_dma_address(ScatterList);
+ ScatterGatherList->SegmentByteCount =
+ (DAC960_ByteCount64_T)sg_dma_len(ScatterList);
+ }
}
DAC960_QueueCommand(Command);
}
@@ -2832,32 +3200,36 @@ static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
boolean WaitForCommand)
{
RequestQueue_T *RequestQueue = &Controller->RequestQueue;
- ListHead_T *RequestQueueHead;
IO_Request_T *Request;
DAC960_Command_T *Command;
- if (RequestQueue == NULL) return false;
- RequestQueueHead = &RequestQueue->queue_head;
- while (true)
- {
- if (list_empty(RequestQueueHead)) return false;
+
+ if (!Controller->ControllerInitialized)
+ return false;
+
+ while (true) {
+ if (blk_queue_empty(RequestQueue))
+ return false;
+
Request = elv_next_request(RequestQueue);
Command = DAC960_AllocateCommand(Controller);
- if (Command != NULL) break;
- if (!WaitForCommand) return false;
+ if (Command != NULL)
+ break;
+
+ if (!WaitForCommand)
+ return false;
+
DAC960_WaitForCommand(Controller);
- }
- if (Request->cmd == READ)
+ }
+ if (rq_data_dir(Request) == READ)
Command->CommandType = DAC960_ReadCommand;
- else Command->CommandType = DAC960_WriteCommand;
+ else
+ Command->CommandType = DAC960_WriteCommand;
Command->Completion = Request->waiting;
Command->LogicalDriveNumber = (int)Request->rq_disk->private_data;
Command->BlockNumber = Request->sector;
Command->BlockCount = Request->nr_sectors;
- Command->SegmentCount = Request->nr_phys_segments;
- Command->BufferHeader = Request->bio;
- Command->RequestBuffer = Request->buffer;
+ Command->Request = Request;
blkdev_dequeue_request(Request);
- blk_put_request(Request);
DAC960_QueueReadWriteCommand(Command);
return true;
}
@@ -2904,16 +3276,43 @@ static void DAC960_RequestFunction(RequestQueue_T *RequestQueue)
individual Buffer.
*/
-static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
+static inline void DAC960_ProcessCompletedRequest(DAC960_Command_T *Command,
boolean SuccessfulIO)
{
- bio_endio(BufferHeader, BufferHeader->bi_size, SuccessfulIO ? 0 : -EIO);
- blk_finished_io(bio_sectors(BufferHeader));
-}
-
-static inline int DAC960_PartitionByCommand(DAC960_Command_T *Command)
-{
- return (int)Command->BufferHeader->bi_bdev->bd_disk->private_data;
+ DAC960_CommandType_T CommandType = Command->CommandType;
+ IO_Request_T *Request = Command->Request;
+ int DmaDirection, UpToDate;
+
+ UpToDate = 0;
+ if (SuccessfulIO)
+ UpToDate = 1;
+
+ /*
+ * We could save DmaDirection in the command structure
+ * and just reuse that information here.
+ */
+ if (CommandType == DAC960_ReadCommand ||
+ CommandType == DAC960_ReadRetryCommand)
+ DmaDirection = PCI_DMA_FROMDEVICE;
+ else
+ DmaDirection = PCI_DMA_TODEVICE;
+
+ pci_unmap_sg(Command->PciDevice, Command->V1.ScatterList,
+ Command->SegmentCount, DmaDirection);
+ /*
+ * BlockCount is redundant with nr_sectors in the request
+ * structure. Consider eliminating BlockCount from the
+ * command structure now that Command includes a pointer to
+ * the request.
+ */
+ while (end_that_request_first(Request, UpToDate, Command->BlockCount))
+ ;
+ end_that_request_last(Request);
+
+ if (Command->Completion) {
+ complete(Command->Completion);
+ Command->Completion = NULL;
+ }
}
/*
@@ -2966,13 +3365,6 @@ static void DAC960_V1_ReadWriteError(DAC960_Command_T *Command)
Controller, Controller->ControllerNumber,
Command->LogicalDriveNumber, Command->BlockNumber,
Command->BlockNumber + Command->BlockCount - 1);
- if (DAC960_PartitionByCommand(Command) > 0)
- DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %u..%u\n",
- Controller, Controller->ControllerNumber,
- Command->LogicalDriveNumber,
- DAC960_PartitionByCommand(Command),
- Command->BufferHeader->bi_sector,
- Command->BufferHeader->bi_sector + Command->BlockCount - 1);
}
@@ -2988,129 +3380,60 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
DAC960_V1_CommandOpcode_T CommandOpcode =
Command->V1.CommandMailbox.Common.CommandOpcode;
DAC960_V1_CommandStatus_T CommandStatus = Command->V1.CommandStatus;
- BufferHeader_T *BufferHeader = Command->BufferHeader;
+
if (CommandType == DAC960_ReadCommand ||
CommandType == DAC960_WriteCommand)
{
if (CommandStatus == DAC960_V1_NormalCompletion)
+
+ DAC960_ProcessCompletedRequest(Command, true);
+
+ else if (CommandStatus == DAC960_V1_IrrecoverableDataError ||
+ CommandStatus == DAC960_V1_BadDataEncountered)
{
+
/*
- Perform completion processing for all buffers in this I/O Request.
- */
- while (BufferHeader != NULL)
- {
- BufferHeader_T *NextBufferHeader = BufferHeader->bi_next;
- BufferHeader->bi_next = NULL;
- DAC960_ProcessCompletedBuffer(BufferHeader, true);
- BufferHeader = NextBufferHeader;
- }
- if (Command->Completion != NULL)
- {
- complete(Command->Completion);
- Command->Completion = NULL;
- }
- add_disk_randomness(Controller->disks[Command->LogicalDriveNumber]);
- }
- else if ((CommandStatus == DAC960_V1_IrrecoverableDataError ||
- CommandStatus == DAC960_V1_BadDataEncountered) &&
- BufferHeader != NULL &&
- BufferHeader->bi_next != NULL)
- {
- DAC960_V1_CommandMailbox_T *CommandMailbox =
- &Command->V1.CommandMailbox;
- if (CommandType == DAC960_ReadCommand)
- {
- Command->CommandType = DAC960_ReadRetryCommand;
- CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
- }
- else
- {
- Command->CommandType = DAC960_WriteRetryCommand;
- CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
- }
- Command->BlockCount = BufferHeader->bi_size >> DAC960_BlockSizeBits;
- CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
- CommandMailbox->Type5.BusAddress =
- Virtual_to_Bus32(bio_data(BufferHeader));
- DAC960_QueueCommand(Command);
- return;
+ * Finish this later.
+ *
+ * We should call "complete_that_request_first()"
+ * to remove the first part of the request. Then, if there
+ * is still more I/O to be done, resubmit the request.
+ *
+ * We want to recalculate scatter/gather list,
+ * and requeue the command.
+ *
+ * For now, print a message on the console, and clone
+ * the code for "normal" completion.
+ */
+ printk("V1_ProcessCompletedCommand: I/O error on read/write\n");
+
+ DAC960_ProcessCompletedRequest(Command, false);
}
else
{
if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
DAC960_V1_ReadWriteError(Command);
- /*
- Perform completion processing for all buffers in this I/O Request.
- */
- while (BufferHeader != NULL)
- {
- BufferHeader_T *NextBufferHeader = BufferHeader->bi_next;
- BufferHeader->bi_next = NULL;
- DAC960_ProcessCompletedBuffer(BufferHeader, false);
- BufferHeader = NextBufferHeader;
- }
- if (Command->Completion != NULL)
- {
- complete(Command->Completion);
- Command->Completion = NULL;
- }
+
+ DAC960_ProcessCompletedRequest(Command, false);
}
}
else if (CommandType == DAC960_ReadRetryCommand ||
CommandType == DAC960_WriteRetryCommand)
{
- BufferHeader_T *NextBufferHeader = BufferHeader->bi_next;
- BufferHeader->bi_next = NULL;
- /*
- Perform completion processing for this single buffer.
- */
- if (CommandStatus == DAC960_V1_NormalCompletion)
- DAC960_ProcessCompletedBuffer(BufferHeader, true);
- else
- {
- if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
- DAC960_V1_ReadWriteError(Command);
- DAC960_ProcessCompletedBuffer(BufferHeader, false);
- }
- if (NextBufferHeader != NULL)
- {
- DAC960_V1_CommandMailbox_T *CommandMailbox =
- &Command->V1.CommandMailbox;
- Command->BlockNumber +=
- BufferHeader->bi_size >> DAC960_BlockSizeBits;
- Command->BlockCount =
- NextBufferHeader->bi_size >> DAC960_BlockSizeBits;
- Command->BufferHeader = NextBufferHeader;
- CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
- CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
- CommandMailbox->Type5.BusAddress =
- Virtual_to_Bus32(bio_data(NextBufferHeader));
- DAC960_QueueCommand(Command);
- return;
- }
+ /*
+ * We're not doing retry commands yet.
+ */
+ printk("DAC960_ProcessCompletedCommand: RetryCommand not done yet\n");
}
- else if (CommandType == DAC960_MonitoringCommand ||
- CommandOpcode == DAC960_V1_Enquiry ||
- CommandOpcode == DAC960_V1_GetRebuildProgress)
+
+ else if (CommandType == DAC960_MonitoringCommand)
{
- if (CommandType != DAC960_MonitoringCommand)
- {
- if (CommandOpcode == DAC960_V1_Enquiry)
- memcpy(&Controller->V1.NewEnquiry,
- Bus32_to_Virtual(Command->V1.CommandMailbox
- .Type3.BusAddress),
- sizeof(DAC960_V1_Enquiry_T));
- else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
- memcpy(&Controller->V1.RebuildProgress,
- Bus32_to_Virtual(Command->V1.CommandMailbox
- .Type3.BusAddress),
- sizeof(DAC960_V1_RebuildProgress_T));
- }
- if (CommandOpcode == DAC960_V1_Enquiry &&
- Controller->ControllerInitialized)
+ if (Controller->ShutdownMonitoringTimer)
+ return;
+ if (CommandOpcode == DAC960_V1_Enquiry)
{
DAC960_V1_Enquiry_T *OldEnquiry = &Controller->V1.Enquiry;
- DAC960_V1_Enquiry_T *NewEnquiry = &Controller->V1.NewEnquiry;
+ DAC960_V1_Enquiry_T *NewEnquiry = Controller->V1.NewEnquiry;
unsigned int OldCriticalLogicalDriveCount =
OldEnquiry->CriticalLogicalDriveCount;
unsigned int NewCriticalLogicalDriveCount =
@@ -3220,17 +3543,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
(NewEnquiry->CriticalLogicalDriveCount > 0 ||
NewEnquiry->OfflineLogicalDriveCount > 0 ||
NewEnquiry->DeadDriveCount > 0);
- if (CommandType != DAC960_MonitoringCommand &&
- Controller->V1.RebuildFlagPending)
- {
- DAC960_V1_Enquiry_T *Enquiry = (DAC960_V1_Enquiry_T *)
- Bus32_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress);
- Enquiry->RebuildFlag = Controller->V1.PendingRebuildFlag;
- Controller->V1.RebuildFlagPending = false;
- }
- else if (CommandType == DAC960_MonitoringCommand &&
- NewEnquiry->RebuildFlag >
- DAC960_V1_BackgroundCheckInProgress)
+ if (NewEnquiry->RebuildFlag > DAC960_V1_BackgroundCheckInProgress)
{
Controller->V1.PendingRebuildFlag = NewEnquiry->RebuildFlag;
Controller->V1.RebuildFlagPending = true;
@@ -3256,7 +3569,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
"killed due to SCSI phase sequence error",
"killed due to unknown status" };
DAC960_V1_EventLogEntry_T *EventLogEntry =
- &Controller->V1.EventLogEntry;
+ Controller->V1.EventLogEntry;
if (EventLogEntry->SequenceNumber ==
Controller->V1.OldEventLogSequenceNumber)
{
@@ -3316,7 +3629,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
else if (CommandOpcode == DAC960_V1_GetErrorTable)
{
DAC960_V1_ErrorTable_T *OldErrorTable = &Controller->V1.ErrorTable;
- DAC960_V1_ErrorTable_T *NewErrorTable = &Controller->V1.NewErrorTable;
+ DAC960_V1_ErrorTable_T *NewErrorTable = Controller->V1.NewErrorTable;
int Channel, TargetID;
for (Channel = 0; Channel < Controller->Channels; Channel++)
for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
@@ -3342,7 +3655,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
NewErrorEntry->HardErrorCount,
NewErrorEntry->MiscErrorCount);
}
- memcpy(&Controller->V1.ErrorTable, &Controller->V1.NewErrorTable,
+ memcpy(&Controller->V1.ErrorTable, Controller->V1.NewErrorTable,
sizeof(DAC960_V1_ErrorTable_T));
}
else if (CommandOpcode == DAC960_V1_GetDeviceState)
@@ -3351,7 +3664,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
&Controller->V1.DeviceState[Controller->V1.DeviceStateChannel]
[Controller->V1.DeviceStateTargetID];
DAC960_V1_DeviceState_T *NewDeviceState =
- &Controller->V1.NewDeviceState;
+ Controller->V1.NewDeviceState;
if (NewDeviceState->DeviceState != OldDeviceState->DeviceState)
DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
Controller->V1.DeviceStateChannel,
@@ -3387,7 +3700,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
DAC960_V1_LogicalDriveInformation_T *OldLogicalDriveInformation =
&Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
DAC960_V1_LogicalDriveInformation_T *NewLogicalDriveInformation =
- &Controller->V1.NewLogicalDriveInformation[LogicalDriveNumber];
+ &(*Controller->V1.NewLogicalDriveInformation)[LogicalDriveNumber];
if (NewLogicalDriveInformation->LogicalDriveState !=
OldLogicalDriveInformation->LogicalDriveState)
DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
@@ -3412,17 +3725,17 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
? "WRITE BACK" : "WRITE THRU"));
}
memcpy(&Controller->V1.LogicalDriveInformation,
- &Controller->V1.NewLogicalDriveInformation,
+ Controller->V1.NewLogicalDriveInformation,
sizeof(DAC960_V1_LogicalDriveInformationArray_T));
}
else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
{
unsigned int LogicalDriveNumber =
- Controller->V1.RebuildProgress.LogicalDriveNumber;
+ Controller->V1.RebuildProgress->LogicalDriveNumber;
unsigned int LogicalDriveSize =
- Controller->V1.RebuildProgress.LogicalDriveSize;
+ Controller->V1.RebuildProgress->LogicalDriveSize;
unsigned int BlocksCompleted =
- LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
+ LogicalDriveSize - Controller->V1.RebuildProgress->RemainingBlocks;
if (CommandStatus == DAC960_V1_NoRebuildOrCheckInProgress &&
Controller->V1.LastRebuildStatus == DAC960_V1_NormalCompletion)
CommandStatus = DAC960_V1_RebuildSuccessful;
@@ -3479,11 +3792,11 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
else if (CommandOpcode == DAC960_V1_RebuildStat)
{
unsigned int LogicalDriveNumber =
- Controller->V1.RebuildProgress.LogicalDriveNumber;
+ Controller->V1.RebuildProgress->LogicalDriveNumber;
unsigned int LogicalDriveSize =
- Controller->V1.RebuildProgress.LogicalDriveSize;
+ Controller->V1.RebuildProgress->LogicalDriveSize;
unsigned int BlocksCompleted =
- LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
+ LogicalDriveSize - Controller->V1.RebuildProgress->RemainingBlocks;
if (CommandStatus == DAC960_V1_NormalCompletion)
{
Controller->EphemeralProgressMessage = true;
@@ -3501,15 +3814,15 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
else if (CommandOpcode == DAC960_V1_BackgroundInitializationControl)
{
unsigned int LogicalDriveNumber =
- Controller->V1.BackgroundInitializationStatus.LogicalDriveNumber;
+ Controller->V1.BackgroundInitializationStatus->LogicalDriveNumber;
unsigned int LogicalDriveSize =
- Controller->V1.BackgroundInitializationStatus.LogicalDriveSize;
+ Controller->V1.BackgroundInitializationStatus->LogicalDriveSize;
unsigned int BlocksCompleted =
- Controller->V1.BackgroundInitializationStatus.BlocksCompleted;
+ Controller->V1.BackgroundInitializationStatus->BlocksCompleted;
switch (CommandStatus)
{
case DAC960_V1_NormalCompletion:
- switch (Controller->V1.BackgroundInitializationStatus.Status)
+ switch (Controller->V1.BackgroundInitializationStatus->Status)
{
case DAC960_V1_BackgroundInitializationInvalid:
break;
@@ -3519,11 +3832,11 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
break;
case DAC960_V1_BackgroundInitializationInProgress:
if (BlocksCompleted ==
- Controller->V1.LastBackgroundInitializationStatus
- .BlocksCompleted &&
+ Controller->V1.LastBackgroundInitializationStatus.
+ BlocksCompleted &&
LogicalDriveNumber ==
- Controller->V1.LastBackgroundInitializationStatus
- .LogicalDriveNumber)
+ Controller->V1.LastBackgroundInitializationStatus.
+ LogicalDriveNumber)
break;
Controller->EphemeralProgressMessage = true;
DAC960_Progress("Background Initialization in Progress: "
@@ -3546,32 +3859,84 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
break;
}
memcpy(&Controller->V1.LastBackgroundInitializationStatus,
- &Controller->V1.BackgroundInitializationStatus,
+ Controller->V1.BackgroundInitializationStatus,
sizeof(DAC960_V1_BackgroundInitializationStatus_T));
break;
case DAC960_V1_BackgroundInitSuccessful:
- if (Controller->V1.BackgroundInitializationStatus.Status ==
+ if (Controller->V1.BackgroundInitializationStatus->Status ==
DAC960_V1_BackgroundInitializationInProgress)
DAC960_Progress("Background Initialization "
"Completed Successfully\n", Controller);
- Controller->V1.BackgroundInitializationStatus.Status =
+ Controller->V1.BackgroundInitializationStatus->Status =
DAC960_V1_BackgroundInitializationInvalid;
break;
case DAC960_V1_BackgroundInitAborted:
- if (Controller->V1.BackgroundInitializationStatus.Status ==
+ if (Controller->V1.BackgroundInitializationStatus->Status ==
DAC960_V1_BackgroundInitializationInProgress)
DAC960_Progress("Background Initialization Aborted\n",
Controller);
- Controller->V1.BackgroundInitializationStatus.Status =
+ Controller->V1.BackgroundInitializationStatus->Status =
DAC960_V1_BackgroundInitializationInvalid;
break;
case DAC960_V1_NoBackgroundInitInProgress:
break;
}
+ }
+ else if (CommandOpcode == DAC960_V1_DCDB)
+ {
+ /*
+ This is a bit ugly.
+
+ The InquiryStandardData and
+ the InquiryUntitSerialNumber information
+ retrieval operations BOTH use the DAC960_V1_DCDB
+ commands. the test above can't distinguish between
+ these two cases.
+
+ Instead, we rely on the order of code later in this
+ function to ensure that DeviceInquiryInformation commands
+ are submitted before DeviceSerialNumber commands.
+ */
+ if (Controller->V1.NeedDeviceInquiryInformation)
+ {
+ DAC960_SCSI_Inquiry_T *InquiryStandardData =
+ &Controller->V1.InquiryStandardData
+ [Controller->V1.DeviceStateChannel]
+ [Controller->V1.DeviceStateTargetID];
+ if (CommandStatus != DAC960_V1_NormalCompletion)
+ {
+ memset(InquiryStandardData, 0,
+ sizeof(DAC960_SCSI_Inquiry_T));
+ InquiryStandardData->PeripheralDeviceType = 0x1F;
+ }
+ else
+ memcpy(InquiryStandardData,
+ Controller->V1.NewInquiryStandardData,
+ sizeof(DAC960_SCSI_Inquiry_T));
+ Controller->V1.NeedDeviceInquiryInformation = false;
+ }
+ else if (Controller->V1.NeedDeviceSerialNumberInformation)
+ {
+ DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
+ &Controller->V1.InquiryUnitSerialNumber
+ [Controller->V1.DeviceStateChannel]
+ [Controller->V1.DeviceStateTargetID];
+ if (CommandStatus != DAC960_V1_NormalCompletion)
+ {
+ memset(InquiryUnitSerialNumber, 0,
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
+ InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+ }
+ else
+ memcpy(InquiryUnitSerialNumber,
+ Controller->V1.NewInquiryUnitSerialNumber,
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
+ Controller->V1.NeedDeviceSerialNumberInformation = false;
+ }
}
- }
- if (CommandType == DAC960_MonitoringCommand)
- {
+ /*
+ Begin submitting new monitoring commands.
+ */
if (Controller->V1.NewEventLogSequenceNumber
- Controller->V1.OldEventLogSequenceNumber > 0)
{
@@ -3583,7 +3948,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
Command->V1.CommandMailbox.Type3E.SequenceNumber =
Controller->V1.OldEventLogSequenceNumber;
Command->V1.CommandMailbox.Type3E.BusAddress =
- Virtual_to_Bus32(&Controller->V1.EventLogEntry);
+ Controller->V1.EventLogEntryDMA;
DAC960_QueueCommand(Command);
return;
}
@@ -3593,7 +3958,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
Command->V1.CommandMailbox.Type3.CommandOpcode =
DAC960_V1_GetErrorTable;
Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(&Controller->V1.NewErrorTable);
+ Controller->V1.NewErrorTableDMA;
DAC960_QueueCommand(Command);
return;
}
@@ -3604,7 +3969,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
Command->V1.CommandMailbox.Type3.CommandOpcode =
DAC960_V1_GetRebuildProgress;
Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(&Controller->V1.RebuildProgress);
+ Controller->V1.RebuildProgressDMA;
DAC960_QueueCommand(Command);
return;
}
@@ -3612,15 +3977,14 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
{
if (Controller->V1.NeedDeviceInquiryInformation)
{
- DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
- DAC960_SCSI_Inquiry_T *InquiryStandardData =
- &Controller->V1.InquiryStandardData
- [Controller->V1.DeviceStateChannel]
- [Controller->V1.DeviceStateTargetID];
- InquiryStandardData->PeripheralDeviceType = 0x1F;
+ DAC960_V1_DCDB_T *DCDB = Controller->V1.MonitoringDCDB;
+ dma_addr_t DCDB_DMA = Controller->V1.MonitoringDCDB_DMA;
+
+ dma_addr_t NewInquiryStandardDataDMA =
+ Controller->V1.NewInquiryStandardDataDMA;
+
Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
- Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(DCDB);
+ Command->V1.CommandMailbox.Type3.BusAddress = DCDB_DMA;
DCDB->Channel = Controller->V1.DeviceStateChannel;
DCDB->TargetID = Controller->V1.DeviceStateTargetID;
DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
@@ -3629,7 +3993,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
DCDB->NoAutomaticRequestSense = false;
DCDB->DisconnectPermitted = true;
DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
- DCDB->BusAddress = Virtual_to_Bus32(InquiryStandardData);
+ DCDB->BusAddress = NewInquiryStandardDataDMA;
DCDB->CDBLength = 6;
DCDB->TransferLengthHigh4 = 0;
DCDB->SenseLength = sizeof(DCDB->SenseData);
@@ -3640,20 +4004,17 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
DCDB->CDB[5] = 0; /* Control */
DAC960_QueueCommand(Command);
- Controller->V1.NeedDeviceInquiryInformation = false;
return;
}
if (Controller->V1.NeedDeviceSerialNumberInformation)
{
- DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
- DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
- &Controller->V1.InquiryUnitSerialNumber
- [Controller->V1.DeviceStateChannel]
- [Controller->V1.DeviceStateTargetID];
- InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+ DAC960_V1_DCDB_T *DCDB = Controller->V1.MonitoringDCDB;
+ dma_addr_t DCDB_DMA = Controller->V1.MonitoringDCDB_DMA;
+ dma_addr_t NewInquiryUnitSerialNumberDMA =
+ Controller->V1.NewInquiryUnitSerialNumberDMA;
+
Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
- Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(DCDB);
+ Command->V1.CommandMailbox.Type3.BusAddress = DCDB_DMA;
DCDB->Channel = Controller->V1.DeviceStateChannel;
DCDB->TargetID = Controller->V1.DeviceStateTargetID;
DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
@@ -3663,7 +4024,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
DCDB->DisconnectPermitted = true;
DCDB->TransferLength =
sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
- DCDB->BusAddress = Virtual_to_Bus32(InquiryUnitSerialNumber);
+ DCDB->BusAddress = NewInquiryUnitSerialNumberDMA;
DCDB->CDBLength = 6;
DCDB->TransferLengthHigh4 = 0;
DCDB->SenseLength = sizeof(DCDB->SenseData);
@@ -3674,7 +4035,6 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
DCDB->CDB[5] = 0; /* Control */
DAC960_QueueCommand(Command);
- Controller->V1.NeedDeviceSerialNumberInformation = false;
return;
}
if (Controller->V1.StartDeviceStateScan)
@@ -3690,7 +4050,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
}
if (Controller->V1.DeviceStateChannel < Controller->Channels)
{
- Controller->V1.NewDeviceState.DeviceState =
+ Controller->V1.NewDeviceState->DeviceState =
DAC960_V1_Device_Dead;
Command->V1.CommandMailbox.Type3D.CommandOpcode =
DAC960_V1_GetDeviceState;
@@ -3699,7 +4059,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
Command->V1.CommandMailbox.Type3D.TargetID =
Controller->V1.DeviceStateTargetID;
Command->V1.CommandMailbox.Type3D.BusAddress =
- Virtual_to_Bus32(&Controller->V1.NewDeviceState);
+ Controller->V1.NewDeviceStateDMA;
DAC960_QueueCommand(Command);
return;
}
@@ -3711,7 +4071,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
Command->V1.CommandMailbox.Type3.CommandOpcode =
DAC960_V1_GetLogicalDriveInformation;
Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(&Controller->V1.NewLogicalDriveInformation);
+ Controller->V1.NewLogicalDriveInformationDMA;
DAC960_QueueCommand(Command);
return;
}
@@ -3721,7 +4081,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
Command->V1.CommandMailbox.Type3.CommandOpcode =
DAC960_V1_GetRebuildProgress;
Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(&Controller->V1.RebuildProgress);
+ Controller->V1.RebuildProgressDMA;
DAC960_QueueCommand(Command);
return;
}
@@ -3731,7 +4091,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
Command->V1.CommandMailbox.Type3.CommandOpcode =
DAC960_V1_RebuildStat;
Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(&Controller->V1.RebuildProgress);
+ Controller->V1.RebuildProgressDMA;
DAC960_QueueCommand(Command);
return;
}
@@ -3742,14 +4102,14 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
DAC960_V1_BackgroundInitializationControl;
Command->V1.CommandMailbox.Type3B.CommandOpcode2 = 0x20;
Command->V1.CommandMailbox.Type3B.BusAddress =
- Virtual_to_Bus32(&Controller->V1.BackgroundInitializationStatus);
+ Controller->V1.BackgroundInitializationStatusDMA;
DAC960_QueueCommand(Command);
return;
}
Controller->MonitoringTimerCount++;
Controller->MonitoringTimer.expires =
jiffies + DAC960_MonitoringTimerInterval;
- add_timer(&Controller->MonitoringTimer);
+ add_timer(&Controller->MonitoringTimer);
}
if (CommandType == DAC960_ImmediateCommand)
{
@@ -3825,18 +4185,11 @@ static void DAC960_V2_ReadWriteError(DAC960_Command_T *Command)
break;
}
DAC960_Error("Error Condition %s on %s:\n", Controller,
- SenseErrors[Command->V2.RequestSense.SenseKey], CommandName);
+ SenseErrors[Command->V2.RequestSense->SenseKey], CommandName);
DAC960_Error(" /dev/rd/c%dd%d: absolute blocks %u..%u\n",
Controller, Controller->ControllerNumber,
Command->LogicalDriveNumber, Command->BlockNumber,
Command->BlockNumber + Command->BlockCount - 1);
- if (DAC960_PartitionByCommand(Command) > 0)
- DAC960_Error(" /dev/rd/c%dd%dp%d: relative blocks %u..%u\n",
- Controller, Controller->ControllerNumber,
- Command->LogicalDriveNumber,
- DAC960_PartitionByCommand(Command),
- Command->BufferHeader->bi_sector,
- Command->BufferHeader->bi_sector + Command->BlockCount - 1);
}
@@ -4094,123 +4447,51 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
DAC960_V2_IOCTL_Opcode_T CommandOpcode = CommandMailbox->Common.IOCTL_Opcode;
DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus;
- BufferHeader_T *BufferHeader = Command->BufferHeader;
+
if (CommandType == DAC960_ReadCommand ||
CommandType == DAC960_WriteCommand)
{
if (CommandStatus == DAC960_V2_NormalCompletion)
+
+ DAC960_ProcessCompletedRequest(Command, true);
+
+ else if (Command->V2.RequestSense->SenseKey == DAC960_SenseKey_MediumError)
{
+
/*
- Perform completion processing for all buffers in this I/O Request.
- */
- while (BufferHeader != NULL)
- {
- BufferHeader_T *NextBufferHeader = BufferHeader->bi_next;
- BufferHeader->bi_next = NULL;
- DAC960_ProcessCompletedBuffer(BufferHeader, true);
- BufferHeader = NextBufferHeader;
- }
- if (Command->Completion != NULL)
- {
- complete(Command->Completion);
- Command->Completion = NULL;
- }
- add_disk_randomness(Controller->disks[Command->LogicalDriveNumber]);
- }
- else if (Command->V2.RequestSense.SenseKey
- == DAC960_SenseKey_MediumError &&
- BufferHeader != NULL &&
- BufferHeader->bi_next != NULL)
- {
- if (CommandType == DAC960_ReadCommand)
- Command->CommandType = DAC960_ReadRetryCommand;
- else Command->CommandType = DAC960_WriteRetryCommand;
- Command->BlockCount = BufferHeader->bi_size >> DAC960_BlockSizeBits;
- CommandMailbox->SCSI_10.CommandControlBits
- .AdditionalScatterGatherListMemory = false;
- CommandMailbox->SCSI_10.DataTransferSize =
- Command->BlockCount << DAC960_BlockSizeBits;
- CommandMailbox->SCSI_10.DataTransferMemoryAddress
- .ScatterGatherSegments[0].SegmentDataPointer =
- Virtual_to_Bus64(bio_data(BufferHeader));
- CommandMailbox->SCSI_10.DataTransferMemoryAddress
- .ScatterGatherSegments[0].SegmentByteCount =
- CommandMailbox->SCSI_10.DataTransferSize;
- CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
- CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
- DAC960_QueueCommand(Command);
- return;
+ * Don't know yet how to handle this case.
+ * See comments in DAC960_V1_ProcessCompletedCommand()
+ *
+ * For now, print a message on the console, and clone
+ * the code for "normal" completion.
+ */
+ printk("V1_ProcessCompletedCommand: I/O error on read/write\n");
+
+ DAC960_ProcessCompletedRequest(Command, false);
}
else
{
- if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
+ if (Command->V2.RequestSense->SenseKey != DAC960_SenseKey_NotReady)
DAC960_V2_ReadWriteError(Command);
/*
Perform completion processing for all buffers in this I/O Request.
*/
- while (BufferHeader != NULL)
- {
- BufferHeader_T *NextBufferHeader = BufferHeader->bi_next;
- BufferHeader->bi_next = NULL;
- DAC960_ProcessCompletedBuffer(BufferHeader, false);
- BufferHeader = NextBufferHeader;
- }
- if (Command->Completion != NULL)
- {
- complete(Command->Completion);
- Command->Completion = NULL;
- }
+ DAC960_ProcessCompletedRequest(Command, false);
}
}
else if (CommandType == DAC960_ReadRetryCommand ||
CommandType == DAC960_WriteRetryCommand)
{
- BufferHeader_T *NextBufferHeader = BufferHeader->bi_next;
- BufferHeader->bi_next = NULL;
- /*
- Perform completion processing for this single buffer.
- */
- if (CommandStatus == DAC960_V2_NormalCompletion)
- DAC960_ProcessCompletedBuffer(BufferHeader, true);
- else
- {
- if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
- DAC960_V2_ReadWriteError(Command);
- DAC960_ProcessCompletedBuffer(BufferHeader, false);
- }
- if (NextBufferHeader != NULL)
- {
- Command->BlockNumber +=
- BufferHeader->bi_size >> DAC960_BlockSizeBits;
- Command->BlockCount =
- NextBufferHeader->bi_size >> DAC960_BlockSizeBits;
- Command->BufferHeader = NextBufferHeader;
- CommandMailbox->SCSI_10.DataTransferSize =
- Command->BlockCount << DAC960_BlockSizeBits;
- CommandMailbox->SCSI_10.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(bio_data(NextBufferHeader));
- CommandMailbox->SCSI_10.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentByteCount =
- CommandMailbox->SCSI_10.DataTransferSize;
- CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
- CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
- CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
- CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
- CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
- CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
- DAC960_QueueCommand(Command);
- return;
- }
+ printk("DAC960_V2_ProcessCompletedCommand: retries not coded yet\n");
}
else if (CommandType == DAC960_MonitoringCommand)
{
+ if (Controller->ShutdownMonitoringTimer)
+ return;
if (CommandOpcode == DAC960_V2_GetControllerInfo)
{
DAC960_V2_ControllerInfo_T *NewControllerInfo =
- &Controller->V2.NewControllerInformation;
+ Controller->V2.NewControllerInformation;
DAC960_V2_ControllerInfo_T *ControllerInfo =
&Controller->V2.ControllerInformation;
Controller->LogicalDriveCount =
@@ -4229,15 +4510,16 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
}
else if (CommandOpcode == DAC960_V2_GetEvent)
{
- if (CommandStatus == DAC960_V2_NormalCompletion)
- DAC960_V2_ReportEvent(Controller, &Controller->V2.Event);
+ if (CommandStatus == DAC960_V2_NormalCompletion) {
+ DAC960_V2_ReportEvent(Controller, Controller->V2.Event);
+ }
Controller->V2.NextEventSequenceNumber++;
}
else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid &&
CommandStatus == DAC960_V2_NormalCompletion)
{
DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
- &Controller->V2.NewPhysicalDeviceInformation;
+ Controller->V2.NewPhysicalDeviceInformation;
unsigned int PhysicalDeviceIndex = Controller->V2.PhysicalDeviceIndex;
DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
@@ -4448,7 +4730,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
CommandStatus == DAC960_V2_NormalCompletion)
{
DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
- &Controller->V2.NewLogicalDeviceInformation;
+ Controller->V2.NewLogicalDeviceInformation;
unsigned short LogicalDeviceNumber =
NewLogicalDeviceInfo->LogicalDeviceNumber;
DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
@@ -4598,6 +4880,23 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
}
Controller->V2.NeedLogicalDeviceInformation = false;
}
+ else if (CommandOpcode == DAC960_V2_SCSI_10_Passthru)
+ {
+ DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
+ Controller->V2.InquiryUnitSerialNumber[Controller->V2.PhysicalDeviceIndex - 1];
+
+ if (CommandStatus != DAC960_V2_NormalCompletion) {
+ memset(InquiryUnitSerialNumber,
+ 0, sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
+ InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+ } else
+ memcpy(InquiryUnitSerialNumber,
+ Controller->V2.NewInquiryUnitSerialNumber,
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
+
+ Controller->V2.NeedDeviceSerialNumberInformation = false;
+ }
+
if (Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
- Controller->V2.NextEventSequenceNumber > 0)
{
@@ -4613,7 +4912,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
CommandMailbox->GetEvent.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentDataPointer =
- Virtual_to_Bus64(&Controller->V2.Event);
+ Controller->V2.EventDMA;
CommandMailbox->GetEvent.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentByteCount =
@@ -4626,62 +4925,41 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
if (Controller->V2.NeedDeviceSerialNumberInformation)
{
DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
- Controller->V2.InquiryUnitSerialNumber
- [Controller->V2.PhysicalDeviceIndex - 1];
+ Controller->V2.NewInquiryUnitSerialNumber;
InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
- CommandMailbox->SCSI_10.CommandOpcode =
- DAC960_V2_SCSI_10_Passthru;
- CommandMailbox->SCSI_10.DataTransferSize =
- sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
- CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit =
- Controller->V2.NewPhysicalDeviceInformation.LogicalUnit - 1;
- CommandMailbox->SCSI_10.PhysicalDevice.TargetID =
- Controller->V2.NewPhysicalDeviceInformation.TargetID;
- CommandMailbox->SCSI_10.PhysicalDevice.Channel =
- Controller->V2.NewPhysicalDeviceInformation.Channel;
- CommandMailbox->SCSI_10.CDBLength = 6;
- CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
- CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
- CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
- CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
- CommandMailbox->SCSI_10.SCSI_CDB[4] =
- sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
- CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
- CommandMailbox->SCSI_10.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(InquiryUnitSerialNumber);
- CommandMailbox->SCSI_10.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentByteCount =
- CommandMailbox->SCSI_10.DataTransferSize;
+
+ DAC960_V2_ConstructNewUnitSerialNumber(Controller, CommandMailbox,
+ Controller->V2.NewPhysicalDeviceInformation->Channel,
+ Controller->V2.NewPhysicalDeviceInformation->TargetID,
+ Controller->V2.NewPhysicalDeviceInformation->LogicalUnit - 1);
+
+
DAC960_QueueCommand(Command);
- Controller->V2.NeedDeviceSerialNumberInformation = false;
return;
}
if (Controller->V2.StartPhysicalDeviceInformationScan)
{
Controller->V2.PhysicalDeviceIndex = 0;
- Controller->V2.NewPhysicalDeviceInformation.Channel = 0;
- Controller->V2.NewPhysicalDeviceInformation.TargetID = 0;
- Controller->V2.NewPhysicalDeviceInformation.LogicalUnit = 0;
+ Controller->V2.NewPhysicalDeviceInformation->Channel = 0;
+ Controller->V2.NewPhysicalDeviceInformation->TargetID = 0;
+ Controller->V2.NewPhysicalDeviceInformation->LogicalUnit = 0;
Controller->V2.StartPhysicalDeviceInformationScan = false;
}
CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
sizeof(DAC960_V2_PhysicalDeviceInfo_T);
CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit =
- Controller->V2.NewPhysicalDeviceInformation.LogicalUnit;
+ Controller->V2.NewPhysicalDeviceInformation->LogicalUnit;
CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID =
- Controller->V2.NewPhysicalDeviceInformation.TargetID;
+ Controller->V2.NewPhysicalDeviceInformation->TargetID;
CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel =
- Controller->V2.NewPhysicalDeviceInformation.Channel;
+ Controller->V2.NewPhysicalDeviceInformation->Channel;
CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
DAC960_V2_GetPhysicalDeviceInfoValid;
CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentDataPointer =
- Virtual_to_Bus64(&Controller->V2.NewPhysicalDeviceInformation);
+ Controller->V2.NewPhysicalDeviceInformationDMA;
CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentByteCount =
@@ -4699,21 +4977,20 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
LogicalDriveNumber++)
Controller->V2.LogicalDriveFoundDuringScan
[LogicalDriveNumber] = false;
- Controller->V2.NewLogicalDeviceInformation
- .LogicalDeviceNumber = 0;
+ Controller->V2.NewLogicalDeviceInformation->LogicalDeviceNumber = 0;
Controller->V2.StartLogicalDeviceInformationScan = false;
}
CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
CommandMailbox->LogicalDeviceInfo.DataTransferSize =
sizeof(DAC960_V2_LogicalDeviceInfo_T);
CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
- Controller->V2.NewLogicalDeviceInformation.LogicalDeviceNumber;
+ Controller->V2.NewLogicalDeviceInformation->LogicalDeviceNumber;
CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
DAC960_V2_GetLogicalDeviceInfoValid;
CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentDataPointer =
- Virtual_to_Bus64(&Controller->V2.NewLogicalDeviceInformation);
+ Controller->V2.NewLogicalDeviceInformationDMA;
CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentByteCount =
@@ -4724,7 +5001,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
Controller->MonitoringTimerCount++;
Controller->MonitoringTimer.expires =
jiffies + DAC960_HealthStatusMonitoringInterval;
- add_timer(&Controller->MonitoringTimer);
+ add_timer(&Controller->MonitoringTimer);
}
if (CommandType == DAC960_ImmediateCommand)
{
@@ -5002,6 +5279,10 @@ static void DAC960_PD_InterruptHandler(int IRQ_Channel,
/*
DAC960_P_InterruptHandler handles hardware interrupts from DAC960 P Series
Controllers.
+
+ Translations of DAC960_V1_Enquiry and DAC960_V1_GetDeviceState rely
+ on the data having been placed into DAC960_Controller_T, rather than
+ an arbitrary buffer.
*/
static void DAC960_P_InterruptHandler(int IRQ_Channel,
@@ -5034,14 +5315,12 @@ static void DAC960_P_InterruptHandler(int IRQ_Channel,
{
case DAC960_V1_Enquiry_Old:
Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Enquiry;
- DAC960_P_To_PD_TranslateEnquiry(
- Bus32_to_Virtual(CommandMailbox->Type3.BusAddress));
+ DAC960_P_To_PD_TranslateEnquiry(Controller->V1.NewEnquiry);
break;
case DAC960_V1_GetDeviceState_Old:
Command->V1.CommandMailbox.Common.CommandOpcode =
- DAC960_V1_GetDeviceState;
- DAC960_P_To_PD_TranslateDeviceState(
- Bus32_to_Virtual(CommandMailbox->Type3.BusAddress));
+ DAC960_V1_GetDeviceState;
+ DAC960_P_To_PD_TranslateDeviceState(Controller->V1.NewDeviceState);
break;
case DAC960_V1_Read_Old:
Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Read;
@@ -5090,8 +5369,7 @@ static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *Command)
DAC960_V1_ClearCommand(Command);
Command->CommandType = DAC960_MonitoringCommand;
CommandMailbox->Type3.CommandOpcode = DAC960_V1_Enquiry;
- CommandMailbox->Type3.BusAddress =
- Virtual_to_Bus32(&Controller->V1.NewEnquiry);
+ CommandMailbox->Type3.BusAddress = Controller->V1.NewEnquiryDMA;
DAC960_QueueCommand(Command);
}
@@ -5119,7 +5397,7 @@ static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *Command)
CommandMailbox->ControllerInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentDataPointer =
- Virtual_to_Bus64(&Controller->V2.NewControllerInformation);
+ Controller->V2.NewControllerInformationDMA;
CommandMailbox->ControllerInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentByteCount =
@@ -5198,7 +5476,7 @@ static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
{
Controller->MonitoringTimer.expires =
jiffies + DAC960_HealthStatusMonitoringInterval;
- add_timer(&Controller->MonitoringTimer);
+ add_timer(&Controller->MonitoringTimer);
return;
}
Controller->V2.StatusChangeCounter = StatusChangeCounter;
@@ -5225,6 +5503,7 @@ static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
}
}
+
/*
DAC960_Open is the Device Open Function for the DAC960 Driver.
*/
@@ -5423,14 +5702,17 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
DAC960_V1_CommandOpcode_T CommandOpcode;
DAC960_V1_CommandStatus_T CommandStatus;
DAC960_V1_DCDB_T DCDB;
+ DAC960_V1_DCDB_T *DCDB_IOBUF = NULL;
+ dma_addr_t DCDB_IOBUFDMA;
ProcessorFlags_T ProcessorFlags;
int ControllerNumber, DataTransferLength;
unsigned char *DataTransferBuffer = NULL;
+ dma_addr_t DataTransferBufferDMA;
if (UserSpaceUserCommand == NULL) return -EINVAL;
if (copy_from_user(&UserCommand, UserSpaceUserCommand,
sizeof(DAC960_V1_UserCommand_T))) {
ErrorCode = -EFAULT;
- goto Failure1;
+ goto Failure1a;
}
ControllerNumber = UserCommand.ControllerNumber;
if (ControllerNumber < 0 ||
@@ -5447,7 +5729,7 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
if (copy_from_user(&DCDB, UserCommand.DCDB,
sizeof(DAC960_V1_DCDB_T))) {
ErrorCode = -EFAULT;
- goto Failure1;
+ goto Failure1a;
}
if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL;
if (!((DataTransferLength == 0 &&
@@ -5463,17 +5745,29 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
!= abs(DataTransferLength))
return -EINVAL;
+ DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice,
+ sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA);
+ if (DCDB_IOBUF == NULL)
+ return -ENOMEM;
}
if (DataTransferLength > 0)
{
- DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
- if (DataTransferBuffer == NULL) return -ENOMEM;
+ DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
+ DataTransferLength, &DataTransferBufferDMA);
+ if (DataTransferBuffer == NULL) {
+ ErrorCode = -ENOMEM;
+ goto Failure1;
+ }
memset(DataTransferBuffer, 0, DataTransferLength);
}
else if (DataTransferLength < 0)
{
- DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
- if (DataTransferBuffer == NULL) return -ENOMEM;
+ DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
+ -DataTransferLength, &DataTransferBufferDMA);
+ if (DataTransferBuffer == NULL) {
+ ErrorCode = -ENOMEM;
+ goto Failure1;
+ }
if (copy_from_user(DataTransferBuffer,
UserCommand.DataTransferBuffer,
-DataTransferLength)) {
@@ -5489,11 +5783,11 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
while (Controller->V1.DirectCommandActive[DCDB.Channel]
[DCDB.TargetID])
{
- spin_unlock_irq(Controller->RequestQueue.queue_lock);
+ spin_unlock_irq(&Controller->queue_lock);
__wait_event(Controller->CommandWaitQueue,
!Controller->V1.DirectCommandActive
[DCDB.Channel][DCDB.TargetID]);
- spin_lock_irq(Controller->RequestQueue.queue_lock);
+ spin_lock_irq(&Controller->queue_lock);
}
Controller->V1.DirectCommandActive[DCDB.Channel]
[DCDB.TargetID] = true;
@@ -5502,9 +5796,9 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
Command->CommandType = DAC960_ImmediateCommand;
memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
sizeof(DAC960_V1_CommandMailbox_T));
- Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(&DCDB);
- DCDB.BusAddress = Virtual_to_Bus32(DataTransferBuffer);
+ Command->V1.CommandMailbox.Type3.BusAddress = DCDB_IOBUFDMA;
+ DCDB.BusAddress = DataTransferBufferDMA;
+ memcpy(DCDB_IOBUF, &DCDB, sizeof(DAC960_V1_DCDB_T));
}
else
{
@@ -5518,7 +5812,7 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
sizeof(DAC960_V1_CommandMailbox_T));
if (DataTransferBuffer != NULL)
Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(DataTransferBuffer);
+ DataTransferBufferDMA;
}
DAC960_ExecuteCommand(Command);
CommandStatus = Command->V1.CommandStatus;
@@ -5528,15 +5822,20 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
if (DataTransferLength > 0)
{
if (copy_to_user(UserCommand.DataTransferBuffer,
- DataTransferBuffer, DataTransferLength))
+ DataTransferBuffer, DataTransferLength)) {
ErrorCode = -EFAULT;
goto Failure1;
+ }
}
if (CommandOpcode == DAC960_V1_DCDB)
{
+ /*
+ I don't believe Target or Channel in the DCDB_IOBUF
+ should be any different from the contents of DCDB.
+ */
Controller->V1.DirectCommandActive[DCDB.Channel]
[DCDB.TargetID] = false;
- if (copy_to_user(UserCommand.DCDB, &DCDB,
+ if (copy_to_user(UserCommand.DCDB, DCDB_IOBUF,
sizeof(DAC960_V1_DCDB_T))) {
ErrorCode = -EFAULT;
goto Failure1;
@@ -5545,7 +5844,12 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
ErrorCode = CommandStatus;
Failure1:
if (DataTransferBuffer != NULL)
- kfree(DataTransferBuffer);
+ pci_free_consistent(Controller->PCIDevice, abs(DataTransferLength),
+ DataTransferBuffer, DataTransferBufferDMA);
+ if (DCDB_IOBUF != NULL)
+ pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T),
+ DCDB_IOBUF, DCDB_IOBUFDMA);
+ Failure1a:
return ErrorCode;
}
case DAC960_IOCTL_V2_EXECUTE_COMMAND:
@@ -5561,12 +5865,14 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
int ControllerNumber, DataTransferLength;
int DataTransferResidue, RequestSenseLength;
unsigned char *DataTransferBuffer = NULL;
+ dma_addr_t DataTransferBufferDMA;
unsigned char *RequestSenseBuffer = NULL;
+ dma_addr_t RequestSenseBufferDMA;
if (UserSpaceUserCommand == NULL) return -EINVAL;
if (copy_from_user(&UserCommand, UserSpaceUserCommand,
sizeof(DAC960_V2_UserCommand_T))) {
ErrorCode = -EFAULT;
- goto Failure2;
+ goto Failure2a;
}
ControllerNumber = UserCommand.ControllerNumber;
if (ControllerNumber < 0 ||
@@ -5578,13 +5884,15 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
DataTransferLength = UserCommand.DataTransferLength;
if (DataTransferLength > 0)
{
- DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
+ DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
+ DataTransferLength, &DataTransferBufferDMA);
if (DataTransferBuffer == NULL) return -ENOMEM;
memset(DataTransferBuffer, 0, DataTransferLength);
}
else if (DataTransferLength < 0)
{
- DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
+ DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
+ -DataTransferLength, &DataTransferBufferDMA);
if (DataTransferBuffer == NULL) return -ENOMEM;
if (copy_from_user(DataTransferBuffer,
UserCommand.DataTransferBuffer,
@@ -5596,7 +5904,8 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
RequestSenseLength = UserCommand.RequestSenseLength;
if (RequestSenseLength > 0)
{
- RequestSenseBuffer = kmalloc(RequestSenseLength, GFP_KERNEL);
+ RequestSenseBuffer = pci_alloc_consistent(Controller->PCIDevice,
+ RequestSenseLength, &RequestSenseBufferDMA);
if (RequestSenseBuffer == NULL)
{
ErrorCode = -ENOMEM;
@@ -5637,8 +5946,7 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
}
CommandMailbox->Common.DataTransferMemoryAddress
.ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(DataTransferBuffer);
+ .SegmentDataPointer = DataTransferBufferDMA;
CommandMailbox->Common.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentByteCount =
@@ -5650,7 +5958,7 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
.NoAutoRequestSense = false;
CommandMailbox->Common.RequestSenseSize = RequestSenseLength;
CommandMailbox->Common.RequestSenseBusAddress =
- Virtual_to_Bus64(RequestSenseBuffer);
+ RequestSenseBufferDMA;
}
DAC960_ExecuteCommand(Command);
CommandStatus = Command->V2.CommandStatus;
@@ -5690,10 +5998,12 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
}
ErrorCode = CommandStatus;
Failure2:
- if (DataTransferBuffer != NULL)
- kfree(DataTransferBuffer);
+ pci_free_consistent(Controller->PCIDevice, abs(DataTransferLength),
+ DataTransferBuffer, DataTransferBufferDMA);
if (RequestSenseBuffer != NULL)
- kfree(RequestSenseBuffer);
+ pci_free_consistent(Controller->PCIDevice, RequestSenseLength,
+ RequestSenseBuffer, RequestSenseBufferDMA);
+ Failure2a:
return ErrorCode;
}
case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
@@ -5740,226 +6050,6 @@ static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
/*
- DAC960_KernelIOCTL is the Kernel IOCTL Function for the DAC960 Driver.
-*/
-
-int DAC960_KernelIOCTL(unsigned int Request, void *Argument)
-{
- switch (Request)
- {
- case DAC960_IOCTL_GET_CONTROLLER_COUNT:
- return DAC960_ControllerCount;
- case DAC960_IOCTL_GET_CONTROLLER_INFO:
- {
- DAC960_ControllerInfo_T *ControllerInfo =
- (DAC960_ControllerInfo_T *) Argument;
- DAC960_Controller_T *Controller;
- int ControllerNumber;
- if (ControllerInfo == NULL) return -EINVAL;
- ControllerNumber = ControllerInfo->ControllerNumber;
- if (ControllerNumber < 0 ||
- ControllerNumber > DAC960_ControllerCount - 1)
- return -ENXIO;
- Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) return -ENXIO;
- memset(ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
- ControllerInfo->ControllerNumber = ControllerNumber;
- ControllerInfo->FirmwareType = Controller->FirmwareType;
- ControllerInfo->Channels = Controller->Channels;
- ControllerInfo->Targets = Controller->Targets;
- ControllerInfo->PCI_Bus = Controller->Bus;
- ControllerInfo->PCI_Device = Controller->Device;
- ControllerInfo->PCI_Function = Controller->Function;
- ControllerInfo->IRQ_Channel = Controller->IRQ_Channel;
- ControllerInfo->PCI_Address = Controller->PCI_Address;
- strcpy(ControllerInfo->ModelName, Controller->ModelName);
- strcpy(ControllerInfo->FirmwareVersion, Controller->FirmwareVersion);
- return 0;
- }
- case DAC960_IOCTL_V1_EXECUTE_COMMAND:
- {
- DAC960_V1_KernelCommand_T *KernelCommand =
- (DAC960_V1_KernelCommand_T *) Argument;
- DAC960_Controller_T *Controller;
- DAC960_Command_T *Command = NULL;
- DAC960_V1_CommandOpcode_T CommandOpcode;
- DAC960_V1_DCDB_T *DCDB = NULL;
- ProcessorFlags_T ProcessorFlags;
- int ControllerNumber, DataTransferLength;
- unsigned char *DataTransferBuffer = NULL;
- if (KernelCommand == NULL) return -EINVAL;
- ControllerNumber = KernelCommand->ControllerNumber;
- if (ControllerNumber < 0 ||
- ControllerNumber > DAC960_ControllerCount - 1)
- return -ENXIO;
- Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) return -ENXIO;
- if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
- CommandOpcode = KernelCommand->CommandMailbox.Common.CommandOpcode;
- DataTransferLength = KernelCommand->DataTransferLength;
- DataTransferBuffer = KernelCommand->DataTransferBuffer;
- if (CommandOpcode & 0x80) return -EINVAL;
- if (CommandOpcode == DAC960_V1_DCDB)
- {
- DCDB = KernelCommand->DCDB;
- if (DCDB->Channel >= DAC960_V1_MaxChannels) return -EINVAL;
- if (!((DataTransferLength == 0 &&
- DCDB->Direction == DAC960_V1_DCDB_NoDataTransfer) ||
- (DataTransferLength > 0 &&
- DCDB->Direction
- == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
- (DataTransferLength < 0 &&
- DCDB->Direction
- == DAC960_V1_DCDB_DataTransferSystemToDevice)))
- return -EINVAL;
- if (((DCDB->TransferLengthHigh4 << 16) | DCDB->TransferLength)
- != abs(DataTransferLength))
- return -EINVAL;
- }
- if (DataTransferLength != 0 && DataTransferBuffer == NULL)
- return -EINVAL;
- if (DataTransferLength > 0)
- memset(DataTransferBuffer, 0, DataTransferLength);
- if (CommandOpcode == DAC960_V1_DCDB)
- {
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- if (!Controller->V1.DirectCommandActive[DCDB->Channel]
- [DCDB->TargetID])
- Command = DAC960_AllocateCommand(Controller);
- if (Command == NULL)
- {
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- return -EBUSY;
- }
- else Controller->V1.DirectCommandActive[DCDB->Channel]
- [DCDB->TargetID] = true;
- DAC960_V1_ClearCommand(Command);
- Command->CommandType = DAC960_QueuedCommand;
- memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
- sizeof(DAC960_V1_CommandMailbox_T));
- Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(DCDB);
- Command->V1.KernelCommand = KernelCommand;
- DCDB->BusAddress = Virtual_to_Bus32(DataTransferBuffer);
- DAC960_QueueCommand(Command);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- }
- else
- {
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- Command = DAC960_AllocateCommand(Controller);
- if (Command == NULL)
- {
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- return -EBUSY;
- }
- DAC960_V1_ClearCommand(Command);
- Command->CommandType = DAC960_QueuedCommand;
- memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
- sizeof(DAC960_V1_CommandMailbox_T));
- if (DataTransferBuffer != NULL)
- Command->V1.CommandMailbox.Type3.BusAddress =
- Virtual_to_Bus32(DataTransferBuffer);
- Command->V1.KernelCommand = KernelCommand;
- DAC960_QueueCommand(Command);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- }
- return 0;
- }
- case DAC960_IOCTL_V2_EXECUTE_COMMAND:
- {
- DAC960_V2_KernelCommand_T *KernelCommand =
- (DAC960_V2_KernelCommand_T *) Argument;
- DAC960_Controller_T *Controller;
- DAC960_Command_T *Command = NULL;
- DAC960_V2_CommandMailbox_T *CommandMailbox;
- ProcessorFlags_T ProcessorFlags;
- int ControllerNumber, DataTransferLength, RequestSenseLength;
- unsigned char *DataTransferBuffer = NULL;
- unsigned char *RequestSenseBuffer = NULL;
- if (KernelCommand == NULL) return -EINVAL;
- ControllerNumber = KernelCommand->ControllerNumber;
- if (ControllerNumber < 0 ||
- ControllerNumber > DAC960_ControllerCount - 1)
- return -ENXIO;
- Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) return -ENXIO;
- if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
- DataTransferLength = KernelCommand->DataTransferLength;
- RequestSenseLength = KernelCommand->RequestSenseLength;
- DataTransferBuffer = KernelCommand->DataTransferBuffer;
- RequestSenseBuffer = KernelCommand->RequestSenseBuffer;
- if (DataTransferLength != 0 && DataTransferBuffer == NULL)
- return -EINVAL;
- if (RequestSenseLength < 0)
- return -EINVAL;
- if (RequestSenseLength > 0 && RequestSenseBuffer == NULL)
- return -EINVAL;
- if (DataTransferLength > 0)
- memset(DataTransferBuffer, 0, DataTransferLength);
- if (RequestSenseLength > 0)
- memset(RequestSenseBuffer, 0, RequestSenseLength);
- DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
- Command = DAC960_AllocateCommand(Controller);
- if (Command == NULL)
- {
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- return -EBUSY;
- }
- DAC960_V2_ClearCommand(Command);
- Command->CommandType = DAC960_QueuedCommand;
- CommandMailbox = &Command->V2.CommandMailbox;
- memcpy(CommandMailbox, &KernelCommand->CommandMailbox,
- sizeof(DAC960_V2_CommandMailbox_T));
- CommandMailbox->Common.CommandControlBits
- .AdditionalScatterGatherListMemory = false;
- CommandMailbox->Common.CommandControlBits
- .NoAutoRequestSense = true;
- CommandMailbox->Common.DataTransferSize = 0;
- CommandMailbox->Common.DataTransferPageNumber = 0;
- memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
- sizeof(DAC960_V2_DataTransferMemoryAddress_T));
- if (DataTransferLength != 0)
- {
- if (DataTransferLength > 0)
- {
- CommandMailbox->Common.CommandControlBits
- .DataTransferControllerToHost = true;
- CommandMailbox->Common.DataTransferSize = DataTransferLength;
- }
- else
- {
- CommandMailbox->Common.CommandControlBits
- .DataTransferControllerToHost = false;
- CommandMailbox->Common.DataTransferSize = -DataTransferLength;
- }
- CommandMailbox->Common.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentDataPointer =
- Virtual_to_Bus64(DataTransferBuffer);
- CommandMailbox->Common.DataTransferMemoryAddress
- .ScatterGatherSegments[0]
- .SegmentByteCount =
- CommandMailbox->Common.DataTransferSize;
- }
- if (RequestSenseLength > 0)
- {
- CommandMailbox->Common.CommandControlBits
- .NoAutoRequestSense = false;
- CommandMailbox->Common.RequestSenseBusAddress =
- Virtual_to_Bus64(RequestSenseBuffer);
- }
- Command->V2.KernelCommand = KernelCommand;
- DAC960_QueueCommand(Command);
- DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
- return 0;
- }
- }
- return -EINVAL;
-}
-
-
-/*
DAC960_CheckStatusBuffer verifies that there is room to hold ByteCount
additional bytes in the Combined Status Buffer and grows the buffer if
necessary. It returns true if there is enough room and false otherwise.
@@ -6381,11 +6471,25 @@ static boolean DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
else if (strcmp(UserCommand, "cancel-rebuild") == 0 ||
strcmp(UserCommand, "cancel-consistency-check") == 0)
{
- unsigned char OldRebuildRateConstant;
+ /*
+ the OldRebuildRateConstant is never actually used
+ once its value is retrieved from the controller.
+ */
+ unsigned char *OldRebuildRateConstant;
+ dma_addr_t OldRebuildRateConstantDMA;
+
+ OldRebuildRateConstant = pci_alloc_consistent( Controller->PCIDevice,
+ sizeof(char), &OldRebuildRateConstantDMA);
+ if (OldRebuildRateConstant == NULL) {
+ DAC960_UserCritical("Cancellation of Rebuild or "
+ "Consistency Check Failed - "
+ "Out of Memory",
+ Controller);
+ goto failure;
+ }
CommandMailbox->Type3R.CommandOpcode = DAC960_V1_RebuildControl;
CommandMailbox->Type3R.RebuildRateConstant = 0xFF;
- CommandMailbox->Type3R.BusAddress =
- Virtual_to_Bus32(&OldRebuildRateConstant);
+ CommandMailbox->Type3R.BusAddress = OldRebuildRateConstantDMA;
DAC960_ExecuteCommand(Command);
switch (Command->V1.CommandStatus)
{
@@ -6400,6 +6504,9 @@ static boolean DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
Controller, Command->V1.CommandStatus);
break;
}
+failure:
+ pci_free_consistent(Controller->PCIDevice, sizeof(char),
+ OldRebuildRateConstant, OldRebuildRateConstantDMA);
}
else DAC960_UserCritical("Illegal User Command: '%s'\n",
Controller, UserCommand);
@@ -6423,10 +6530,12 @@ static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
*LogicalDeviceNumber)
{
DAC960_V2_CommandMailbox_T SavedCommandMailbox, *CommandMailbox;
- DAC960_V2_PhysicalToLogicalDevice_T PhysicalToLogicalDevice;
+ DAC960_Controller_T *Controller = Command->Controller;
+
CommandMailbox = &Command->V2.CommandMailbox;
memcpy(&SavedCommandMailbox, CommandMailbox,
sizeof(DAC960_V2_CommandMailbox_T));
+
CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
CommandMailbox->PhysicalDeviceInfo.CommandControlBits
.DataTransferControllerToHost = true;
@@ -6441,15 +6550,17 @@ static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
CommandMailbox->Common.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentDataPointer =
- Virtual_to_Bus64(&PhysicalToLogicalDevice);
+ Controller->V2.PhysicalToLogicalDeviceDMA;
CommandMailbox->Common.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentByteCount =
- CommandMailbox->Common.DataTransferSize;
+ CommandMailbox->Common.DataTransferSize;
+
DAC960_ExecuteCommand(Command);
+ *LogicalDeviceNumber = Controller->V2.PhysicalToLogicalDevice->LogicalDeviceNumber;
+
memcpy(CommandMailbox, &SavedCommandMailbox,
sizeof(DAC960_V2_CommandMailbox_T));
- *LogicalDeviceNumber = PhysicalToLogicalDevice.LogicalDeviceNumber;
return (Command->V2.CommandStatus == DAC960_V2_NormalCompletion);
}
@@ -6635,16 +6746,20 @@ static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
CommandMailbox->ControllerInfo.ControllerNumber = 0;
CommandMailbox->ControllerInfo.IOCTL_Opcode =
DAC960_V2_GetControllerInfo;
+ /*
+ * How does this NOT race with the queued Monitoring
+ * usage of this structure?
+ */
CommandMailbox->ControllerInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentDataPointer =
- Virtual_to_Bus64(&Controller->V2.NewControllerInformation);
+ Controller->V2.NewControllerInformationDMA;
CommandMailbox->ControllerInfo.DataTransferMemoryAddress
.ScatterGatherSegments[0]
.SegmentByteCount =
CommandMailbox->ControllerInfo.DataTransferSize;
DAC960_ExecuteCommand(Command);
- while (Controller->V2.NewControllerInformation.PhysicalScanActive)
+ while (Controller->V2.NewControllerInformation->PhysicalScanActive)
{
DAC960_ExecuteCommand(Command);
sleep_on_timeout(&Controller->CommandWaitQueue, HZ);
@@ -6817,22 +6932,19 @@ static int DAC960_ProcWriteUserCommand(File_T *File, const char *Buffer,
DAC960 Driver.
*/
-static void DAC960_CreateProcEntries(void)
+static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller)
{
- PROC_DirectoryEntry_T *StatusProcEntry;
- int ControllerNumber;
- DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL);
- StatusProcEntry = create_proc_read_entry("status", 0,
+ PROC_DirectoryEntry_T *StatusProcEntry;
+ PROC_DirectoryEntry_T *ControllerProcEntry;
+ PROC_DirectoryEntry_T *UserCommandProcEntry;
+
+ if (DAC960_ProcDirectoryEntry == NULL) {
+ DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL);
+ StatusProcEntry = create_proc_read_entry("status", 0,
DAC960_ProcDirectoryEntry,
DAC960_ProcReadStatus, NULL);
- for (ControllerNumber = 0;
- ControllerNumber < DAC960_ControllerCount;
- ControllerNumber++)
- {
- DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
- PROC_DirectoryEntry_T *ControllerProcEntry;
- PROC_DirectoryEntry_T *UserCommandProcEntry;
- if (Controller == NULL) continue;
+ }
+
sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
ControllerProcEntry = proc_mkdir(Controller->ControllerName,
DAC960_ProcDirectoryEntry);
@@ -6846,7 +6958,6 @@ static void DAC960_CreateProcEntries(void)
Controller);
UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand;
Controller->ControllerProcEntry = ControllerProcEntry;
- }
}
@@ -6855,26 +6966,138 @@ static void DAC960_CreateProcEntries(void)
DAC960 Driver.
*/
-static void DAC960_DestroyProcEntries(void)
+static void DAC960_DestroyProcEntries(DAC960_Controller_T *Controller)
{
- int ControllerNumber;
- for (ControllerNumber = 0;
- ControllerNumber < DAC960_ControllerCount;
- ControllerNumber++)
- {
- DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
- if (Controller == NULL) continue;
+ if (Controller->ControllerProcEntry == NULL)
+ return;
remove_proc_entry("initial_status", Controller->ControllerProcEntry);
remove_proc_entry("current_status", Controller->ControllerProcEntry);
remove_proc_entry("user_command", Controller->ControllerProcEntry);
remove_proc_entry(Controller->ControllerName, DAC960_ProcDirectoryEntry);
- }
- remove_proc_entry("rd/status", NULL);
- remove_proc_entry("rd", NULL);
+ Controller->ControllerProcEntry = NULL;
+}
+
+static struct DAC960_privdata DAC960_BA_privdata = {
+ .HardwareType = DAC960_BA_Controller,
+ .FirmwareType = DAC960_V2_Controller,
+ .InterruptHandler = DAC960_BA_InterruptHandler,
+ .MemoryWindowSize = DAC960_BA_RegisterWindowSize,
+};
+
+static struct DAC960_privdata DAC960_LP_privdata = {
+ .HardwareType = DAC960_LP_Controller,
+ .FirmwareType = DAC960_LP_Controller,
+ .InterruptHandler = DAC960_LP_InterruptHandler,
+ .MemoryWindowSize = DAC960_LP_RegisterWindowSize,
+};
+
+static struct DAC960_privdata DAC960_LA_privdata = {
+ .HardwareType = DAC960_LA_Controller,
+ .FirmwareType = DAC960_V1_Controller,
+ .InterruptHandler = DAC960_LA_InterruptHandler,
+ .MemoryWindowSize = DAC960_LA_RegisterWindowSize,
+};
+
+static struct DAC960_privdata DAC960_PG_privdata = {
+ .HardwareType = DAC960_PG_Controller,
+ .FirmwareType = DAC960_V1_Controller,
+ .InterruptHandler = DAC960_PG_InterruptHandler,
+ .MemoryWindowSize = DAC960_PG_RegisterWindowSize,
+};
+
+static struct DAC960_privdata DAC960_PD_privdata = {
+ .HardwareType = DAC960_PD_Controller,
+ .FirmwareType = DAC960_V1_Controller,
+ .InterruptHandler = DAC960_PD_InterruptHandler,
+ .MemoryWindowSize = DAC960_PD_RegisterWindowSize,
+};
+
+static struct DAC960_privdata DAC960_P_privdata = {
+ .HardwareType = DAC960_P_Controller,
+ .FirmwareType = DAC960_V1_Controller,
+ .InterruptHandler = DAC960_P_InterruptHandler,
+ .MemoryWindowSize = DAC960_PD_RegisterWindowSize,
+};
+
+static struct pci_device_id DAC960_id_table[] = {
+ {
+ .vendor = PCI_VENDOR_ID_MYLEX,
+ .device = PCI_DEVICE_ID_MYLEX_DAC960_BA,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (unsigned long) &DAC960_BA_privdata,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_MYLEX,
+ .device = PCI_DEVICE_ID_MYLEX_DAC960_LP,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (unsigned long) &DAC960_LP_privdata,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_DEC,
+ .device = PCI_DEVICE_ID_DEC_21285,
+ .subvendor = PCI_VENDOR_ID_MYLEX,
+ .subdevice = PCI_DEVICE_ID_MYLEX_DAC960_LA,
+ .driver_data = (unsigned long) &DAC960_LA_privdata,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_MYLEX,
+ .device = PCI_DEVICE_ID_MYLEX_DAC960_PG,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (unsigned long) &DAC960_PG_privdata,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_MYLEX,
+ .device = PCI_DEVICE_ID_MYLEX_DAC960_PD,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (unsigned long) &DAC960_PD_privdata,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_MYLEX,
+ .device = PCI_DEVICE_ID_MYLEX_DAC960_P,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (unsigned long) &DAC960_P_privdata,
+ },
+ {0, },
+};
+
+MODULE_DEVICE_TABLE(pci, DAC960_id_table);
+
+static struct pci_driver DAC960_pci_driver = {
+ .name = "DAC960",
+ .id_table = DAC960_id_table,
+ .probe = DAC960_Probe,
+ .remove = DAC960_Remove,
+};
+
+static int DAC960_init_module(void)
+{
+ return pci_module_init(&DAC960_pci_driver);
}
+static void DAC960_cleanup_module(void)
+{
+ int i;
+
+ for (i = 0; i < DAC960_ControllerCount; i++) {
+ DAC960_Controller_T *Controller = DAC960_Controllers[i];
+ if (Controller == NULL)
+ continue;
+ DAC960_FinalizeController(Controller);
+ }
+ if (DAC960_ProcDirectoryEntry != NULL) {
+ remove_proc_entry("rd/status", NULL);
+ remove_proc_entry("rd", NULL);
+ }
+ DAC960_ControllerCount = 0;
+ pci_unregister_driver(&DAC960_pci_driver);
+}
-module_init(DAC960_Initialize);
-module_exit(DAC960_Finalize);
+module_init(DAC960_init_module);
+module_exit(DAC960_cleanup_module);
MODULE_LICENSE("GPL");
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h
index e66cd95f87dd..1d3ea76554b9 100644
--- a/drivers/block/DAC960.h
+++ b/drivers/block/DAC960.h
@@ -60,6 +60,17 @@
#define DAC960_V1_MaxPhysicalDevices 45
#define DAC960_V2_MaxPhysicalDevices 272
+/*
+ Define the pci dma mask supported by DAC960 V1 and V2 Firmware Controlers
+
+ For now set the V2 mask to only 32 bits. The controller IS capable
+ of doing 64 bit dma. But I have yet to find out whether this needs to
+ be explicitely enabled in the controller, or of the controller adapts
+ automatically.
+ */
+
+#define DAC690_V1_PciDmaMask 0xffffffff
+#define DAC690_V2_PciDmaMask 0xffffffffffffffff
/*
Define a Boolean data type.
@@ -111,6 +122,20 @@ typedef unsigned long long DAC960_ByteCount64_T;
/*
+ dma_loaf is used by helper routines to divide a region of
+ dma mapped memory into smaller pieces, where those pieces
+ are not of uniform size.
+ */
+
+struct dma_loaf {
+ void *cpu_base;
+ dma_addr_t dma_base;
+ size_t length;
+ void *cpu_free;
+ dma_addr_t dma_free;
+};
+
+/*
Define the SCSI INQUIRY Standard Data structure.
*/
@@ -2059,9 +2084,6 @@ extern int DAC960_KernelIOCTL(unsigned int Request, void *Argument);
#define DAC960_LogicalDriveNumber(Device) \
(minor(Device) >> DAC960_MaxPartitionsBits)
-#define DAC960_PartitionNumber(Device) \
- (minor(Device) & (DAC960_MaxPartitions - 1))
-
#define DAC960_MajorNumber(ControllerNumber) \
(DAC960_MAJOR + (ControllerNumber))
@@ -2191,7 +2213,6 @@ static char
of the Linux Kernel and I/O Subsystem.
*/
-typedef struct bio BufferHeader_T;
typedef struct file File_T;
typedef struct block_device_operations BlockDeviceOperations_T;
typedef struct completion Completion_T;
@@ -2200,7 +2221,6 @@ typedef struct inode Inode_T;
typedef struct inode_operations InodeOperations_T;
typedef kdev_t KernelDevice_T;
typedef struct list_head ListHead_T;
-typedef struct notifier_block NotifierBlock_T;
typedef struct pci_dev PCI_Device_T;
typedef struct proc_dir_entry PROC_DirectoryEntry_T;
typedef unsigned long ProcessorFlags_T;
@@ -2211,6 +2231,13 @@ typedef struct super_block SuperBlock_T;
typedef struct timer_list Timer_T;
typedef wait_queue_head_t WaitQueue_T;
+struct DAC960_privdata {
+ DAC960_HardwareType_T HardwareType;
+ DAC960_FirmwareType_T FirmwareType;
+ void (*InterruptHandler)(int, void *, Registers_T *);
+ unsigned int MemoryWindowSize;
+};
+
/*
Define the DAC960 V1 Firmware Controller Status Mailbox structure.
@@ -2278,16 +2305,16 @@ typedef struct DAC960_Command
unsigned int BlockNumber;
unsigned int BlockCount;
unsigned int SegmentCount;
- BufferHeader_T *BufferHeader;
- void *RequestBuffer;
+ IO_Request_T *Request;
+ struct pci_dev *PciDevice;
union {
struct {
DAC960_V1_CommandMailbox_T CommandMailbox;
DAC960_V1_KernelCommand_T *KernelCommand;
DAC960_V1_CommandStatus_T CommandStatus;
- DAC960_V1_ScatterGatherSegment_T
- ScatterGatherList[DAC960_V1_ScatterGatherLimit]
- __attribute__ ((aligned (sizeof(DAC960_V1_ScatterGatherSegment_T))));
+ DAC960_V1_ScatterGatherSegment_T *ScatterGatherList;
+ dma_addr_t ScatterGatherListDMA;
+ struct scatterlist ScatterList[DAC960_V1_ScatterGatherLimit];
unsigned int EndMarker[0];
} V1;
struct {
@@ -2296,11 +2323,11 @@ typedef struct DAC960_Command
DAC960_V2_CommandStatus_T CommandStatus;
unsigned char RequestSenseLength;
int DataTransferResidue;
- DAC960_V2_ScatterGatherSegment_T
- ScatterGatherList[DAC960_V2_ScatterGatherLimit]
- __attribute__ ((aligned (sizeof(DAC960_V2_ScatterGatherSegment_T))));
- DAC960_SCSI_RequestSense_T RequestSense
- __attribute__ ((aligned (sizeof(int))));
+ DAC960_V2_ScatterGatherSegment_T *ScatterGatherList;
+ dma_addr_t ScatterGatherListDMA;
+ DAC960_SCSI_RequestSense_T *RequestSense;
+ dma_addr_t RequestSenseDMA;
+ struct scatterlist ScatterList[DAC960_V2_ScatterGatherLimit];
unsigned int EndMarker[0];
} V2;
} FW;
@@ -2320,6 +2347,7 @@ typedef struct DAC960_Controller
DAC960_HardwareType_T HardwareType;
DAC960_IO_Address_T IO_Address;
DAC960_PCI_Address_T PCI_Address;
+ PCI_Device_T *PCIDevice;
unsigned char ControllerNumber;
unsigned char ControllerName[4];
unsigned char ModelName[20];
@@ -2345,14 +2373,13 @@ typedef struct DAC960_Controller
unsigned int CurrentStatusLength;
unsigned int ProgressBufferLength;
unsigned int UserStatusLength;
- unsigned long MemoryMailboxPagesAddress;
- unsigned long MemoryMailboxPagesOrder;
+ struct dma_loaf DmaPages;
unsigned long MonitoringTimerCount;
unsigned long PrimaryMonitoringTime;
unsigned long SecondaryMonitoringTime;
+ unsigned long ShutdownMonitoringTimer;
unsigned long LastProgressReportTime;
unsigned long LastCurrentStatusTime;
- boolean ControllerDetectionSuccessful;
boolean ControllerInitialized;
boolean MonitoringCommandDeferred;
boolean EphemeralProgressMessage;
@@ -2361,6 +2388,7 @@ typedef struct DAC960_Controller
boolean SuppressEnclosureMessages;
Timer_T MonitoringTimer;
struct gendisk *disks[DAC960_MaxLogicalDrives];
+ struct pci_pool *ScatterGatherPool;
DAC960_Command_T *FreeCommands;
unsigned char *CombinedStatusBuffer;
unsigned char *CurrentStatusBuffer;
@@ -2404,36 +2432,63 @@ typedef struct DAC960_Controller
boolean RebuildProgressFirst;
boolean RebuildFlagPending;
boolean RebuildStatusPending;
+
+ dma_addr_t FirstCommandMailboxDMA;
DAC960_V1_CommandMailbox_T *FirstCommandMailbox;
DAC960_V1_CommandMailbox_T *LastCommandMailbox;
DAC960_V1_CommandMailbox_T *NextCommandMailbox;
DAC960_V1_CommandMailbox_T *PreviousCommandMailbox1;
DAC960_V1_CommandMailbox_T *PreviousCommandMailbox2;
+
+ dma_addr_t FirstStatusMailboxDMA;
DAC960_V1_StatusMailbox_T *FirstStatusMailbox;
DAC960_V1_StatusMailbox_T *LastStatusMailbox;
DAC960_V1_StatusMailbox_T *NextStatusMailbox;
- DAC960_V1_DCDB_T MonitoringDCDB;
+
+ DAC960_V1_DCDB_T *MonitoringDCDB;
+ dma_addr_t MonitoringDCDB_DMA;
+
DAC960_V1_Enquiry_T Enquiry;
- DAC960_V1_Enquiry_T NewEnquiry;
+ DAC960_V1_Enquiry_T *NewEnquiry;
+ dma_addr_t NewEnquiryDMA;
+
DAC960_V1_ErrorTable_T ErrorTable;
- DAC960_V1_ErrorTable_T NewErrorTable;
- DAC960_V1_EventLogEntry_T EventLogEntry;
- DAC960_V1_RebuildProgress_T RebuildProgress;
+ DAC960_V1_ErrorTable_T *NewErrorTable;
+ dma_addr_t NewErrorTableDMA;
+
+ DAC960_V1_EventLogEntry_T *EventLogEntry;
+ dma_addr_t EventLogEntryDMA;
+
+ DAC960_V1_RebuildProgress_T *RebuildProgress;
+ dma_addr_t RebuildProgressDMA;
DAC960_V1_CommandStatus_T LastRebuildStatus;
DAC960_V1_CommandStatus_T PendingRebuildStatus;
+
DAC960_V1_LogicalDriveInformationArray_T LogicalDriveInformation;
- DAC960_V1_LogicalDriveInformationArray_T NewLogicalDriveInformation;
+ DAC960_V1_LogicalDriveInformationArray_T *NewLogicalDriveInformation;
+ dma_addr_t NewLogicalDriveInformationDMA;
+
DAC960_V1_BackgroundInitializationStatus_T
- BackgroundInitializationStatus;
+ *BackgroundInitializationStatus;
+ dma_addr_t BackgroundInitializationStatusDMA;
DAC960_V1_BackgroundInitializationStatus_T
- LastBackgroundInitializationStatus;
+ LastBackgroundInitializationStatus;
+
DAC960_V1_DeviceState_T
DeviceState[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
- DAC960_V1_DeviceState_T NewDeviceState;
+ DAC960_V1_DeviceState_T *NewDeviceState;
+ dma_addr_t NewDeviceStateDMA;
+
DAC960_SCSI_Inquiry_T
InquiryStandardData[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
+ DAC960_SCSI_Inquiry_T *NewInquiryStandardData;
+ dma_addr_t NewInquiryStandardDataDMA;
+
DAC960_SCSI_Inquiry_UnitSerialNumber_T
InquiryUnitSerialNumber[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
+ DAC960_SCSI_Inquiry_UnitSerialNumber_T *NewInquiryUnitSerialNumber;
+ dma_addr_t NewInquiryUnitSerialNumberDMA;
+
int DeviceResetCount[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
boolean DirectCommandActive[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
} V1;
@@ -2446,28 +2501,50 @@ typedef struct DAC960_Controller
boolean NeedDeviceSerialNumberInformation;
boolean StartLogicalDeviceInformationScan;
boolean StartPhysicalDeviceInformationScan;
+ struct pci_pool *RequestSensePool;
+
+ dma_addr_t FirstCommandMailboxDMA;
DAC960_V2_CommandMailbox_T *FirstCommandMailbox;
DAC960_V2_CommandMailbox_T *LastCommandMailbox;
DAC960_V2_CommandMailbox_T *NextCommandMailbox;
DAC960_V2_CommandMailbox_T *PreviousCommandMailbox1;
DAC960_V2_CommandMailbox_T *PreviousCommandMailbox2;
+
+ dma_addr_t FirstStatusMailboxDMA;
DAC960_V2_StatusMailbox_T *FirstStatusMailbox;
DAC960_V2_StatusMailbox_T *LastStatusMailbox;
DAC960_V2_StatusMailbox_T *NextStatusMailbox;
+
+ dma_addr_t HealthStatusBufferDMA;
DAC960_V2_HealthStatusBuffer_T *HealthStatusBuffer;
+
DAC960_V2_ControllerInfo_T ControllerInformation;
- DAC960_V2_ControllerInfo_T NewControllerInformation;
+ DAC960_V2_ControllerInfo_T *NewControllerInformation;
+ dma_addr_t NewControllerInformationDMA;
+
DAC960_V2_LogicalDeviceInfo_T
*LogicalDeviceInformation[DAC960_MaxLogicalDrives];
- DAC960_V2_LogicalDeviceInfo_T NewLogicalDeviceInformation;
+ DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInformation;
+ dma_addr_t NewLogicalDeviceInformationDMA;
+
DAC960_V2_PhysicalDeviceInfo_T
*PhysicalDeviceInformation[DAC960_V2_MaxPhysicalDevices];
- DAC960_V2_PhysicalDeviceInfo_T NewPhysicalDeviceInformation;
+ DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInformation;
+ dma_addr_t NewPhysicalDeviceInformationDMA;
+
+ DAC960_SCSI_Inquiry_UnitSerialNumber_T *NewInquiryUnitSerialNumber;
+ dma_addr_t NewInquiryUnitSerialNumberDMA;
DAC960_SCSI_Inquiry_UnitSerialNumber_T
*InquiryUnitSerialNumber[DAC960_V2_MaxPhysicalDevices];
+
+ DAC960_V2_Event_T *Event;
+ dma_addr_t EventDMA;
+
+ DAC960_V2_PhysicalToLogicalDevice_T *PhysicalToLogicalDevice;
+ dma_addr_t PhysicalToLogicalDeviceDMA;
+
DAC960_V2_PhysicalDevice_T
LogicalDriveToVirtualDevice[DAC960_MaxLogicalDrives];
- DAC960_V2_Event_T Event;
boolean LogicalDriveFoundDuringScan[DAC960_MaxLogicalDrives];
} V2;
} FW;
@@ -2495,16 +2572,47 @@ DAC960_Controller_T;
#define DAC960_QueueReadWriteCommand(Command) \
(Controller->QueueReadWriteCommand)(Command)
+/*
+ * dma_addr_writeql is provided to write dma_addr_t types
+ * to a 64-bit pci address space register. The controller
+ * will accept having the register written as two 32-bit
+ * values.
+ *
+ * In HIGHMEM kernels, dma_addr_t is a 64-bit value.
+ * without HIGHMEM, dma_addr_t is a 32-bit value.
+ *
+ * The compiler should always fix up the assignment
+ * to u.wq appropriately, depending upon the size of
+ * dma_addr_t.
+ */
+static inline
+void dma_addr_writeql(dma_addr_t addr, void *write_address)
+{
+ union {
+ u64 wq;
+ uint wl[2];
+ } u;
+
+ u.wq = addr;
+
+ writel(u.wl[0], write_address);
+ writel(u.wl[1], write_address + 4);
+}
/*
DAC960_AcquireControllerLock acquires exclusive access to Controller.
+ Reference the queue_lock through the controller structure,
+ rather than through the request queue. These macros are
+ used to mutex on the controller structure during initialization,
+ BEFORE the request queue is allocated and initialized in
+ DAC960_RegisterBlockDevice().
*/
static inline
void DAC960_AcquireControllerLock(DAC960_Controller_T *Controller,
ProcessorFlags_T *ProcessorFlags)
{
- spin_lock_irqsave(Controller->RequestQueue.queue_lock, *ProcessorFlags);
+ spin_lock_irqsave(&Controller->queue_lock, *ProcessorFlags);
}
@@ -2516,7 +2624,7 @@ static inline
void DAC960_ReleaseControllerLock(DAC960_Controller_T *Controller,
ProcessorFlags_T *ProcessorFlags)
{
- spin_unlock_irqrestore(Controller->RequestQueue.queue_lock, *ProcessorFlags);
+ spin_unlock_irqrestore(&Controller->queue_lock, *ProcessorFlags);
}
@@ -2553,7 +2661,7 @@ static inline
void DAC960_AcquireControllerLockIH(DAC960_Controller_T *Controller,
ProcessorFlags_T *ProcessorFlags)
{
- spin_lock_irqsave(Controller->RequestQueue.queue_lock, *ProcessorFlags);
+ spin_lock_irqsave(&Controller->queue_lock, *ProcessorFlags);
}
@@ -2566,10 +2674,9 @@ static inline
void DAC960_ReleaseControllerLockIH(DAC960_Controller_T *Controller,
ProcessorFlags_T *ProcessorFlags)
{
- spin_unlock_irqrestore(Controller->RequestQueue.queue_lock, *ProcessorFlags);
+ spin_unlock_irqrestore(&Controller->queue_lock, *ProcessorFlags);
}
-#error I am a non-portable driver, please convert me to use the Documentation/DMA-mapping.txt interfaces
/*
Define the DAC960 BA Series Controller Interface Register Offsets.
@@ -2834,17 +2941,14 @@ void DAC960_BA_WriteCommandMailbox(DAC960_V2_CommandMailbox_T
mb();
}
+
static inline
void DAC960_BA_WriteHardwareMailbox(void *ControllerBaseAddress,
- DAC960_V2_CommandMailbox_T *CommandMailbox)
+ dma_addr_t CommandMailboxDMA)
{
-#ifdef __ia64__
- writeq(Virtual_to_Bus64(CommandMailbox),
- ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset);
-#else
- writel(Virtual_to_Bus32(CommandMailbox),
- ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset);
-#endif
+ dma_addr_writeql(CommandMailboxDMA,
+ ControllerBaseAddress +
+ DAC960_BA_CommandMailboxBusAddressOffset);
}
static inline DAC960_V2_CommandIdentifier_T
@@ -3142,15 +3246,11 @@ void DAC960_LP_WriteCommandMailbox(DAC960_V2_CommandMailbox_T
static inline
void DAC960_LP_WriteHardwareMailbox(void *ControllerBaseAddress,
- DAC960_V2_CommandMailbox_T *CommandMailbox)
+ dma_addr_t CommandMailboxDMA)
{
-#ifdef __ia64__
- writeq(Virtual_to_Bus64(CommandMailbox),
- ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset);
-#else
- writel(Virtual_to_Bus32(CommandMailbox),
- ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset);
-#endif
+ dma_addr_writeql(CommandMailboxDMA,
+ ControllerBaseAddress +
+ DAC960_LP_CommandMailboxBusAddressOffset);
}
static inline DAC960_V2_CommandIdentifier_T
@@ -3506,43 +3606,6 @@ DAC960_LA_ReadErrorStatus(void *ControllerBaseAddress,
return true;
}
-static inline
-void DAC960_LA_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
-{
-#ifdef __i386__
- void *ControllerBaseAddress = Controller->BaseAddress;
- writel(0x743C485E,
- ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset);
- writel((unsigned long) Controller->V1.FirstCommandMailbox,
- ControllerBaseAddress + DAC960_LA_MailboxRegister4Offset);
- writew(Controller->V1.NextCommandMailbox - Controller->V1.FirstCommandMailbox,
- ControllerBaseAddress + DAC960_LA_MailboxRegister8Offset);
- writew(Controller->V1.NextStatusMailbox - Controller->V1.FirstStatusMailbox,
- ControllerBaseAddress + DAC960_LA_MailboxRegister10Offset);
-#endif
-}
-
-static inline
-void DAC960_LA_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
- void **MemoryMailboxAddress,
- short *NextCommandMailboxIndex,
- short *NextStatusMailboxIndex)
-{
-#ifdef __i386__
- void *ControllerBaseAddress = Controller->BaseAddress;
- if (readl(ControllerBaseAddress
- + DAC960_LA_CommandOpcodeRegisterOffset) != 0x743C485E)
- return;
- *MemoryMailboxAddress =
- (void *) readl(ControllerBaseAddress + DAC960_LA_MailboxRegister4Offset);
- *NextCommandMailboxIndex =
- readw(ControllerBaseAddress + DAC960_LA_MailboxRegister8Offset);
- *NextStatusMailboxIndex =
- readw(ControllerBaseAddress + DAC960_LA_MailboxRegister10Offset);
-#endif
-}
-
-
/*
Define the DAC960 PG Series Controller Interface Register Offsets.
*/
@@ -3868,43 +3931,6 @@ DAC960_PG_ReadErrorStatus(void *ControllerBaseAddress,
return true;
}
-static inline
-void DAC960_PG_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
-{
-#ifdef __i386__
- void *ControllerBaseAddress = Controller->BaseAddress;
- writel(0x743C485E,
- ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset);
- writel((unsigned long) Controller->V1.FirstCommandMailbox,
- ControllerBaseAddress + DAC960_PG_MailboxRegister4Offset);
- writew(Controller->V1.NextCommandMailbox - Controller->V1.FirstCommandMailbox,
- ControllerBaseAddress + DAC960_PG_MailboxRegister8Offset);
- writew(Controller->V1.NextStatusMailbox - Controller->V1.FirstStatusMailbox,
- ControllerBaseAddress + DAC960_PG_MailboxRegister10Offset);
-#endif
-}
-
-static inline
-void DAC960_PG_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
- void **MemoryMailboxAddress,
- short *NextCommandMailboxIndex,
- short *NextStatusMailboxIndex)
-{
-#ifdef __i386__
- void *ControllerBaseAddress = Controller->BaseAddress;
- if (readl(ControllerBaseAddress
- + DAC960_PG_CommandOpcodeRegisterOffset) != 0x743C485E)
- return;
- *MemoryMailboxAddress =
- (void *) readl(ControllerBaseAddress + DAC960_PG_MailboxRegister4Offset);
- *NextCommandMailboxIndex =
- readw(ControllerBaseAddress + DAC960_PG_MailboxRegister8Offset);
- *NextStatusMailboxIndex =
- readw(ControllerBaseAddress + DAC960_PG_MailboxRegister10Offset);
-#endif
-}
-
-
/*
Define the DAC960 PD Series Controller Interface Register Offsets.
*/
@@ -4206,9 +4232,8 @@ void DAC960_P_To_PD_TranslateReadWriteCommand(DAC960_V1_CommandMailbox_T
*/
static void DAC960_FinalizeController(DAC960_Controller_T *);
-static int DAC960_Notifier(NotifierBlock_T *, unsigned long, void *);
static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *);
-static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *);
+static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *);
static void DAC960_RequestFunction(RequestQueue_T *);
static void DAC960_BA_InterruptHandler(int, void *, Registers_T *);
static void DAC960_LP_InterruptHandler(int, void *, Registers_T *);
@@ -4225,7 +4250,7 @@ static int DAC960_IOCTL(Inode_T *, File_T *, unsigned int, unsigned long);
static int DAC960_UserIOCTL(Inode_T *, File_T *, unsigned int, unsigned long);
static void DAC960_Message(DAC960_MessageLevel_T, unsigned char *,
DAC960_Controller_T *, ...);
-static void DAC960_CreateProcEntries(void);
-static void DAC960_DestroyProcEntries(void);
+static void DAC960_CreateProcEntries(DAC960_Controller_T *);
+static void DAC960_DestroyProcEntries(DAC960_Controller_T *);
#endif /* DAC960_DriverVersion */
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index a4892d874b20..1f42081de2bd 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -26,6 +26,8 @@
* reduce number of partial TCP segments sent. <steve@chygwyn.com>
* 01-12-6 Fix deadlock condition by making queue locks independant of
* the transmit lock. <steve@chygwyn.com>
+ * 02-10-11 Allow hung xmit to be aborted via SIGKILL & various fixes.
+ * <Paul.Clements@SteelEye.com> <James.Bottomley@SteelEye.com>
*
* possible FIXME: make set_sock / set_blksize / set_size / do_it one syscall
* why not: would need verify_area and friends, would share yet another
@@ -89,10 +91,12 @@ static int nbd_xmit(int send, struct socket *sock, char *buf, int size, int msg_
oldfs = get_fs();
set_fs(get_ds());
-
+ /* Allow interception of SIGKILL only
+ * Don't allow other signals to interrupt the transmission */
spin_lock_irqsave(&current->sig->siglock, flags);
oldset = current->blocked;
sigfillset(&current->blocked);
+ sigdelsetmask(&current->blocked, sigmask(SIGKILL));
recalc_sigpending();
spin_unlock_irqrestore(&current->sig->siglock, flags);
@@ -115,6 +119,17 @@ static int nbd_xmit(int send, struct socket *sock, char *buf, int size, int msg_
else
result = sock_recvmsg(sock, &msg, size, 0);
+ if (signal_pending(current)) {
+ siginfo_t info;
+ spin_lock_irqsave(&current->sig->siglock, flags);
+ printk(KERN_WARNING "NBD (pid %d: %s) got signal %d\n",
+ current->pid, current->comm,
+ dequeue_signal(&current->blocked, &info));
+ spin_unlock_irqrestore(&current->sig->siglock, flags);
+ result = -EINTR;
+ break;
+ }
+
if (result <= 0) {
#ifdef PARANOIA
printk(KERN_ERR "NBD: %s - sock=%ld at buf=%ld, size=%d returned %d.\n",
@@ -154,6 +169,10 @@ void nbd_send_req(struct nbd_device *lo, struct request *req)
down(&lo->tx_lock);
+ if (!sock || !lo->sock) {
+ FAIL("Attempted sendmsg to closed socket\n");
+ }
+
result = nbd_xmit(1, sock, (char *) &request, sizeof(request), nbd_cmd(req) == NBD_CMD_WRITE ? MSG_MORE : 0);
if (result <= 0)
FAIL("Sendmsg failed for control.");
@@ -324,11 +343,31 @@ static void do_nbd_request(request_queue_t * q)
spin_unlock_irq(q->queue_lock);
spin_lock(&lo->queue_lock);
+
+ if (!lo->file) {
+ spin_unlock(&lo->queue_lock);
+ printk(KERN_ERR "nbd: failed between accept and semaphore, file lost\n");
+ req->errors++;
+ nbd_end_request(req);
+ spin_lock_irq(q->queue_lock);
+ continue;
+ }
+
list_add(&req->queuelist, &lo->queue_head);
spin_unlock(&lo->queue_lock);
nbd_send_req(lo, req);
+ if (req->errors) {
+ printk(KERN_ERR "nbd: nbd_send_req failed\n");
+ spin_lock(&lo->queue_lock);
+ list_del(&req->queuelist);
+ spin_unlock(&lo->queue_lock);
+ nbd_end_request(req);
+ spin_lock_irq(q->queue_lock);
+ continue;
+ }
+
spin_lock_irq(q->queue_lock);
continue;
@@ -371,12 +410,14 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
printk(KERN_ERR "nbd: Some requests are in progress -> can not turn off.\n");
return -EBUSY;
}
- spin_unlock(&lo->queue_lock);
file = lo->file;
- if (!file)
+ if (!file) {
+ spin_unlock(&lo->queue_lock);
return -EINVAL;
+ }
lo->file = NULL;
lo->sock = NULL;
+ spin_unlock(&lo->queue_lock);
fput(file);
return 0;
case NBD_SET_SOCK:
@@ -420,6 +461,26 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
if (!lo->file)
return -EINVAL;
nbd_do_it(lo);
+ /* on return tidy up in case we have a signal */
+ /* Forcibly shutdown the socket causing all listeners
+ * to error
+ *
+ * FIXME: This code is duplicated from sys_shutdown, but
+ * there should be a more generic interface rather than
+ * calling socket ops directly here */
+ down(&lo->tx_lock);
+ printk(KERN_WARNING "nbd: shutting down socket\n");
+ lo->sock->ops->shutdown(lo->sock, SEND_SHUTDOWN|RCV_SHUTDOWN);
+ lo->sock = NULL;
+ up(&lo->tx_lock);
+ spin_lock(&lo->queue_lock);
+ file = lo->file;
+ lo->file = NULL;
+ spin_unlock(&lo->queue_lock);
+ nbd_clear_que(lo);
+ printk(KERN_WARNING "nbd: queue cleared\n");
+ if (file)
+ fput(file);
return lo->harderror;
case NBD_CLEAR_QUE:
nbd_clear_que(lo);
@@ -498,7 +559,7 @@ static int __init nbd_init(void)
init_MUTEX(&nbd_dev[i].tx_lock);
nbd_dev[i].blksize = 1024;
nbd_dev[i].blksize_bits = 10;
- nbd_dev[i].bytesize = 0x7ffffc00; /* 2GB */
+ nbd_dev[i].bytesize = ((u64)0x7ffffc00) << 10; /* 2TB */
disk->major = MAJOR_NR;
disk->first_minor = i;
disk->fops = &nbd_fops;
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index f5f8c37ed679..7e5b565c7421 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -294,7 +294,14 @@ struct agp_bridge_data {
#define I810_DRAM_ROW_0 0x00000001
#define I810_DRAM_ROW_0_SDRAM 0x00000001
-
+/* Intel 7505 registers */
+#define INTEL_I7505_NAPBASELO 0x10
+#define INTEL_I7505_APSIZE 0x74
+#define INTEL_I7505_NCAPID 0x60
+#define INTEL_I7505_NISTAT 0x6c
+#define INTEL_I7505_ATTBASE 0x78
+#define INTEL_I7505_ERRSTS 0x42
+#define INTEL_I7505_AGPCTRL 0x70
/* VIA register */
#define VIA_APBASE 0x10
diff --git a/drivers/char/ftape/lowlevel/ftape-init.h b/drivers/char/ftape/lowlevel/ftape-init.h
index 08af60c8a369..99a7b8ab086f 100644
--- a/drivers/char/ftape/lowlevel/ftape-init.h
+++ b/drivers/char/ftape/lowlevel/ftape-init.h
@@ -40,15 +40,4 @@
#define QIC117_TAPE_MAJOR 27
#endif
-/* ftape-init.c defined global variables.
- */
-
-
-/* ftape-init.c defined global functions not defined in ftape.h
- */
-#ifdef MODULE
-asmlinkage extern int init_module (void);
-asmlinkage extern void cleanup_module(void);
-#endif
-
#endif
diff --git a/drivers/char/ftape/zftape/zftape-ctl.c b/drivers/char/ftape/zftape/zftape-ctl.c
index 6441ca9298f2..67f8f6223422 100644
--- a/drivers/char/ftape/zftape/zftape-ctl.c
+++ b/drivers/char/ftape/zftape/zftape-ctl.c
@@ -648,50 +648,6 @@ int zft_check_write_access(zft_position *pos)
TRACE_EXIT 0;
}
-/* decide when we should lock the module in memory, even when calling
- * the release routine. This really is necessary for use with
- * kerneld.
- *
- * NOTE: we MUST NOT use zft_write_protected, because this includes
- * the file access mode as well which has no meaning with our
- * asynchronous update scheme.
- *
- * Ugly, ugly. We need to look the module if we changed the block size.
- * How sad! Need persistent modules storage!
- *
- * NOTE: I don't want to lock the module if the number of dma buffers
- * has been changed. It's enough! Stop the story! Give me persisitent
- * module storage! Do it!
- */
-int zft_dirty(void)
-{
- if (!ft_formatted || zft_offline) {
- /* cannot be dirty if not formatted or offline */
- return 0;
- }
- if (zft_blk_sz != CONFIG_ZFT_DFLT_BLK_SZ) {
- /* blocksize changed, must lock */
- return 1;
- }
- if (zft_mt_compression != 0) {
- /* compression mode with /dev/qft, must lock */
- return 1;
- }
- if (!zft_header_read) {
- /* tape is logical at BOT, no lock */
- return 0;
- }
- if (!zft_tape_at_lbot(&zft_pos)) {
- /* somewhere inside a volume, lock tape */
- return 1;
- }
- if (zft_volume_table_changed || zft_header_changed) {
- /* header segments dirty if tape not write protected */
- return !(ft_write_protected || zft_old_ftape);
- }
- return 0;
-}
-
/* OPEN routine called by kernel-interface code
*
* NOTE: this is also called by mt_reset() with dev_minor == -1
diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
index 82bfe2ef9e89..3ce0a682a1df 100644
--- a/drivers/char/ftape/zftape/zftape-init.c
+++ b/drivers/char/ftape/zftape/zftape-init.c
@@ -314,7 +314,7 @@ extern int zft_compressor_init(void);
/* Called by modules package when installing the driver or by kernel
* during the initialization phase
*/
-int __init zft_init(void)
+static int __init zft_init(void)
{
int i;
TRACE_FUN(ft_t_flow);
@@ -392,27 +392,9 @@ KERN_INFO
}
-#ifdef MODULE
-/* Called by modules package before trying to unload the module
- */
-static int can_unload(void)
-{
- return (GET_USE_COUNT(THIS_MODULE)||zft_dirty()||test_bit(0,&busy_flag))?-EBUSY:0;
-}
-/* Called by modules package when installing the driver
- */
-int init_module(void)
-{
- if (!mod_member_present(&__this_module, can_unload)) {
- return -EBUSY;
- }
- __this_module.can_unload = can_unload;
- return zft_init();
-}
-
/* Called by modules package when removing the driver
*/
-void cleanup_module(void)
+static void zft_exit(void)
{
int i;
TRACE_FUN(ft_t_flow);
@@ -435,4 +417,5 @@ void cleanup_module(void)
TRACE_EXIT;
}
-#endif /* MODULE */
+module_init(zft_init);
+module_exit(zft_exit);
diff --git a/drivers/char/ftape/zftape/zftape-init.h b/drivers/char/ftape/zftape/zftape-init.h
index 39d83f78c3b5..5f9ce2eef1ff 100644
--- a/drivers/char/ftape/zftape/zftape-init.h
+++ b/drivers/char/ftape/zftape/zftape-init.h
@@ -73,13 +73,6 @@ extern int zft_cmpr_register(struct zft_cmpr_ops *new_ops);
extern struct zft_cmpr_ops *zft_cmpr_unregister(void);
extern int zft_cmpr_lock(int try_to_load);
-#ifdef MODULE
-
-asmlinkage extern int init_module(void);
-asmlinkage extern void cleanup_module(void);
-
-#endif
-
#endif
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
index 1ba5ef35b6e4..77bd26b03160 100644
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -253,10 +253,6 @@ static int Fip_firmware_size;
/***********************/
/* Global module entry functions */
-#ifdef MODULE
-int init_module(void);
-void cleanup_module(void);
-#endif
/* Private (static) functions */
static int ip2_open(PTTY, struct file *);
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 41f31dd72261..ddb472255a6a 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -681,8 +681,8 @@ static void k_cur(struct vc_data *vc, unsigned char value, char up_flag)
static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)
{
- static const char *pad_chars = "0123456789+-*/\015,.?()";
- static const char *app_map = "pqrstuvwxylSRQMnnmPQ";
+ static const char *pad_chars = "0123456789+-*/\015,.?()#";
+ static const char *app_map = "pqrstuvwxylSRQMnnmPQS";
if (up_flag)
return; /* no action, if this is a key release */
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index c1ca48f798e0..9e888905fd27 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -697,9 +697,6 @@ int __init chr_dev_init(void)
lp_m68k_init();
#endif
misc_init();
-#if CONFIG_QIC02_TAPE
- qic02_tape_init();
-#endif
#ifdef CONFIG_FTAPE
ftape_init();
#endif
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 3bda171c4591..f67a1f8659c1 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -2198,6 +2198,23 @@ static int probe_si (struct sx_board *board)
}
}
+ /* Now we're pretty much convinced that there is an SI board here,
+ but to prevent trouble, we'd better double check that we don't
+ have an SI1 board when we're probing for an SI2 board.... */
+
+ write_sx_byte (board, SI2_ISA_ID_BASE,0x10);
+ if ( IS_SI1_BOARD(board)) {
+ /* This should be an SI1 board, which has this
+ location writable... */
+ if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10)
+ return 0;
+ } else {
+ /* This should be an SI2 board, which has the bottom
+ 3 bits non-writable... */
+ if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10)
+ return 0;
+ }
+
printheader ();
printk (KERN_DEBUG "sx: Found an SI board at %lx\n", board->hw_base);
diff --git a/drivers/char/tpqic02.c b/drivers/char/tpqic02.c
index 7bcafb16d21f..e85106fe3cfd 100644
--- a/drivers/char/tpqic02.c
+++ b/drivers/char/tpqic02.c
@@ -2759,9 +2759,7 @@ int __init qic02_tape_init(void)
return 0;
} /* qic02_tape_init */
-#ifdef MODULE
-
-void cleanup_module(void)
+static void qic02_module_exit(void)
{
unregister_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME);
if (status_zombie == NO)
@@ -2777,7 +2775,7 @@ void cleanup_module(void)
devfs_remove("tpqic150");
}
-int init_module(void)
+static int qic02_module_init(void)
{
int retval;
retval = qic02_tape_init();
@@ -2788,12 +2786,14 @@ int init_module(void)
if (!retval && qic02_tape_dynconf.ifc_type) {
retval = update_ifc_masks(qic02_tape_dynconf.ifc_type);
if (retval) {
- cleanup_module();
+ qic02_module_exit();
}
}
# endif
return retval;
}
-#endif
MODULE_LICENSE("GPL");
+
+module_init(qic02_module_init);
+module_exit(qic02_module_exit);
diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c
index 41fa773f6f8c..eba57eb21513 100644
--- a/drivers/char/watchdog/scx200_wdt.c
+++ b/drivers/char/watchdog/scx200_wdt.c
@@ -245,13 +245,18 @@ static int __init scx200_wdt_init(void)
sema_init(&open_semaphore, 1);
r = misc_register(&scx200_wdt_miscdev);
- if (r)
+ if (r) {
+ release_region(SCx200_CB_BASE + SCx200_WDT_OFFSET,
+ SCx200_WDT_SIZE);
return r;
+ }
r = register_reboot_notifier(&scx200_wdt_notifier);
if (r) {
printk(KERN_ERR NAME ": unable to register reboot notifier");
misc_deregister(&scx200_wdt_miscdev);
+ release_region(SCx200_CB_BASE + SCx200_WDT_OFFSET,
+ SCx200_WDT_SIZE);
return r;
}
diff --git a/drivers/hotplug/cpqphp_nvram.c b/drivers/hotplug/cpqphp_nvram.c
index d8208ca574de..a525141cbf2b 100644
--- a/drivers/hotplug/cpqphp_nvram.c
+++ b/drivers/hotplug/cpqphp_nvram.c
@@ -177,12 +177,12 @@ static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
spin_lock_irqsave(&int15_lock, flags);
__asm__ (
- "xorl %%ebx,%%ebx
- xorl %%edx,%%edx
- pushf
- push %%cs
- cli
- call *%6"
+ "xorl %%ebx,%%ebx\n" \
+ "xorl %%edx,%%edx\n" \
+ "pushf\n" \
+ "push %%cs\n" \
+ "cli\n" \
+ "call *%6\n"
: "=c" (*buf_size), "=a" (ret_val)
: "a" (op), "c" (*buf_size), "S" (ev_name),
"D" (buffer), "m" (compaq_int15_entry_point)
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 1d3142c87764..aa45e47c1a84 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -467,17 +467,25 @@ config BLK_DEV_CY82C693
If you say Y here, you need to say Y to "Use DMA by default
when available" as well.
+config BLK_DEV_CS5520
+ tristate "Cyrix CS5510/20 MediaGX chipset support (VERY EXPERIMENTAL)"
+ depends on BLK_DEV_IDEDMA_PCI && EXPERIMENTAL
+ help
+ Include support for PIO tuning an virtual DMA on the Cyrix MediaGX
+ 5510/5520 chipset. This will automatically be detected and
+ configured if found.
+
+ It is safe to say Y to this question.
+
config BLK_DEV_CS5530
- tristate "Cyrix CS5530 MediaGX chipset support"
- depends on BLK_DEV_IDEDMA_PCI
+ tristate "Cyrix/National Semiconductor CS5530 MediaGX chipset support"
+ depends on BLK_DEV_IDEDMA_PCIOA
help
Include support for UDMA on the Cyrix MediaGX 5530 chipset. This
will automatically be detected and configured if found.
It is safe to say Y to this question.
- People with SCSI-only systems should say N here. If unsure, say Y.
-
config BLK_DEV_HPT34X
tristate "HPT34X chipset support"
depends on BLK_DEV_IDEDMA_PCI
@@ -524,6 +532,13 @@ config BLK_DEV_HPT366
ide-probe at boot. It is reported to support DVD II drives, by the
manufacturer.
+config BLK_DEV_SC1200
+ tristate "National SCx200 chipset support"
+ depends on BLK_DEV_IDEDMA_PCI
+ help
+ This driver adds support for the built in IDE on the National
+ SCx200 series of embedded x86 "Geode" systems
+
config BLK_DEV_PIIX
tristate "Intel PIIXn chipsets support"
depends on BLK_DEV_IDEDMA_PCI
@@ -616,6 +631,9 @@ config BLK_DEV_SVWKS
config BLK_DEV_SIIMAGE
tristate "Silicon Image chipset support"
depends on BLK_DEV_IDEDMA_PCI
+ help
+ This driver adds PIO/(U)DMA support for the SI CMD680 and SII
+ 3112 (Serial ATA) chips.
config BLK_DEV_SIS5513
tristate "SiS5513 chipset support"
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index b1e4f1df8d07..30cc8720f36b 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -7,14 +7,14 @@
# Note : at this point, these files are compiled on all systems.
# In the future, some of these should be built conditionally.
#
-export-objs := ide-iops.o ide-taskfile.o ide-proc.o ide.o ide-probe.o ide-dma.o ide-lib.o setup-pci.o
+export-objs := ide-iops.o ide-taskfile.o ide-proc.o ide.o ide-probe.o ide-dma.o ide-lib.o setup-pci.o ide-io.o
# First come modules that register themselves with the core
obj-$(CONFIG_BLK_DEV_IDEPCI) += pci/
# Core IDE code - must come before legacy
-obj-$(CONFIG_BLK_DEV_IDE) += ide-probe.o ide-geometry.o ide-iops.o ide-taskfile.o ide.o ide-lib.o
+obj-$(CONFIG_BLK_DEV_IDE) += ide-io.o ide-probe.o ide-geometry.o ide-iops.o ide-taskfile.o ide.o ide-lib.o
obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o
obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o
obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index de4e1da086a3..eb93c33e91e2 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -2965,10 +2965,8 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
printk(", %dkB Cache", be16_to_cpu(cap.buffer_size));
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (drive->using_dma)
(void) HWIF(drive)->ide_dma_verbose(drive);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
printk("\n");
return nslots;
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index b13ddc6ca2bd..0505624354b4 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1412,24 +1412,6 @@ static int do_idedisk_standby (ide_drive_t *drive)
return call_idedisk_standby(drive, 0);
}
-static int call_idedisk_suspend (ide_drive_t *drive, int arg)
-{
- ide_task_t args;
- u8 suspend = (arg) ? WIN_SLEEPNOW2 : WIN_SLEEPNOW1;
- memset(&args, 0, sizeof(ide_task_t));
- args.tfRegister[IDE_COMMAND_OFFSET] = suspend;
- args.command_type = ide_cmd_type_parser(&args);
- return ide_raw_taskfile(drive, &args, NULL);
-}
-
-static int do_idedisk_suspend (ide_drive_t *drive)
-{
- if (drive->suspend_reset)
- return 1;
-
- return call_idedisk_suspend(drive, 0);
-}
-
#if 0
static int call_idedisk_checkpower (ide_drive_t *drive, int arg)
{
@@ -1456,13 +1438,6 @@ static int do_idedisk_checkpower (ide_drive_t *drive)
}
#endif
-static int do_idedisk_resume (ide_drive_t *drive)
-{
- if (!drive->suspend_reset)
- return 1;
- return 0;
-}
-
static int do_idedisk_flushcache (ide_drive_t *drive)
{
ide_task_t args;
@@ -1561,6 +1536,39 @@ static void idedisk_add_settings(ide_drive_t *drive)
#endif
}
+static int idedisk_suspend(struct device *dev, u32 state, u32 level)
+{
+ ide_drive_t *drive = dev->driver_data;
+
+ printk("Suspending device %p\n", dev->driver_data);
+
+ /* I hope that every freeze operation from the upper levels have
+ * already been done...
+ */
+
+ if (level != SUSPEND_SAVE_STATE)
+ return 0;
+
+ /* set the drive to standby */
+ printk(KERN_INFO "suspending: %s ", drive->name);
+ do_idedisk_standby(drive);
+ drive->blocked = 1;
+
+ BUG_ON (HWGROUP(drive)->handler);
+ return 0;
+}
+
+static int idedisk_resume(struct device *dev, u32 level)
+{
+ ide_drive_t *drive = dev->driver_data;
+
+ if (level != RESUME_RESTORE_STATE)
+ return 0;
+ BUG_ON(!drive->blocked);
+ drive->blocked = 0;
+ return 0;
+}
+
static void idedisk_setup (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
@@ -1641,10 +1649,8 @@ static void idedisk_setup (ide_drive_t *drive)
printk(", CHS=%d/%d/%d",
drive->bios_cyl, drive->bios_head, drive->bios_sect);
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (drive->using_dma)
(void) HWIF(drive)->ide_dma_verbose(drive);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
printk("\n");
drive->mult_count = 0;
@@ -1671,6 +1677,7 @@ static int idedisk_cleanup (ide_drive_t *drive)
{
struct gendisk *g = drive->disk;
+ do_idedisk_standby(drive);
if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
if (do_idedisk_flushcache(drive))
printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
@@ -1696,9 +1703,6 @@ static ide_driver_t idedisk_driver = {
.supports_dma = 1,
.supports_dsc_overlap = 0,
.cleanup = idedisk_cleanup,
- .standby = do_idedisk_standby,
- .suspend = do_idedisk_suspend,
- .resume = do_idedisk_resume,
.flushcache = do_idedisk_flushcache,
.do_request = do_rw_disk,
.sense = idedisk_dump_status,
@@ -1709,6 +1713,10 @@ static ide_driver_t idedisk_driver = {
.proc = idedisk_proc,
.attach = idedisk_attach,
.drives = LIST_HEAD_INIT(idedisk_driver.drives),
+ .gen_driver = {
+ .suspend = idedisk_suspend,
+ .resume = idedisk_resume,
+ }
};
static int idedisk_open(struct inode *inode, struct file *filp)
@@ -1835,8 +1843,7 @@ static void __exit idedisk_exit (void)
static int idedisk_init (void)
{
- ide_register_driver(&idedisk_driver);
- return 0;
+ return ide_register_driver(&idedisk_driver);
}
module_init(idedisk_init);
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 843df73d1251..b5953a4b009b 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -90,6 +90,7 @@
#include <asm/io.h>
#include <asm/irq.h>
+#define CONFIG_IDEDMA_NEW_DRIVE_LISTINGS
#ifdef CONFIG_IDEDMA_NEW_DRIVE_LISTINGS
struct drive_list_entry {
@@ -145,11 +146,20 @@ struct drive_list_entry drive_blacklist [] = {
};
-int in_drive_list(struct hd_driveid *id, struct drive_list_entry * drive_table)
+/**
+ * in_drive_list - look for drive in black/white list
+ * @id: drive identifier
+ * @drive_table: list to inspect
+ *
+ * Look for a drive in the blacklist and the whitelist tables
+ * Returns 1 if the drive is found in the table.
+ */
+
+static int in_drive_list(struct hd_driveid *id, struct drive_list_entry * drive_table)
{
for ( ; drive_table->id_model ; drive_table++)
if ((!strcmp(drive_table->id_model, id->model)) &&
- ((!strstr(drive_table->id_firmware, id->fw_rev)) ||
+ ((strstr(drive_table->id_firmware, id->fw_rev)) ||
(!strcmp(drive_table->id_firmware, "ALL"))))
return 1;
return 0;
@@ -189,9 +199,14 @@ const char *bad_dma_drives[] = {"WDC AC11000H",
#endif /* CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */
-/*
- * dma_intr() is the handler for disk read/write DMA interrupts
+/**
+ * ide_dma_intr - IDE DMA interrupt handler
+ * @drive: the drive the interrupt is for
+ *
+ * Handle an interrupt completing a read/write DMA transfer on an
+ * IDE device
*/
+
ide_startstop_t ide_dma_intr (ide_drive_t *drive)
{
u8 stat = 0, dma_stat = 0;
@@ -205,7 +220,7 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
DRIVER(drive)->end_request(drive, 1, rq->nr_sectors);
return ide_stopped;
}
- printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
+ printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
drive->name, dma_stat);
}
return DRIVER(drive)->error(drive, "dma_intr", stat);
@@ -213,6 +228,17 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
EXPORT_SYMBOL_GPL(ide_dma_intr);
+/**
+ * ide_build_sglist - map IDE scatter gather for DMA I/O
+ * @drive: the drive to build the DMA table for
+ * @rq: the request holding the sg list
+ *
+ * Perform the PCI mapping magic neccessary to access the source or
+ * target buffers of a request via PCI DMA. The lower layers of the
+ * kernel provide the neccessary cache management so that we can
+ * operate in a portable fashion
+ */
+
static int ide_build_sglist (ide_drive_t *drive, struct request *rq)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -232,6 +258,17 @@ static int ide_build_sglist (ide_drive_t *drive, struct request *rq)
return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
}
+/**
+ * ide_raw_build_sglist - map IDE scatter gather for DMA
+ * @drive: the drive to build the DMA table for
+ * @rq: the request holding the sg list
+ *
+ * Perform the PCI mapping magic neccessary to access the source or
+ * target buffers of a taskfile request via PCI DMA. The lower layers
+ * of the kernel provide the neccessary cache management so that we can
+ * operate in a portable fashion
+ */
+
static int ide_raw_build_sglist (ide_drive_t *drive, struct request *rq)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -246,6 +283,9 @@ static int ide_raw_build_sglist (ide_drive_t *drive, struct request *rq)
else
hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
#if 1
+ if (sector_count > 256)
+ BUG();
+
if (sector_count > 128) {
memset(&sg[nents], 0, sizeof(*sg));
sg[nents].page = virt_to_page(virt_addr);
@@ -279,11 +319,18 @@ static int ide_raw_build_sglist (ide_drive_t *drive, struct request *rq)
return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
}
-/*
- * ide_build_dmatable() prepares a dma request.
- * Returns 0 if all went okay, returns 1 otherwise.
- * May also be invoked from trm290.c
+/**
+ * ide_build_dmatable - build IDE DMA table
+ *
+ * ide_build_dmatable() prepares a dma request. We map the command
+ * to get the pci bus addresses of the buffers and then build up
+ * the PRD table that the IDE layer wants to be fed. The code
+ * knows about the 64K wrap bug in the CS5530.
+ *
+ * Returns 0 if all went okay, returns 1 otherwise.
+ * May also be invoked from trm290.c
*/
+
int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -317,7 +364,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
while (cur_len) {
if (count++ >= PRD_ENTRIES) {
- printk("%s: DMA table too small\n", drive->name);
+ printk(KERN_ERR "%s: DMA table too small\n", drive->name);
goto use_pio_instead;
} else {
u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
@@ -335,7 +382,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
* So here we break the 64KB entry into two 32KB entries instead.
*/
if (count++ >= PRD_ENTRIES) {
- printk("%s: DMA table too small\n", drive->name);
+ printk(KERN_ERR "%s: DMA table too small\n", drive->name);
goto use_pio_instead;
}
*table++ = cpu_to_le32(0x8000);
@@ -357,7 +404,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
*--table |= cpu_to_le32(0x80000000);
return count;
}
- printk("%s: empty DMA table?\n", drive->name);
+ printk(KERN_ERR "%s: empty DMA table?\n", drive->name);
use_pio_instead:
pci_unmap_sg(hwif->pci_dev,
hwif->sg_table,
@@ -369,7 +416,17 @@ use_pio_instead:
EXPORT_SYMBOL_GPL(ide_build_dmatable);
-/* Teardown mappings after DMA has completed. */
+/**
+ * ide_destroy_dmatable - clean up DMA mapping
+ * @drive: The drive to unmap
+ *
+ * Teardown mappings after DMA has completed. This must be called
+ * after the completion of each use of ide_build_dmatable and before
+ * the next use of ide_build_dmatable. Failure to do so will cause
+ * an oops as only one mapping can be live for each target at a given
+ * time.
+ */
+
void ide_destroy_dmatable (ide_drive_t *drive)
{
struct pci_dev *dev = HWIF(drive)->pci_dev;
@@ -382,6 +439,17 @@ void ide_destroy_dmatable (ide_drive_t *drive)
EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
+/**
+ * config_drive_for_dma - attempt to activate IDE DMA
+ * @drive: the drive to place in DMA mode
+ *
+ * If the drive supports at least mode 2 DMA or UDMA of any kind
+ * then attempt to place it into DMA mode. Drives that are known to
+ * support DMA but predate the DMA properties or that are known
+ * to have DMA handling bugs are also set up appropriately based
+ * on the good/bad drive lists.
+ */
+
static int config_drive_for_dma (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
@@ -415,15 +483,25 @@ static int config_drive_for_dma (ide_drive_t *drive)
return hwif->ide_dma_off_quietly(drive);
}
-/*
- * 1 dmaing, 2 error, 4 intr
+/**
+ * dma_timer_expiry - handle a DMA timeout
+ * @drive: Drive that timed out
+ *
+ * An IDE DMA transfer timed out. In the event of an error we ask
+ * the driver to resolve the problem, if a DMA transfer is still
+ * in progress we continue to wait (arguably we need to add a
+ * secondary 'I dont care what the drive thinks' timeout here)
+ * Finally if we have an interrupt but for some reason got the
+ * timeout first we complete the I/O. This can occur if an
+ * interrupt is lost or due to bugs.
*/
+
static int dma_timer_expiry (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
u8 dma_stat = hwif->INB(hwif->dma_status);
- printk("%s: dma_timer_expiry: dma status == 0x%02x\n",
+ printk(KERN_WARNING "%s: dma_timer_expiry: dma status == 0x%02x\n",
drive->name, dma_stat);
if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */
@@ -431,6 +509,8 @@ static int dma_timer_expiry (ide_drive_t *drive)
HWGROUP(drive)->expiry = NULL; /* one free ride for now */
+ /* 1 dmaing, 2 error, 4 intr */
+
if (dma_stat & 2) { /* ERROR */
(void) hwif->ide_dma_end(drive);
return DRIVER(drive)->error(drive,
@@ -445,6 +525,14 @@ static int dma_timer_expiry (ide_drive_t *drive)
return 0;
}
+/**
+ * __ide_dma_host_off - Generic DMA kill
+ * @drive: drive to control
+ *
+ * Perform the generic IDE controller DMA off operation. This
+ * works for most IDE bus mastering controllers
+ */
+
int __ide_dma_host_off (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -457,6 +545,13 @@ int __ide_dma_host_off (ide_drive_t *drive)
EXPORT_SYMBOL(__ide_dma_host_off);
+/**
+ * __ide_dma_host_off_quietly - Generic DMA kill
+ * @drive: drive to control
+ *
+ * Turn off the current DMA on this IDE controller.
+ */
+
int __ide_dma_off_quietly (ide_drive_t *drive)
{
drive->using_dma = 0;
@@ -473,14 +568,30 @@ int __ide_dma_off_quietly (ide_drive_t *drive)
EXPORT_SYMBOL(__ide_dma_off_quietly);
+/**
+ * __ide_dma_host_off - Generic DMA kill
+ * @drive: drive to control
+ *
+ * Turn off the current DMA on this IDE controller. Inform the
+ * user that DMA has been disabled.
+ */
+
int __ide_dma_off (ide_drive_t *drive)
{
- printk("%s: DMA disabled\n", drive->name);
+ printk(KERN_INFO "%s: DMA disabled\n", drive->name);
return HWIF(drive)->ide_dma_off_quietly(drive);
}
EXPORT_SYMBOL(__ide_dma_off);
+/**
+ * __ide_dma_host_on - Enable DMA on a host
+ * @drive: drive to enable for DMA
+ *
+ * Enable DMA on an IDE controller following generic bus mastering
+ * IDE controller behaviour
+ */
+
int __ide_dma_host_on (ide_drive_t *drive)
{
if (drive->using_dma) {
@@ -496,6 +607,13 @@ int __ide_dma_host_on (ide_drive_t *drive)
EXPORT_SYMBOL(__ide_dma_host_on);
+/**
+ * __ide_dma_on - Enable DMA on a device
+ * @drive: drive to enable DMA on
+ *
+ * Enable IDE DMA for a device on this IDE controller.
+ */
+
int __ide_dma_on (ide_drive_t *drive)
{
drive->using_dma = 1;
@@ -512,6 +630,13 @@ int __ide_dma_on (ide_drive_t *drive)
EXPORT_SYMBOL(__ide_dma_on);
+/**
+ * __ide_dma_check - check DMA setup
+ * @drive: drive to check
+ *
+ * Don't use - due for extermination
+ */
+
int __ide_dma_check (ide_drive_t *drive)
{
return config_drive_for_dma(drive);
@@ -519,6 +644,21 @@ int __ide_dma_check (ide_drive_t *drive)
EXPORT_SYMBOL(__ide_dma_check);
+/**
+ * ide_start_dma - begin a DMA phase
+ * @hwif: interface
+ * @drive: target device
+ * @reading: set if reading, clear if writing
+ *
+ * Build an IDE DMA PRD (IDE speak for scatter gather table)
+ * and then set up the DMA transfer registers for a device
+ * that follows generic IDE PCI DMA behaviour. Controllers can
+ * override this function if they need to
+ *
+ * Returns 0 on success. If a PIO fallback is required then 1
+ * is returned.
+ */
+
int ide_start_dma(ide_hwif_t *hwif, ide_drive_t *drive, int reading)
{
struct request *rq = HWGROUP(drive)->rq;
@@ -566,6 +706,10 @@ int __ide_dma_read (ide_drive_t *drive /*, struct request *rq */)
ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry);
command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA;
+
+ if (drive->vdma)
+ command = (lba48) ? WIN_READ_EXT: WIN_READ;
+
if (rq->flags & REQ_DRIVE_TASKFILE) {
ide_task_t *args = rq->special;
command = args->tfRegister[IDE_COMMAND_OFFSET];
@@ -600,6 +744,9 @@ int __ide_dma_write (ide_drive_t *drive /*, struct request *rq */)
ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry);
command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
+ if (drive->vdma)
+ command = (lba48) ? WIN_WRITE_EXT: WIN_WRITE;
+
if (rq->flags & REQ_DRIVE_TASKFILE) {
ide_task_t *args = rq->special;
command = args->tfRegister[IDE_COMMAND_OFFSET];
@@ -791,9 +938,17 @@ int __ide_dma_verbose (ide_drive_t *drive)
EXPORT_SYMBOL(__ide_dma_verbose);
+/**
+ * __ide_dma_retune - default retune handler
+ * @drive: drive to retune
+ *
+ * Default behaviour when we decide to return the IDE DMA setup.
+ * The default behaviour is "we don't"
+ */
+
int __ide_dma_retune (ide_drive_t *drive)
{
- printk("%s: chipset supported call only\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: chipset supported call only\n", __FUNCTION__);
return 1;
}
@@ -809,7 +964,7 @@ EXPORT_SYMBOL(__ide_dma_lostirq);
int __ide_dma_timeout (ide_drive_t *drive)
{
- printk("%s: timeout waiting for DMA\n", drive->name);
+ printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
if (HWIF(drive)->ide_dma_test_irq(drive))
return 0;
@@ -882,7 +1037,7 @@ int ide_allocate_dma_engine (ide_hwif_t *hwif)
if ((hwif->dmatable_cpu) && (hwif->sg_table))
return 0;
- printk("%s: -- Error, unable to allocate%s%s table(s).\n",
+ printk(KERN_ERR "%s: -- Error, unable to allocate%s%s table(s).\n",
(hwif->dmatable_cpu == NULL) ? " CPU" : "",
(hwif->sg_table == NULL) ? " SG DMA" : " DMA",
hwif->cds->name);
@@ -893,7 +1048,7 @@ int ide_allocate_dma_engine (ide_hwif_t *hwif)
int ide_mmio_dma (ide_hwif_t *hwif, unsigned long base, unsigned int ports)
{
- printk(" %s: MMIO-DMA at 0x%08lx-0x%08lx",
+ printk(KERN_INFO " %s: MMIO-DMA at 0x%08lx-0x%08lx",
hwif->name, base, base + ports - 1);
if (check_mem_region(base, ports)) {
printk(" -- Error, MMIO ports already in use.\n");
@@ -905,7 +1060,11 @@ int ide_mmio_dma (ide_hwif_t *hwif, unsigned long base, unsigned int ports)
request_region(base+16, hwif->cds->extra, hwif->cds->name);
hwif->dma_extra = hwif->cds->extra;
}
- hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
+
+ if(hwif->mate)
+ hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
+ else
+ hwif->dma_master = base;
if (hwif->dma_base2) {
if (!check_mem_region(hwif->dma_base2, ports))
request_mem_region(hwif->dma_base2, ports, hwif->name);
@@ -915,7 +1074,7 @@ int ide_mmio_dma (ide_hwif_t *hwif, unsigned long base, unsigned int ports)
int ide_iomio_dma (ide_hwif_t *hwif, unsigned long base, unsigned int ports)
{
- printk(" %s: BM-DMA at 0x%04lx-0x%04lx",
+ printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx",
hwif->name, base, base + ports - 1);
if (!request_region(base, ports, hwif->name)) {
printk(" -- Error, ports in use.\n");
@@ -926,7 +1085,11 @@ int ide_iomio_dma (ide_hwif_t *hwif, unsigned long base, unsigned int ports)
request_region(base+16, hwif->cds->extra, hwif->cds->name);
hwif->dma_extra = hwif->cds->extra;
}
- hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
+
+ if(hwif->mate)
+ hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
+ else
+ hwif->dma_master = base;
if (hwif->dma_base2) {
if (!request_region(hwif->dma_base2, ports, hwif->name))
{
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 49bdec5f81ec..f8e518bab609 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -115,6 +115,12 @@
/* #define IDEFLOPPY_DEBUG(fmt, args...) printk(KERN_INFO fmt, ## args) */
#define IDEFLOPPY_DEBUG( fmt, args... )
+#ifndef IDEFLOPPY_DEBUG_LOG
+#define debug_log(fmt, args... ) do {} while(0)
+#else
+#define debug_log printk
+#endif
+
/*
* Some drives require a longer irq timeout.
@@ -543,9 +549,7 @@ static int idefloppy_do_end_request(ide_drive_t *drive, int uptodate, int nsecs)
struct request *rq = HWGROUP(drive)->rq;
int error;
-#if IDEFLOPPY_DEBUG_LOG
- printk(KERN_INFO "Reached idefloppy_end_request\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ debug_log(KERN_INFO "Reached idefloppy_end_request\n");
switch (uptodate) {
case 0: error = IDEFLOPPY_ERROR_GENERAL; break;
@@ -627,7 +631,6 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un
}
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc)
{
struct request *rq = pc->rq;
@@ -636,7 +639,6 @@ static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc)
while ((bio = rq->bio) != NULL)
idefloppy_do_end_request(drive, 1, 0);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
/*
* idefloppy_queue_pc_head generates a new packet command request in front
@@ -682,25 +684,22 @@ static void idefloppy_analyze_error (ide_drive_t *drive,idefloppy_request_sense_
floppy->ascq = result->ascq;
floppy->progress_indication = result->sksv[0] & 0x80 ?
(u16)get_unaligned((u16 *)(result->sksv+1)):0x10000;
-#if IDEFLOPPY_DEBUG_LOG
if (floppy->failed_pc)
- printk(KERN_INFO "ide-floppy: pc = %x, sense key = %x, "
+ debug_log(KERN_INFO "ide-floppy: pc = %x, sense key = %x, "
"asc = %x, ascq = %x\n", floppy->failed_pc->c[0],
result->sense_key, result->asc, result->ascq);
else
- printk(KERN_INFO "ide-floppy: sense key = %x, asc = %x, "
+ debug_log(KERN_INFO "ide-floppy: sense key = %x, asc = %x, "
"ascq = %x\n", result->sense_key,
result->asc, result->ascq);
-#endif /* IDEFLOPPY_DEBUG_LOG */
}
static void idefloppy_request_sense_callback (ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
-#if IDEFLOPPY_DEBUG_LOG
- printk(KERN_INFO "ide-floppy: Reached %s\n", __FUNCTION__);
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ debug_log(KERN_INFO "ide-floppy: Reached %s\n", __FUNCTION__);
+
if (!floppy->pc->error) {
idefloppy_analyze_error(drive,(idefloppy_request_sense_result_t *) floppy->pc->buffer);
idefloppy_do_end_request(drive, 1, 0);
@@ -717,9 +716,7 @@ static void idefloppy_pc_callback (ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "ide-floppy: Reached %s\n", __FUNCTION__);
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ debug_log(KERN_INFO "ide-floppy: Reached %s\n", __FUNCTION__);
idefloppy_do_end_request(drive, floppy->pc->error ? 0 : 1, 0);
}
@@ -781,12 +778,9 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
struct request *rq = pc->rq;
unsigned int temp;
-#if IDEFLOPPY_DEBUG_LOG
- printk(KERN_INFO "ide-floppy: Reached %s interrupt handler\n",
+ debug_log(KERN_INFO "ide-floppy: Reached %s interrupt handler\n",
__FUNCTION__);
-#endif /* IDEFLOPPY_DEBUG_LOG */
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
if (HWIF(drive)->ide_dma_end(drive)) {
set_bit(PC_DMA_ERROR, &pc->flags);
@@ -794,30 +788,23 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
pc->actually_transferred = pc->request_transfer;
idefloppy_update_buffers(drive, pc);
}
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "ide-floppy: DMA finished\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ debug_log(KERN_INFO "ide-floppy: DMA finished\n");
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
/* Clear the interrupt */
status.all = HWIF(drive)->INB(IDE_STATUS_REG);
if (!status.b.drq) { /* No more interrupts */
-#if IDEFLOPPY_DEBUG_LOG
- printk(KERN_INFO "Packet command completed, %d bytes "
+ debug_log(KERN_INFO "Packet command completed, %d bytes "
"transferred\n", pc->actually_transferred);
-#endif /* IDEFLOPPY_DEBUG_LOG */
clear_bit(PC_DMA_IN_PROGRESS, &pc->flags);
local_irq_enable();
if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) {
/* Error detected */
-#if IDEFLOPPY_DEBUG_LOG
- printk(KERN_INFO "ide-floppy: %s: I/O error\n",
+ debug_log(KERN_INFO "ide-floppy: %s: I/O error\n",
drive->name);
-#endif /* IDEFLOPPY_DEBUG_LOG */
rq->errors++;
if (pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) {
printk(KERN_ERR "ide-floppy: I/O error in "
@@ -836,14 +823,14 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
pc->callback(drive);
return ide_stopped;
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
+
if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
printk(KERN_ERR "ide-floppy: The floppy wants to issue "
"more interrupts in DMA mode\n");
(void) HWIF(drive)->ide_dma_off(drive);
return ide_do_reset(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+
/* Get the number of bytes to transfer */
bcount.b.high = HWIF(drive)->INB(IDE_BCOUNTH_REG);
bcount.b.low = HWIF(drive)->INB(IDE_BCOUNTL_REG);
@@ -879,11 +866,9 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
NULL);
return ide_started;
}
-#if IDEFLOPPY_DEBUG_LOG
- printk(KERN_NOTICE "ide-floppy: The floppy wants to "
+ debug_log(KERN_NOTICE "ide-floppy: The floppy wants to "
"send us more data than expected - "
"allowing transfer\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
}
}
if (test_bit(PC_WRITING, &pc->flags)) {
@@ -1047,9 +1032,8 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
pc->callback(drive);
return ide_stopped;
}
-#if IDEFLOPPY_DEBUG_LOG
- printk(KERN_INFO "Retry number - %d\n",pc->retries);
-#endif /* IDEFLOPPY_DEBUG_LOG */
+
+ debug_log(KERN_INFO "Retry number - %d\n",pc->retries);
pc->retries++;
/* We haven't transferred any data yet */
@@ -1057,13 +1041,11 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
pc->current_position = pc->buffer;
bcount.all = min(pc->request_transfer, 63 * 1024);
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) {
(void) HWIF(drive)->ide_dma_off(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
feature.all = 0;
-#ifdef CONFIG_BLK_DEV_IDEDMA
+
if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) {
if (test_bit(PC_WRITING, &pc->flags)) {
feature.b.dma = !HWIF(drive)->ide_dma_write(drive);
@@ -1071,7 +1053,6 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
feature.b.dma = !HWIF(drive)->ide_dma_read(drive);
}
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
if (IDE_CONTROL_REG)
HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
@@ -1081,12 +1062,10 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
HWIF(drive)->OUTB(bcount.b.low, IDE_BCOUNTL_REG);
HWIF(drive)->OUTB(drive->select.all, IDE_SELECT_REG);
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (feature.b.dma) { /* Begin DMA, if necessary */
set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
(void) (HWIF(drive)->ide_dma_begin(drive));
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
/* Can we transfer the packet when we get the interrupt or wait? */
if (test_bit(IDEFLOPPY_ZIP_DRIVE, &floppy->flags)) {
@@ -1116,9 +1095,7 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
static void idefloppy_rw_callback (ide_drive_t *drive)
{
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "ide-floppy: Reached idefloppy_rw_callback\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ debug_log(KERN_INFO "ide-floppy: Reached idefloppy_rw_callback\n");
idefloppy_do_end_request(drive, 1, 0);
return;
@@ -1126,10 +1103,8 @@ static void idefloppy_rw_callback (ide_drive_t *drive)
static void idefloppy_create_prevent_cmd (idefloppy_pc_t *pc, int prevent)
{
-#if IDEFLOPPY_DEBUG_LOG
- printk(KERN_INFO "ide-floppy: creating prevent removal command, "
+ debug_log(KERN_INFO "ide-floppy: creating prevent removal command, "
"prevent = %d\n", prevent);
-#endif /* IDEFLOPPY_DEBUG_LOG */
idefloppy_init_pc(pc);
pc->c[0] = IDEFLOPPY_PREVENT_REMOVAL_CMD;
@@ -1212,11 +1187,9 @@ static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t
int blocks = rq->nr_sectors / floppy->bs_factor;
int cmd = rq_data_dir(rq);
-#if IDEFLOPPY_DEBUG_LOG
- printk("create_rw1%d_cmd: block == %d, blocks == %d\n",
+ debug_log("create_rw1%d_cmd: block == %d, blocks == %d\n",
2 * test_bit (IDEFLOPPY_USE_READ12, &floppy->flags),
block, blocks);
-#endif /* IDEFLOPPY_DEBUG_LOG */
idefloppy_init_pc(pc);
if (test_bit(IDEFLOPPY_USE_READ12, &floppy->flags)) {
@@ -1262,14 +1235,12 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request
idefloppy_pc_t *pc;
unsigned long block = (unsigned long)block_s;
-#if IDEFLOPPY_DEBUG_LOG
- printk(KERN_INFO "rq_status: %d, dev: %s, flags: %lx, errors: %d\n",
+ debug_log(KERN_INFO "rq_status: %d, dev: %s, flags: %lx, errors: %d\n",
rq->rq_status, rq->rq_disk->disk_name,
rq->flags, rq->errors);
- printk(KERN_INFO "sector: %ld, nr_sectors: %ld, "
- "current_nr_sectors: %ld\n", (long)rq->sector,
+ debug_log(KERN_INFO "sector: %ld, nr_sectors: %ld, "
+ "current_nr_sectors: %d\n", (long)rq->sector,
rq->nr_sectors, rq->current_nr_sectors);
-#endif /* IDEFLOPPY_DEBUG_LOG */
if (rq->errors >= ERROR_MAX) {
if (floppy->failed_pc != NULL)
@@ -1473,10 +1444,10 @@ static int idefloppy_get_capacity (ide_drive_t *drive)
}
}
if (!i) {
- IDEFLOPPY_DEBUG( "Descriptor 0 Code: %d\n",
+ debug_log( "Descriptor 0 Code: %d\n",
descriptor->dc);
}
- IDEFLOPPY_DEBUG( "Descriptor %d: %dkB, %d blocks, %d "
+ debug_log( "Descriptor %d: %dkB, %d blocks, %d "
"sector size\n", i, blocks * length / 1024, blocks,
length);
}
@@ -1909,9 +1880,7 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
drive->usage++;
-#if IDEFLOPPY_DEBUG_LOG
- printk(KERN_INFO "Reached idefloppy_open\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ debug_log(KERN_INFO "Reached idefloppy_open\n");
if (drive->usage == 1) {
clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
@@ -1958,9 +1927,7 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
idefloppy_pc_t pc;
-#if IDEFLOPPY_DEBUG_LOG
- printk (KERN_INFO "Reached idefloppy_release\n");
-#endif /* IDEFLOPPY_DEBUG_LOG */
+ debug_log(KERN_INFO "Reached idefloppy_release\n");
if (drive->usage == 1) {
idefloppy_floppy_t *floppy = drive->driver_data;
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
new file mode 100644
index 000000000000..89e956d8b011
--- /dev/null
+++ b/drivers/ide/ide-io.c
@@ -0,0 +1,1320 @@
+/*
+ * IDE I/O functions
+ *
+ * Basic PIO and command management functionality.
+ *
+ * This code was split off from ide.c. See ide.c for history and original
+ * copyrights.
+ *
+ * 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, 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.
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open non patent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/genhd.h>
+#include <linux/blkpg.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/completion.h>
+#include <linux/reboot.h>
+#include <linux/cdrom.h>
+#include <linux/seq_file.h>
+#include <linux/device.h>
+#include <linux/kmod.h>
+
+#include <asm/byteorder.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+
+#include "ide_modes.h"
+
+#if (DISK_RECOVERY_TIME > 0)
+
+Error So the User Has To Fix the Compilation And Stop Hacking Port 0x43
+Does anyone ever use this anyway ??
+
+/*
+ * For really screwy hardware (hey, at least it *can* be used with Linux)
+ * we can enforce a minimum delay time between successive operations.
+ */
+static unsigned long read_timer (ide_hwif_t *hwif)
+{
+ unsigned long t, flags;
+ int i;
+
+ /* FIXME this is completely unsafe! */
+ local_irq_save(flags);
+ t = jiffies * 11932;
+ outb_p(0, 0x43);
+ i = inb_p(0x40);
+ i |= inb_p(0x40) << 8;
+ local_irq_restore(flags);
+ return (t - i);
+}
+#endif /* DISK_RECOVERY_TIME */
+
+static inline void set_recovery_timer (ide_hwif_t *hwif)
+{
+#if (DISK_RECOVERY_TIME > 0)
+ hwif->last_time = read_timer(hwif);
+#endif /* DISK_RECOVERY_TIME */
+}
+
+/**
+ * ide_end_request - complete an IDE I/O
+ * @drive: IDE device for the I/O
+ * @uptodate:
+ * @nr_sectors: number of sectors completed
+ *
+ * This is our end_request wrapper function. We complete the I/O
+ * update random number input and dequeue the request, which if
+ * it was tagged may be out of order.
+ */
+
+int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
+{
+ struct request *rq;
+ unsigned long flags;
+ int ret = 1;
+
+ spin_lock_irqsave(&ide_lock, flags);
+ rq = HWGROUP(drive)->rq;
+
+ BUG_ON(!(rq->flags & REQ_STARTED));
+
+ if (!nr_sectors)
+ nr_sectors = rq->hard_cur_sectors;
+
+ /*
+ * decide whether to reenable DMA -- 3 is a random magic for now,
+ * if we DMA timeout more than 3 times, just stay in PIO
+ */
+ if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
+ drive->state = 0;
+ HWGROUP(drive)->hwif->ide_dma_on(drive);
+ }
+
+ if (!end_that_request_first(rq, uptodate, nr_sectors)) {
+ add_disk_randomness(rq->rq_disk);
+ if (!blk_rq_tagged(rq))
+ blkdev_dequeue_request(rq);
+ else
+ blk_queue_end_tag(&drive->queue, rq);
+ HWGROUP(drive)->rq = NULL;
+ end_that_request_last(rq);
+ ret = 0;
+ }
+ spin_unlock_irqrestore(&ide_lock, flags);
+ return ret;
+}
+
+EXPORT_SYMBOL(ide_end_request);
+
+/**
+ * ide_end_drive_cmd - end an explicit drive command
+ * @drive: command
+ * @stat: status bits
+ * @err: error bits
+ *
+ * Clean up after success/failure of an explicit drive command.
+ * These get thrown onto the queue so they are synchronized with
+ * real I/O operations on the drive.
+ *
+ * In LBA48 mode we have to read the register set twice to get
+ * all the extra information out.
+ */
+
+void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ unsigned long flags;
+ struct request *rq;
+
+ spin_lock_irqsave(&ide_lock, flags);
+ rq = HWGROUP(drive)->rq;
+ spin_unlock_irqrestore(&ide_lock, flags);
+
+ if (rq->flags & REQ_DRIVE_CMD) {
+ u8 *args = (u8 *) rq->buffer;
+ if (rq->errors == 0)
+ rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
+
+ if (args) {
+ args[0] = stat;
+ args[1] = err;
+ args[2] = hwif->INB(IDE_NSECTOR_REG);
+ }
+ } else if (rq->flags & REQ_DRIVE_TASK) {
+ u8 *args = (u8 *) rq->buffer;
+ if (rq->errors == 0)
+ rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
+
+ if (args) {
+ args[0] = stat;
+ args[1] = err;
+ args[2] = hwif->INB(IDE_NSECTOR_REG);
+ args[3] = hwif->INB(IDE_SECTOR_REG);
+ args[4] = hwif->INB(IDE_LCYL_REG);
+ args[5] = hwif->INB(IDE_HCYL_REG);
+ args[6] = hwif->INB(IDE_SELECT_REG);
+ }
+ } else if (rq->flags & REQ_DRIVE_TASKFILE) {
+ ide_task_t *args = (ide_task_t *) rq->special;
+ if (rq->errors == 0)
+ rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
+
+ if (args) {
+ if (args->tf_in_flags.b.data) {
+ u16 data = hwif->INW(IDE_DATA_REG);
+ args->tfRegister[IDE_DATA_OFFSET] = (data) & 0xFF;
+ args->hobRegister[IDE_DATA_OFFSET_HOB] = (data >> 8) & 0xFF;
+ }
+ args->tfRegister[IDE_ERROR_OFFSET] = err;
+ args->tfRegister[IDE_NSECTOR_OFFSET] = hwif->INB(IDE_NSECTOR_REG);
+ args->tfRegister[IDE_SECTOR_OFFSET] = hwif->INB(IDE_SECTOR_REG);
+ args->tfRegister[IDE_LCYL_OFFSET] = hwif->INB(IDE_LCYL_REG);
+ args->tfRegister[IDE_HCYL_OFFSET] = hwif->INB(IDE_HCYL_REG);
+ args->tfRegister[IDE_SELECT_OFFSET] = hwif->INB(IDE_SELECT_REG);
+ args->tfRegister[IDE_STATUS_OFFSET] = stat;
+
+ if (drive->addressing == 1) {
+ hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG_HOB);
+ args->hobRegister[IDE_FEATURE_OFFSET_HOB] = hwif->INB(IDE_FEATURE_REG);
+ args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = hwif->INB(IDE_NSECTOR_REG);
+ args->hobRegister[IDE_SECTOR_OFFSET_HOB] = hwif->INB(IDE_SECTOR_REG);
+ args->hobRegister[IDE_LCYL_OFFSET_HOB] = hwif->INB(IDE_LCYL_REG);
+ args->hobRegister[IDE_HCYL_OFFSET_HOB] = hwif->INB(IDE_HCYL_REG);
+ }
+ }
+ }
+
+ spin_lock_irqsave(&ide_lock, flags);
+ blkdev_dequeue_request(rq);
+ HWGROUP(drive)->rq = NULL;
+ end_that_request_last(rq);
+ spin_unlock_irqrestore(&ide_lock, flags);
+}
+
+EXPORT_SYMBOL(ide_end_drive_cmd);
+
+/**
+ * try_to_flush_leftover_data - flush junk
+ * @drive: drive to flush
+ *
+ * try_to_flush_leftover_data() is invoked in response to a drive
+ * unexpectedly having its DRQ_STAT bit set. As an alternative to
+ * resetting the drive, this routine tries to clear the condition
+ * by read a sector's worth of data from the drive. Of course,
+ * this may not help if the drive is *waiting* for data from *us*.
+ */
+void try_to_flush_leftover_data (ide_drive_t *drive)
+{
+ int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS;
+
+ if (drive->media != ide_disk)
+ return;
+ while (i > 0) {
+ u32 buffer[16];
+ u32 wcount = (i > 16) ? 16 : i;
+
+ i -= wcount;
+ HWIF(drive)->ata_input_data(drive, buffer, wcount);
+ }
+}
+
+EXPORT_SYMBOL(try_to_flush_leftover_data);
+
+/*
+ * FIXME Add an ATAPI error
+ */
+
+/**
+ * ide_error - handle an error on the IDE
+ * @drive: drive the error occurred on
+ * @msg: message to report
+ * @stat: status bits
+ *
+ * ide_error() takes action based on the error returned by the drive.
+ * For normal I/O that may well include retries. We deal with
+ * both new-style (taskfile) and old style command handling here.
+ * In the case of taskfile command handling there is work left to
+ * do
+ */
+
+ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat)
+{
+ ide_hwif_t *hwif;
+ struct request *rq;
+ u8 err;
+
+ err = ide_dump_status(drive, msg, stat);
+ if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
+ return ide_stopped;
+
+ hwif = HWIF(drive);
+ /* retry only "normal" I/O: */
+ if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
+ rq->errors = 1;
+ ide_end_drive_cmd(drive, stat, err);
+ return ide_stopped;
+ }
+ if (rq->flags & REQ_DRIVE_TASKFILE) {
+ rq->errors = 1;
+ ide_end_drive_cmd(drive, stat, err);
+// ide_end_taskfile(drive, stat, err);
+ return ide_stopped;
+ }
+
+ if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) {
+ /* other bits are useless when BUSY */
+ rq->errors |= ERROR_RESET;
+ } else {
+ if (drive->media != ide_disk)
+ goto media_out;
+
+ if (stat & ERR_STAT) {
+ /* err has different meaning on cdrom and tape */
+ if (err == ABRT_ERR) {
+ if (drive->select.b.lba &&
+ (hwif->INB(IDE_COMMAND_REG) == WIN_SPECIFY))
+ /* some newer drives don't
+ * support WIN_SPECIFY
+ */
+ return ide_stopped;
+ } else if ((err & BAD_CRC) == BAD_CRC) {
+ drive->crc_count++;
+ /* UDMA crc error -- just retry the operation */
+ } else if (err & (BBD_ERR | ECC_ERR)) {
+ /* retries won't help these */
+ rq->errors = ERROR_MAX;
+ } else if (err & TRK0_ERR) {
+ /* help it find track zero */
+ rq->errors |= ERROR_RECAL;
+ }
+ }
+media_out:
+ if ((stat & DRQ_STAT) && rq_data_dir(rq) != WRITE)
+ try_to_flush_leftover_data(drive);
+ }
+ if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) {
+ /* force an abort */
+ hwif->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
+ }
+ if (rq->errors >= ERROR_MAX) {
+ if (drive->driver != NULL)
+ DRIVER(drive)->end_request(drive, 0, 0);
+ else
+ ide_end_request(drive, 0, 0);
+ } else {
+ if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+ ++rq->errors;
+ return ide_do_reset(drive);
+ }
+ if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
+ drive->special.b.recalibrate = 1;
+ ++rq->errors;
+ }
+ return ide_stopped;
+}
+
+EXPORT_SYMBOL(ide_error);
+
+/**
+ * ide_cmd - issue a simple drive command
+ * @drive: drive the command is for
+ * @cmd: command byte
+ * @nsect: sector byte
+ * @handler: handler for the command completion
+ *
+ * Issue a simple drive command with interrupts.
+ * The drive must be selected beforehand.
+ */
+
+void ide_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, ide_handler_t *handler)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ if (HWGROUP(drive)->handler != NULL)
+ BUG();
+ ide_set_handler(drive, handler, WAIT_CMD, NULL);
+ if (IDE_CONTROL_REG)
+ hwif->OUTB(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */
+ SELECT_MASK(drive,0);
+ hwif->OUTB(nsect,IDE_NSECTOR_REG);
+ hwif->OUTB(cmd,IDE_COMMAND_REG);
+}
+
+EXPORT_SYMBOL(ide_cmd);
+
+/**
+ * drive_cmd_intr - drive command completion interrupt
+ * @drive: drive the completion interrupt occurred on
+ *
+ * drive_cmd_intr() is invoked on completion of a special DRIVE_CMD.
+ * We do any neccessary daya reading and then wait for the drive to
+ * go non busy. At that point we may read the error data and complete
+ * the request
+ */
+
+ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
+{
+ struct request *rq = HWGROUP(drive)->rq;
+ ide_hwif_t *hwif = HWIF(drive);
+ u8 *args = (u8 *) rq->buffer;
+ u8 stat = hwif->INB(IDE_STATUS_REG);
+ int retries = 10;
+
+ local_irq_enable();
+ if ((stat & DRQ_STAT) && args && args[3]) {
+ u8 io_32bit = drive->io_32bit;
+ drive->io_32bit = 0;
+ hwif->ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS);
+ drive->io_32bit = io_32bit;
+ while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
+ udelay(100);
+ }
+
+ if (!OK_STAT(stat, READY_STAT, BAD_STAT))
+ return DRIVER(drive)->error(drive, "drive_cmd", stat);
+ /* calls ide_end_drive_cmd */
+ ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
+ return ide_stopped;
+}
+
+EXPORT_SYMBOL(drive_cmd_intr);
+
+/**
+ * do_special - issue some special commands
+ * @drive: drive the command is for
+ *
+ * do_special() is used to issue WIN_SPECIFY, WIN_RESTORE, and WIN_SETMULT
+ * commands to a drive. It used to do much more, but has been scaled
+ * back.
+ */
+
+ide_startstop_t do_special (ide_drive_t *drive)
+{
+ special_t *s = &drive->special;
+
+#ifdef DEBUG
+ printk("%s: do_special: 0x%02x\n", drive->name, s->all);
+#endif
+ if (s->b.set_tune) {
+ s->b.set_tune = 0;
+ if (HWIF(drive)->tuneproc != NULL)
+ HWIF(drive)->tuneproc(drive, drive->tune_req);
+ } else if (drive->driver != NULL) {
+ return DRIVER(drive)->special(drive);
+ } else if (s->all) {
+ printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, s->all);
+ s->all = 0;
+ }
+ return ide_stopped;
+}
+
+EXPORT_SYMBOL(do_special);
+
+/**
+ * execute_drive_command - issue special drive command
+ * @drive: the drive to issue th command on
+ * @rq: the request structure holding the command
+ *
+ * execute_drive_cmd() issues a special drive command, usually
+ * initiated by ioctl() from the external hdparm program. The
+ * command can be a drive command, drive task or taskfile
+ * operation. Weirdly you can call it with NULL to wait for
+ * all commands to finish. Don't do this as that is due to change
+ */
+
+ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ if (rq->flags & REQ_DRIVE_TASKFILE) {
+ ide_task_t *args = rq->special;
+
+ if (!args)
+ goto done;
+
+ if (args->tf_out_flags.all != 0)
+ return flagged_taskfile(drive, args);
+ return do_rw_taskfile(drive, args);
+ } else if (rq->flags & REQ_DRIVE_TASK) {
+ u8 *args = rq->buffer;
+ u8 sel;
+
+ if (!args)
+ goto done;
+#ifdef DEBUG
+ printk("%s: DRIVE_TASK_CMD ", drive->name);
+ printk("cmd=0x%02x ", args[0]);
+ printk("fr=0x%02x ", args[1]);
+ printk("ns=0x%02x ", args[2]);
+ printk("sc=0x%02x ", args[3]);
+ printk("lcyl=0x%02x ", args[4]);
+ printk("hcyl=0x%02x ", args[5]);
+ printk("sel=0x%02x\n", args[6]);
+#endif
+ hwif->OUTB(args[1], IDE_FEATURE_REG);
+ hwif->OUTB(args[3], IDE_SECTOR_REG);
+ hwif->OUTB(args[4], IDE_LCYL_REG);
+ hwif->OUTB(args[5], IDE_HCYL_REG);
+ sel = (args[6] & ~0x10);
+ if (drive->select.b.unit)
+ sel |= 0x10;
+ hwif->OUTB(sel, IDE_SELECT_REG);
+ ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
+ return ide_started;
+ } else if (rq->flags & REQ_DRIVE_CMD) {
+ u8 *args = rq->buffer;
+
+ if (!args)
+ goto done;
+#ifdef DEBUG
+ printk("%s: DRIVE_CMD ", drive->name);
+ printk("cmd=0x%02x ", args[0]);
+ printk("sc=0x%02x ", args[1]);
+ printk("fr=0x%02x ", args[2]);
+ printk("xx=0x%02x\n", args[3]);
+#endif
+ if (args[0] == WIN_SMART) {
+ hwif->OUTB(0x4f, IDE_LCYL_REG);
+ hwif->OUTB(0xc2, IDE_HCYL_REG);
+ hwif->OUTB(args[2],IDE_FEATURE_REG);
+ hwif->OUTB(args[1],IDE_SECTOR_REG);
+ ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
+ return ide_started;
+ }
+ hwif->OUTB(args[2],IDE_FEATURE_REG);
+ ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
+ return ide_started;
+ }
+
+done:
+ /*
+ * NULL is actually a valid way of waiting for
+ * all current requests to be flushed from the queue.
+ */
+#ifdef DEBUG
+ printk("%s: DRIVE_CMD (null)\n", drive->name);
+#endif
+ ide_end_drive_cmd(drive,
+ hwif->INB(IDE_STATUS_REG),
+ hwif->INB(IDE_ERROR_REG));
+ return ide_stopped;
+}
+
+EXPORT_SYMBOL(execute_drive_cmd);
+
+/**
+ * start_request - start of I/O and command issuing for IDE
+ *
+ * start_request() initiates handling of a new I/O request. It
+ * accepts commands and I/O (read/write) requests. It also does
+ * the final remapping for weird stuff like EZDrive. Once
+ * device mapper can work sector level the EZDrive stuff can go away
+ *
+ * FIXME: this function needs a rename
+ */
+
+ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
+{
+ ide_startstop_t startstop;
+ unsigned long block;
+
+ BUG_ON(!(rq->flags & REQ_STARTED));
+
+#ifdef DEBUG
+ printk("%s: start_request: current=0x%08lx\n",
+ HWIF(drive)->name, (unsigned long) rq);
+#endif
+
+ /* bail early if we've exceeded max_failures */
+ if (drive->max_failures && (drive->failures > drive->max_failures)) {
+ goto kill_rq;
+ }
+
+ /*
+ * bail early if we've sent a device to sleep, however how to wake
+ * this needs to be a masked flag. FIXME for proper operations.
+ */
+ if (drive->suspend_reset)
+ goto kill_rq;
+
+ block = rq->sector;
+ if (blk_fs_request(rq) &&
+ (drive->media == ide_disk || drive->media == ide_floppy)) {
+ block += drive->sect0;
+ }
+ /* Yecch - this will shift the entire interval,
+ possibly killing some innocent following sector */
+ if (block == 0 && drive->remap_0_to_1 == 1)
+ block = 1; /* redirect MBR access to EZ-Drive partn table */
+
+#if (DISK_RECOVERY_TIME > 0)
+ while ((read_timer() - HWIF(drive)->last_time) < DISK_RECOVERY_TIME);
+#endif
+
+ SELECT_DRIVE(drive);
+ if (ide_wait_stat(&startstop, drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) {
+ printk(KERN_ERR "%s: drive not ready for command\n", drive->name);
+ return startstop;
+ }
+ if (!drive->special.all) {
+ if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK))
+ return execute_drive_cmd(drive, rq);
+ else if (rq->flags & REQ_DRIVE_TASKFILE)
+ return execute_drive_cmd(drive, rq);
+
+ if (drive->driver != NULL) {
+ return (DRIVER(drive)->do_request(drive, rq, block));
+ }
+ printk(KERN_ERR "%s: media type %d not supported\n", drive->name, drive->media);
+ goto kill_rq;
+ }
+ return do_special(drive);
+kill_rq:
+ if (drive->driver != NULL)
+ DRIVER(drive)->end_request(drive, 0, 0);
+ else
+ ide_end_request(drive, 0, 0);
+ return ide_stopped;
+}
+
+EXPORT_SYMBOL(start_request);
+
+/**
+ * restart_request - reissue an IDE request
+ * @drive: drive for request
+ * @rq: request to reissue
+ *
+ * Reissue a request. See start_request for details and for
+ * FIXME
+ */
+
+int restart_request (ide_drive_t *drive, struct request *rq)
+{
+ (void) start_request(drive, rq);
+ return 0;
+}
+
+EXPORT_SYMBOL(restart_request);
+
+/**
+ * ide_stall_queue - pause an IDE device
+ * @drive: drive to stall
+ * @timeout: time to stall for (jiffies)
+ *
+ * ide_stall_queue() can be used by a drive to give excess bandwidth back
+ * to the hwgroup by sleeping for timeout jiffies.
+ */
+
+void ide_stall_queue (ide_drive_t *drive, unsigned long timeout)
+{
+ if (timeout > WAIT_WORSTCASE)
+ timeout = WAIT_WORSTCASE;
+ drive->sleep = timeout + jiffies;
+}
+
+EXPORT_SYMBOL(ide_stall_queue);
+
+#define WAKEUP(drive) ((drive)->service_start + 2 * (drive)->service_time)
+
+/**
+ * choose_drive - select a drive to service
+ * @hwgroup: hardware group to select on
+ *
+ * choose_drive() selects the next drive which will be serviced.
+ * This is neccessary because the IDE layer can't issue commands
+ * to both drives on the same cable, unlike SCSI.
+ */
+
+static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)
+{
+ ide_drive_t *drive, *best;
+
+repeat:
+ best = NULL;
+ drive = hwgroup->drive;
+ do {
+ if (!blk_queue_empty(&drive->queue) && (!drive->sleep || time_after_eq(jiffies, drive->sleep))) {
+ if (!best
+ || (drive->sleep && (!best->sleep || 0 < (signed long)(best->sleep - drive->sleep)))
+ || (!best->sleep && 0 < (signed long)(WAKEUP(best) - WAKEUP(drive))))
+ {
+ if (!blk_queue_plugged(&drive->queue))
+ best = drive;
+ }
+ }
+ } while ((drive = drive->next) != hwgroup->drive);
+ if (best && best->nice1 && !best->sleep && best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {
+ long t = (signed long)(WAKEUP(best) - jiffies);
+ if (t >= WAIT_MIN_SLEEP) {
+ /*
+ * We *may* have some time to spare, but first let's see if
+ * someone can potentially benefit from our nice mood today..
+ */
+ drive = best->next;
+ do {
+ if (!drive->sleep
+ /* FIXME: use time_before */
+ && 0 < (signed long)(WAKEUP(drive) - (jiffies - best->service_time))
+ && 0 < (signed long)((jiffies + t) - WAKEUP(drive)))
+ {
+ ide_stall_queue(best, IDE_MIN(t, 10 * WAIT_MIN_SLEEP));
+ goto repeat;
+ }
+ } while ((drive = drive->next) != best);
+ }
+ }
+ return best;
+}
+
+/*
+ * Issue a new request to a drive from hwgroup
+ * Caller must have already done spin_lock_irqsave(&ide_lock, ..);
+ *
+ * A hwgroup is a serialized group of IDE interfaces. Usually there is
+ * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640)
+ * may have both interfaces in a single hwgroup to "serialize" access.
+ * Or possibly multiple ISA interfaces can share a common IRQ by being grouped
+ * together into one hwgroup for serialized access.
+ *
+ * Note also that several hwgroups can end up sharing a single IRQ,
+ * possibly along with many other devices. This is especially common in
+ * PCI-based systems with off-board IDE controller cards.
+ *
+ * The IDE driver uses the single global ide_lock spinlock to protect
+ * access to the request queues, and to protect the hwgroup->busy flag.
+ *
+ * The first thread into the driver for a particular hwgroup sets the
+ * hwgroup->busy flag to indicate that this hwgroup is now active,
+ * and then initiates processing of the top request from the request queue.
+ *
+ * Other threads attempting entry notice the busy setting, and will simply
+ * queue their new requests and exit immediately. Note that hwgroup->busy
+ * remains set even when the driver is merely awaiting the next interrupt.
+ * Thus, the meaning is "this hwgroup is busy processing a request".
+ *
+ * When processing of a request completes, the completing thread or IRQ-handler
+ * will start the next request from the queue. If no more work remains,
+ * the driver will clear the hwgroup->busy flag and exit.
+ *
+ * The ide_lock (spinlock) is used to protect all access to the
+ * hwgroup->busy flag, but is otherwise not needed for most processing in
+ * the driver. This makes the driver much more friendlier to shared IRQs
+ * than previous designs, while remaining 100% (?) SMP safe and capable.
+ */
+/* --BenH: made non-static as ide-pmac.c uses it to kick the hwgroup back
+ * into life on wakeup from machine sleep.
+ */
+void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
+{
+ ide_drive_t *drive;
+ ide_hwif_t *hwif;
+ struct request *rq;
+ ide_startstop_t startstop;
+
+ /* for atari only: POSSIBLY BROKEN HERE(?) */
+ ide_get_lock(&ide_intr_lock, ide_intr, hwgroup);
+
+ /* necessary paranoia: ensure IRQs are masked on local CPU */
+ local_irq_disable();
+
+ while (!hwgroup->busy) {
+ hwgroup->busy = 1;
+ drive = choose_drive(hwgroup);
+ if (drive == NULL) {
+ unsigned long sleep = 0;
+ hwgroup->rq = NULL;
+ drive = hwgroup->drive;
+ do {
+ if (drive->sleep && (!sleep || 0 < (signed long)(sleep - drive->sleep)))
+ sleep = drive->sleep;
+ } while ((drive = drive->next) != hwgroup->drive);
+ if (sleep) {
+ /*
+ * Take a short snooze, and then wake up this hwgroup again.
+ * This gives other hwgroups on the same a chance to
+ * play fairly with us, just in case there are big differences
+ * in relative throughputs.. don't want to hog the cpu too much.
+ */
+ if (time_before(sleep, jiffies + WAIT_MIN_SLEEP))
+ sleep = jiffies + WAIT_MIN_SLEEP;
+#if 1
+ if (timer_pending(&hwgroup->timer))
+ printk(KERN_CRIT "ide_set_handler: timer already active\n");
+#endif
+ /* so that ide_timer_expiry knows what to do */
+ hwgroup->sleeping = 1;
+ mod_timer(&hwgroup->timer, sleep);
+ /* we purposely leave hwgroup->busy==1
+ * while sleeping */
+ } else {
+ /* Ugly, but how can we sleep for the lock
+ * otherwise? perhaps from tq_disk?
+ */
+
+ /* for atari only */
+ ide_release_lock(&ide_intr_lock);
+ hwgroup->busy = 0;
+ }
+
+ /* no more work for this hwgroup (for now) */
+ return;
+ }
+ hwif = HWIF(drive);
+ if (hwgroup->hwif->sharing_irq &&
+ hwif != hwgroup->hwif &&
+ hwif->io_ports[IDE_CONTROL_OFFSET]) {
+ /* set nIEN for previous hwif */
+ SELECT_INTERRUPT(drive);
+ }
+ hwgroup->hwif = hwif;
+ hwgroup->drive = drive;
+ drive->sleep = 0;
+ drive->service_start = jiffies;
+
+queue_next:
+ if (!ata_can_queue(drive)) {
+ if (!ata_pending_commands(drive))
+ hwgroup->busy = 0;
+
+ break;
+ }
+
+ if (blk_queue_plugged(&drive->queue)) {
+ if (drive->using_tcq)
+ break;
+
+ printk(KERN_ERR "ide: huh? queue was plugged!\n");
+ break;
+ }
+
+ /*
+ * we know that the queue isn't empty, but this can happen
+ * if the q->prep_rq_fn() decides to kill a request
+ */
+ rq = elv_next_request(&drive->queue);
+ if (!rq) {
+ hwgroup->busy = !!ata_pending_commands(drive);
+ break;
+ }
+
+ if (!rq->bio && ata_pending_commands(drive))
+ break;
+
+ hwgroup->rq = rq;
+
+ /*
+ * Some systems have trouble with IDE IRQs arriving while
+ * the driver is still setting things up. So, here we disable
+ * the IRQ used by this interface while the request is being started.
+ * This may look bad at first, but pretty much the same thing
+ * happens anyway when any interrupt comes in, IDE or otherwise
+ * -- the kernel masks the IRQ while it is being handled.
+ */
+ if (masked_irq && hwif->irq != masked_irq)
+ disable_irq_nosync(hwif->irq);
+ spin_unlock(&ide_lock);
+ local_irq_enable();
+ /* allow other IRQs while we start this request */
+ startstop = start_request(drive, rq);
+ spin_lock_irq(&ide_lock);
+ if (masked_irq && hwif->irq != masked_irq)
+ enable_irq(hwif->irq);
+ if (startstop == ide_released)
+ goto queue_next;
+ if (startstop == ide_stopped)
+ hwgroup->busy = 0;
+ }
+}
+
+EXPORT_SYMBOL(ide_do_request);
+
+/*
+ * Passes the stuff to ide_do_request
+ */
+void do_ide_request(request_queue_t *q)
+{
+ ide_do_request(q->queuedata, 0);
+}
+
+/*
+ * un-busy the hwgroup etc, and clear any pending DMA status. we want to
+ * retry the current request in pio mode instead of risking tossing it
+ * all away
+ */
+void ide_dma_timeout_retry(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ struct request *rq;
+
+ /*
+ * end current dma transaction
+ */
+ (void) hwif->ide_dma_end(drive);
+
+ /*
+ * complain a little, later we might remove some of this verbosity
+ */
+ printk(KERN_WARNING "%s: timeout waiting for DMA\n", drive->name);
+ (void) hwif->ide_dma_timeout(drive);
+
+ /*
+ * disable dma for now, but remember that we did so because of
+ * a timeout -- we'll reenable after we finish this next request
+ * (or rather the first chunk of it) in pio.
+ */
+ drive->retry_pio++;
+ drive->state = DMA_PIO_RETRY;
+ (void) hwif->ide_dma_off_quietly(drive);
+
+ /*
+ * un-busy drive etc (hwgroup->busy is cleared on return) and
+ * make sure request is sane
+ */
+ rq = HWGROUP(drive)->rq;
+ HWGROUP(drive)->rq = NULL;
+
+ rq->errors = 0;
+ rq->sector = rq->bio->bi_sector;
+ rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
+ rq->hard_cur_sectors = rq->current_nr_sectors;
+ if (rq->bio)
+ rq->buffer = NULL;
+}
+
+EXPORT_SYMBOL(ide_dma_timeout_retry);
+
+/**
+ * ide_timer_expiry - handle lack of an IDE interrupt
+ * @data: timer callback magic (hwgroup)
+ *
+ * An IDE command has timed out before the expected drive return
+ * occurred. At this point we attempt to clean up the current
+ * mess. If the current handler includes an expiry handler then
+ * we invoke the expiry handler, and providing it is happy the
+ * work is done. If that fails we apply generic recovery rules
+ * invoking the handler and checking the drive DMA status. We
+ * have an excessively incestuous relationship with the DMA
+ * logic that wants cleaning up.
+ */
+
+void ide_timer_expiry (unsigned long data)
+{
+ ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data;
+ ide_handler_t *handler;
+ ide_expiry_t *expiry;
+ unsigned long flags;
+ unsigned long wait;
+
+ spin_lock_irqsave(&ide_lock, flags);
+ del_timer(&hwgroup->timer);
+
+ if ((handler = hwgroup->handler) == NULL) {
+ /*
+ * Either a marginal timeout occurred
+ * (got the interrupt just as timer expired),
+ * or we were "sleeping" to give other devices a chance.
+ * Either way, we don't really want to complain about anything.
+ */
+ if (hwgroup->sleeping) {
+ hwgroup->sleeping = 0;
+ hwgroup->busy = 0;
+ }
+ } else {
+ ide_drive_t *drive = hwgroup->drive;
+ if (!drive) {
+ printk(KERN_ERR "ide_timer_expiry: hwgroup->drive was NULL\n");
+ hwgroup->handler = NULL;
+ } else {
+ ide_hwif_t *hwif;
+ ide_startstop_t startstop = ide_stopped;
+ if (!hwgroup->busy) {
+ hwgroup->busy = 1; /* paranoia */
+ printk(KERN_ERR "%s: ide_timer_expiry: hwgroup->busy was 0 ??\n", drive->name);
+ }
+ if ((expiry = hwgroup->expiry) != NULL) {
+ /* continue */
+ if ((wait = expiry(drive)) != 0) {
+ /* reset timer */
+ hwgroup->timer.expires = jiffies + wait;
+ add_timer(&hwgroup->timer);
+ spin_unlock_irqrestore(&ide_lock, flags);
+ return;
+ }
+ }
+ hwgroup->handler = NULL;
+ /*
+ * We need to simulate a real interrupt when invoking
+ * the handler() function, which means we need to
+ * globally mask the specific IRQ:
+ */
+ spin_unlock(&ide_lock);
+ hwif = HWIF(drive);
+#if DISABLE_IRQ_NOSYNC
+ disable_irq_nosync(hwif->irq);
+#else
+ /* disable_irq_nosync ?? */
+ disable_irq(hwif->irq);
+#endif /* DISABLE_IRQ_NOSYNC */
+ /* local CPU only,
+ * as if we were handling an interrupt */
+ local_irq_disable();
+ if (hwgroup->poll_timeout != 0) {
+ startstop = handler(drive);
+ } else if (drive_is_ready(drive)) {
+ if (drive->waiting_for_dma)
+ (void) hwgroup->hwif->ide_dma_lostirq(drive);
+ (void)ide_ack_intr(hwif);
+ printk(KERN_WARNING "%s: lost interrupt\n", drive->name);
+ startstop = handler(drive);
+ } else {
+ if (drive->waiting_for_dma) {
+ startstop = ide_stopped;
+ ide_dma_timeout_retry(drive);
+ } else
+ startstop = DRIVER(drive)->error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG));
+ }
+ set_recovery_timer(hwif);
+ drive->service_time = jiffies - drive->service_start;
+ enable_irq(hwif->irq);
+ spin_lock_irq(&ide_lock);
+ if (startstop == ide_stopped)
+ hwgroup->busy = 0;
+ }
+ }
+ ide_do_request(hwgroup, 0);
+ spin_unlock_irqrestore(&ide_lock, flags);
+}
+
+EXPORT_SYMBOL(ide_timer_expiry);
+
+/**
+ * unexpected_intr - handle an unexpected IDE interrupt
+ * @irq: interrupt line
+ * @hwgroup: hwgroup being processed
+ *
+ * There's nothing really useful we can do with an unexpected interrupt,
+ * other than reading the status register (to clear it), and logging it.
+ * There should be no way that an irq can happen before we're ready for it,
+ * so we needn't worry much about losing an "important" interrupt here.
+ *
+ * On laptops (and "green" PCs), an unexpected interrupt occurs whenever
+ * the drive enters "idle", "standby", or "sleep" mode, so if the status
+ * looks "good", we just ignore the interrupt completely.
+ *
+ * This routine assumes __cli() is in effect when called.
+ *
+ * If an unexpected interrupt happens on irq15 while we are handling irq14
+ * and if the two interfaces are "serialized" (CMD640), then it looks like
+ * we could screw up by interfering with a new request being set up for
+ * irq15.
+ *
+ * In reality, this is a non-issue. The new command is not sent unless
+ * the drive is ready to accept one, in which case we know the drive is
+ * not trying to interrupt us. And ide_set_handler() is always invoked
+ * before completing the issuance of any new drive command, so we will not
+ * be accidentally invoked as a result of any valid command completion
+ * interrupt.
+ *
+ * Note that we must walk the entire hwgroup here. We know which hwif
+ * is doing the current command, but we don't know which hwif burped
+ * mysteriously.
+ */
+
+static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
+{
+ u8 stat;
+ ide_hwif_t *hwif = hwgroup->hwif;
+
+ /*
+ * handle the unexpected interrupt
+ */
+ do {
+ if (hwif->irq == irq) {
+ stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+ if (!OK_STAT(stat, READY_STAT, BAD_STAT)) {
+ /* Try to not flood the console with msgs */
+ static unsigned long last_msgtime, count;
+ ++count;
+ if (time_after(jiffies, last_msgtime + HZ)) {
+ last_msgtime = jiffies;
+ printk(KERN_ERR "%s%s: unexpected interrupt, "
+ "status=0x%02x, count=%ld\n",
+ hwif->name,
+ (hwif->next==hwgroup->hwif) ? "" : "(?)", stat, count);
+ }
+ }
+ }
+ } while ((hwif = hwif->next) != hwgroup->hwif);
+}
+
+/**
+ * ide_intr - default IDE interrupt handler
+ * @irq: interrupt number
+ * @dev_id: hwif group
+ * @regs: unused weirdness from the kernel irq layer
+ *
+ * This is the default IRQ handler for the IDE layer. You should
+ * not need to override it. If you do be aware it is subtle in
+ * places
+ *
+ * hwgroup->hwif is the interface in the group currently performing
+ * a command. hwgroup->drive is the drive and hwgroup->handler is
+ * the IRQ handler to call. As we issue a command the handlers
+ * step through multiple states, reassigning the handler to the
+ * next step in the process. Unlike a smart SCSI controller IDE
+ * expects the main processor to sequence the various transfer
+ * stages. We also manage a poll timer to catch up with most
+ * timeout situations. There are still a few where the handlers
+ * don't ever decide to give up.
+ *
+ * The handler eventually returns ide_stopped to indicate the
+ * request completed. At this point we issue the next request
+ * on the hwgroup and the process begins again.
+ */
+
+void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned long flags;
+ ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id;
+ ide_hwif_t *hwif;
+ ide_drive_t *drive;
+ ide_handler_t *handler;
+ ide_startstop_t startstop;
+
+ spin_lock_irqsave(&ide_lock, flags);
+ hwif = hwgroup->hwif;
+
+ if (!ide_ack_intr(hwif)) {
+ spin_unlock_irqrestore(&ide_lock, flags);
+ return;
+ }
+
+ if ((handler = hwgroup->handler) == NULL ||
+ hwgroup->poll_timeout != 0) {
+ /*
+ * Not expecting an interrupt from this drive.
+ * That means this could be:
+ * (1) an interrupt from another PCI device
+ * sharing the same PCI INT# as us.
+ * or (2) a drive just entered sleep or standby mode,
+ * and is interrupting to let us know.
+ * or (3) a spurious interrupt of unknown origin.
+ *
+ * For PCI, we cannot tell the difference,
+ * so in that case we just ignore it and hope it goes away.
+ *
+ * FIXME: unexpected_intr should be hwif-> then we can
+ * remove all the ifdef PCI crap
+ */
+#ifdef CONFIG_BLK_DEV_IDEPCI
+ if (hwif->pci_dev && !hwif->pci_dev->vendor)
+#endif /* CONFIG_BLK_DEV_IDEPCI */
+ {
+ /*
+ * Probably not a shared PCI interrupt,
+ * so we can safely try to do something about it:
+ */
+ unexpected_intr(irq, hwgroup);
+#ifdef CONFIG_BLK_DEV_IDEPCI
+ } else {
+ /*
+ * Whack the status register, just in case
+ * we have a leftover pending IRQ.
+ */
+ (void) hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+#endif /* CONFIG_BLK_DEV_IDEPCI */
+ }
+ spin_unlock_irqrestore(&ide_lock, flags);
+ return;
+ }
+ drive = hwgroup->drive;
+ if (!drive) {
+ /*
+ * This should NEVER happen, and there isn't much
+ * we could do about it here.
+ *
+ * [Note - this can occur if the drive is hot unplugged]
+ */
+ spin_unlock_irqrestore(&ide_lock, flags);
+ return;
+ }
+ if (!drive_is_ready(drive)) {
+ /*
+ * This happens regularly when we share a PCI IRQ with
+ * another device. Unfortunately, it can also happen
+ * with some buggy drives that trigger the IRQ before
+ * their status register is up to date. Hopefully we have
+ * enough advance overhead that the latter isn't a problem.
+ */
+ spin_unlock_irqrestore(&ide_lock, flags);
+ return;
+ }
+ if (!hwgroup->busy) {
+ hwgroup->busy = 1; /* paranoia */
+ printk(KERN_ERR "%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name);
+ }
+ hwgroup->handler = NULL;
+ del_timer(&hwgroup->timer);
+ spin_unlock(&ide_lock);
+
+ if (drive->unmask)
+ local_irq_enable();
+ /* service this interrupt, may set handler for next interrupt */
+ startstop = handler(drive);
+ spin_lock_irq(&ide_lock);
+
+ /*
+ * Note that handler() may have set things up for another
+ * interrupt to occur soon, but it cannot happen until
+ * we exit from this routine, because it will be the
+ * same irq as is currently being serviced here, and Linux
+ * won't allow another of the same (on any CPU) until we return.
+ */
+ set_recovery_timer(HWIF(drive));
+ drive->service_time = jiffies - drive->service_start;
+ if (startstop == ide_stopped) {
+ if (hwgroup->handler == NULL) { /* paranoia */
+ hwgroup->busy = 0;
+ ide_do_request(hwgroup, hwif->irq);
+ } else {
+ printk(KERN_ERR "%s: ide_intr: huh? expected NULL handler "
+ "on exit\n", drive->name);
+ }
+ }
+ spin_unlock_irqrestore(&ide_lock, flags);
+}
+
+EXPORT_SYMBOL(ide_intr);
+
+/**
+ * ide_init_drive_cmd - initialize a drive command request
+ * @rq: request object
+ *
+ * Initialize a request before we fill it in and send it down to
+ * ide_do_drive_cmd. Commands must be set up by this function. Right
+ * now it doesn't do a lot, but if that changes abusers will have a
+ * nasty suprise.
+ */
+
+void ide_init_drive_cmd (struct request *rq)
+{
+ memset(rq, 0, sizeof(*rq));
+ rq->flags = REQ_DRIVE_CMD;
+}
+
+EXPORT_SYMBOL(ide_init_drive_cmd);
+
+/**
+ * ide_do_drive_cmd - issue IDE special command
+ * @drive: device to issue command
+ * @rq: request to issue
+ * @action: action for processing
+ *
+ * This function issues a special IDE device request
+ * onto the request queue.
+ *
+ * If action is ide_wait, then the rq is queued at the end of the
+ * request queue, and the function sleeps until it has been processed.
+ * This is for use when invoked from an ioctl handler.
+ *
+ * If action is ide_preempt, then the rq is queued at the head of
+ * the request queue, displacing the currently-being-processed
+ * request and this function returns immediately without waiting
+ * for the new rq to be completed. This is VERY DANGEROUS, and is
+ * intended for careful use by the ATAPI tape/cdrom driver code.
+ *
+ * If action is ide_next, then the rq is queued immediately after
+ * the currently-being-processed-request (if any), and the function
+ * returns without waiting for the new rq to be completed. As above,
+ * This is VERY DANGEROUS, and is intended for careful use by the
+ * ATAPI tape/cdrom driver code.
+ *
+ * If action is ide_end, then the rq is queued at the end of the
+ * request queue, and the function returns immediately without waiting
+ * for the new rq to be completed. This is again intended for careful
+ * use by the ATAPI tape/cdrom driver code.
+ */
+
+int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action)
+{
+ unsigned long flags;
+ ide_hwgroup_t *hwgroup = HWGROUP(drive);
+ DECLARE_COMPLETION(wait);
+ int insert_end = 1, err;
+
+#ifdef CONFIG_BLK_DEV_PDC4030
+ /*
+ * FIXME: there should be a drive or hwif->special
+ * handler that points here by default, not hacks
+ * in the ide-io.c code
+ */
+ if (HWIF(drive)->chipset == ide_pdc4030 && rq->buffer != NULL)
+ return -ENOSYS; /* special drive cmds not supported */
+#endif
+ rq->errors = 0;
+ rq->rq_status = RQ_ACTIVE;
+
+ rq->rq_disk = drive->disk;
+
+ /*
+ * we need to hold an extra reference to request for safe inspection
+ * after completion
+ */
+ if (action == ide_wait) {
+ rq->ref_count++;
+ rq->waiting = &wait;
+ }
+
+ spin_lock_irqsave(&ide_lock, flags);
+ if (action == ide_preempt) {
+ hwgroup->rq = NULL;
+ insert_end = 0;
+ }
+ __elv_add_request(&drive->queue, rq, insert_end, 0);
+ ide_do_request(hwgroup, 0);
+ spin_unlock_irqrestore(&ide_lock, flags);
+
+ err = 0;
+ if (action == ide_wait) {
+ wait_for_completion(&wait);
+ if (rq->errors)
+ err = -EIO;
+
+ blk_put_request(rq);
+ }
+
+ return err;
+}
+
+EXPORT_SYMBOL(ide_do_drive_cmd);
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index dabb04e4f867..3798c35fd601 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -57,14 +57,14 @@ static void ide_insl (ide_ioreg_t port, void *addr, u32 count)
insl(port, addr, count);
}
-static void ide_outb (u8 addr, ide_ioreg_t port)
+static void ide_outb (u8 value, ide_ioreg_t port)
{
- outb(addr, port);
+ outb(value, port);
}
-static void ide_outw (u16 addr, ide_ioreg_t port)
+static void ide_outw (u16 value, ide_ioreg_t port)
{
- outw(addr, port);
+ outw(value, port);
}
static void ide_outsw (ide_ioreg_t port, void *addr, u32 count)
@@ -72,14 +72,14 @@ static void ide_outsw (ide_ioreg_t port, void *addr, u32 count)
outsw(port, addr, count);
}
-static void ide_outl (u32 addr, ide_ioreg_t port)
+static void ide_outl (u32 value, ide_ioreg_t port)
{
- outl(addr, port);
+ outl(value, port);
}
static void ide_outsl (ide_ioreg_t port, void *addr, u32 count)
{
- return outsl(port, addr, count);
+ outsl(port, addr, count);
}
void default_hwif_iops (ide_hwif_t *hwif)
@@ -819,9 +819,9 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed)
// while (HWGROUP(drive)->busy)
// ide_delay_50ms();
-#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
+#if !defined(CONFIG_DMA_NONPCI)
hwif->ide_dma_host_off(drive);
-#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */
+#endif /* !(CONFIG_DMA_NONPCI) */
/*
* Don't use ide_wait_cmd here - it will
@@ -887,12 +887,12 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed)
drive->id->dma_mword &= ~0x0F00;
drive->id->dma_1word &= ~0x0F00;
-#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
+#if !defined(CONFIG_DMA_NONPCI)
if (speed >= XFER_SW_DMA_0)
hwif->ide_dma_host_on(drive);
else
hwif->ide_dma_off(drive);
-#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */
+#endif /* !(CONFIG_DMA_NONPCI) */
switch(speed) {
case XFER_UDMA_7: drive->id->dma_ultra |= 0x8080; break;
@@ -1057,8 +1057,7 @@ void check_dma_crc (ide_drive_t *drive)
{
if (drive->crc_count) {
(void) HWIF(drive)->ide_dma_off_quietly(drive);
- if ((HWIF(drive)->speedproc) != NULL)
- HWIF(drive)->speedproc(drive, ide_auto_reduce_xfer(drive));
+ ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive));
if (drive->current_speed >= XFER_SW_DMA_0)
(void) HWIF(drive)->ide_dma_on(drive);
} else {
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 70db6da59545..815930c41b5b 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -300,7 +300,7 @@ static int ide_scan_pio_blacklist (char *model)
}
/**
- * ide_get_best_pio_mode - get PIO mode fro drive
+ * ide_get_best_pio_mode - get PIO mode from drive
* @driver: drive to consider
* @mode_wanted: preferred mode
* @max_mode: highest allowed
@@ -387,6 +387,15 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_p
EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
+/**
+ * ide_toggle_bounce - handle bounce buffering
+ * @drive: drive to update
+ * @on: on/off boolean
+ *
+ * Enable or disable bounce buffering for the device. Drives move
+ * between PIO and DMA and that changes the rules we need.
+ */
+
void ide_toggle_bounce(ide_drive_t *drive, int on)
{
u64 addr = BLK_BOUNCE_HIGH; /* dma64_addr_t */
@@ -402,3 +411,28 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
}
EXPORT_SYMBOL(ide_toggle_bounce);
+
+/**
+ * ide_set_xfer_rate - set transfer rate
+ * @drive: drive to set
+ * @speed: speed to attempt to set
+ *
+ * General helper for setting the speed of an IDE device. This
+ * function knows about user enforced limits from the configuration
+ * which speedproc() does not. High level drivers should never
+ * invoke speedproc() directly.
+ */
+
+int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
+{
+#ifndef CONFIG_BLK_DEV_IDEDMA
+ rate = min(rate, (u8) XFER_PIO_4);
+#endif
+ if(HWIF(drive)->speedproc)
+ return HWIF(drive)->speedproc(drive, rate);
+ else
+ return -1;
+}
+
+EXPORT_SYMBOL_GPL(ide_set_xfer_rate);
+
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 21bd08a4db90..5a8f40da8a88 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -144,6 +144,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
id->model[sizeof(id->model)-1] = '\0';
printk("%s: %s, ", drive->name, id->model);
drive->present = 1;
+ drive->dead = 0;
/*
* Check for an ATAPI device
@@ -546,8 +547,24 @@ static inline u8 probe_for_drive (ide_drive_t *drive)
return 1;
}
-#define hwif_check_region(addr, num) \
- ((hwif->mmio) ? check_mem_region((addr),(num)) : check_region((addr),(num)))
+static int hwif_check_region(ide_hwif_t *hwif, unsigned long addr, int num)
+{
+ int err;
+
+ if(hwif->mmio)
+ err = check_mem_region(addr, num);
+ else
+ err = check_region(addr, num);
+
+ if(err)
+ {
+ printk("%s: %s resource 0x%lX-0x%lX not free.\n",
+ hwif->name, hwif->mmio?"MMIO":"I/O", addr, addr+num-1);
+ mdelay(2000);
+ }
+ return err;
+}
+
static int hwif_check_regions (ide_hwif_t *hwif)
{
@@ -556,14 +573,14 @@ static int hwif_check_regions (ide_hwif_t *hwif)
if (hwif->mmio == 2)
return 0;
- addr_errs = hwif_check_region(hwif->io_ports[IDE_DATA_OFFSET], 1);
+ addr_errs = hwif_check_region(hwif, hwif->io_ports[IDE_DATA_OFFSET], 1);
for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET; i++)
- addr_errs += hwif_check_region(hwif->io_ports[i], 1);
+ addr_errs += hwif_check_region(hwif, hwif->io_ports[i], 1);
if (hwif->io_ports[IDE_CONTROL_OFFSET])
- addr_errs += hwif_check_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
+ addr_errs += hwif_check_region(hwif, hwif->io_ports[IDE_CONTROL_OFFSET], 1);
#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
if (hwif->io_ports[IDE_IRQ_OFFSET])
- addr_errs += hwif_check_region(hwif->io_ports[IDE_IRQ_OFFSET], 1);
+ addr_errs += hwif_check_region(hwif, hwif->io_ports[IDE_IRQ_OFFSET], 1);
#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
/* If any errors are return, we drop the hwif interface. */
hwif->straight8 = 0;
@@ -629,7 +646,7 @@ void probe_hwif (ide_hwif_t *hwif)
}
#endif
- if ((hwif->chipset != ide_4drives || !hwif->mate->present) &&
+ if ((hwif->chipset != ide_4drives || !hwif->mate || !hwif->mate->present) &&
#if CONFIG_BLK_DEV_PDC4030
(hwif->chipset != ide_pdc4030 || hwif->channel == 0) &&
#endif /* CONFIG_BLK_DEV_PDC4030 */
@@ -655,6 +672,13 @@ void probe_hwif (ide_hwif_t *hwif)
* we'll install our IRQ driver much later...
*/
irqd = hwif->irq;
+
+ if (irqd >= NR_IRQS)
+ {
+ printk(KERN_ERR "***WARNING***: Bogus interrupt reported. Probably a bug in the Linux ACPI\n");
+ printk(KERN_ERR "***WARNING***: Attempting to continue as best we can.\n");
+ irqd = 0;
+ }
if (irqd)
disable_irq(hwif->irq);
@@ -1058,6 +1082,7 @@ static void init_gendisk (ide_hwif_t *hwif)
"%s","IDE Drive");
drive->gendev.parent = &hwif->gendev;
drive->gendev.bus = &ide_bus_type;
+ drive->gendev.driver_data = drive;
sprintf (name, "ide/host%d/bus%d/target%d/lun%d",
(hwif->channel && hwif->mate) ?
hwif->mate->index : hwif->index,
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 4da916c26243..0a3c9d65591e 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1450,7 +1450,6 @@ static void idetape_output_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsign
}
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
static void idetape_update_buffers (idetape_pc_t *pc)
{
struct bio *bio = pc->bio;
@@ -1475,7 +1474,6 @@ static void idetape_update_buffers (idetape_pc_t *pc)
}
pc->bio = bio;
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
/*
* idetape_next_pc_storage returns a pointer to a place in which we can
@@ -1580,7 +1578,6 @@ static void idetape_analyze_error (ide_drive_t *drive, idetape_request_sense_res
ide_stall_queue(drive, HZ / 2);
return;
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
/*
* Correct pc->actually_transferred by asking the tape.
@@ -1589,7 +1586,7 @@ static void idetape_analyze_error (ide_drive_t *drive, idetape_request_sense_res
pc->actually_transferred = pc->request_transfer - tape->tape_block_size * ntohl(get_unaligned(&result->information));
idetape_update_buffers(pc);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+
if (pc->c[0] == IDETAPE_READ_CMD && result->filemark) {
pc->error = IDETAPE_ERROR_FILEMARK;
set_bit(PC_ABORT, &pc->flags);
@@ -1982,7 +1979,6 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
/* Clear the interrupt */
status.all = HWIF(drive)->INB(IDE_STATUS_REG);
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
if (HWIF(drive)->ide_dma_end(drive)) {
/*
@@ -2006,7 +2002,6 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
printk(KERN_INFO "ide-tape: DMA finished\n");
#endif /* IDETAPE_DEBUG_LOG */
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
/* No more interrupts */
if (!status.b.drq) {
@@ -2061,7 +2056,6 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
tape->failed_pc = NULL;
return pc->callback(drive); /* Command finished - Call the callback function */
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
printk(KERN_ERR "ide-tape: The tape wants to issue more "
"interrupts in DMA mode\n");
@@ -2069,7 +2063,6 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
(void) HWIF(drive)->ide_dma_off(drive);
return ide_do_reset(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
bcount.b.high = IN_BYTE(IDE_BCOUNTH_REG); /* Get the number of bytes to transfer */
bcount.b.low = IN_BYTE(IDE_BCOUNTL_REG); /* on this interrupt */
ireason.all = IN_BYTE(IDE_IREASON_REG);
@@ -2264,7 +2257,6 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
pc->current_position = pc->buffer;
bcount.all = pc->request_transfer; /* Request to transfer the entire buffer at once */
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) {
printk(KERN_WARNING "ide-tape: DMA disabled, "
"reverting to PIO\n");
@@ -2276,7 +2268,6 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
else
dma_ok = !HWIF(drive)->ide_dma_read(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl, IDE_CONTROL_REG);
@@ -2284,12 +2275,10 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
OUT_BYTE(bcount.b.high, IDE_BCOUNTH_REG);
OUT_BYTE(bcount.b.low, IDE_BCOUNTL_REG);
OUT_BYTE(drive->select.all, IDE_SELECT_REG);
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (dma_ok) { /* Begin DMA, if necessary */
set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
(void) (HWIF(drive)->ide_dma_begin(drive));
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
if (HWGROUP(drive)->handler != NULL) /* paranoia check */
BUG();
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 88718f375b9d..bbd53867cef3 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -1068,7 +1068,6 @@ ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct h
case DISABLE_SEAGATE:
case EXABYTE_ENABLE_NEST:
return &task_no_data_intr;
-#ifdef CONFIG_BLK_DEV_IDEDMA
case WIN_READDMA:
// case WIN_READDMA_ONCE:
case WIN_IDENTIFY_DMA:
@@ -1080,7 +1079,6 @@ ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct h
case WIN_WRITEDMA_QUEUED:
case WIN_WRITEDMA_EXT:
case WIN_WRITEDMA_QUEUED_EXT:
-#endif
case WIN_FORMAT:
case WIN_INIT:
case WIN_DEVICE_RESET:
@@ -1164,7 +1162,6 @@ int ide_cmd_type_parser (ide_task_t *args)
default:
return IDE_DRIVE_TASK_NO_DATA;
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
case WIN_READDMA:
// case WIN_READDMA_ONCE:
case WIN_IDENTIFY_DMA:
@@ -1178,7 +1175,6 @@ int ide_cmd_type_parser (ide_task_t *args)
case WIN_WRITEDMA_EXT:
case WIN_WRITEDMA_QUEUED_EXT:
return IDE_DRIVE_TASK_RAW_WRITE;
-#endif
case WIN_SETFEATURES:
switch(args->tfRegister[IDE_FEATURE_OFFSET]) {
case SETFEATURES_EN_8BIT:
@@ -1669,8 +1665,7 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
if (!err && xfer_rate) {
/* active-retuning-calls future */
- if ((HWIF(drive)->speedproc) != NULL)
- HWIF(drive)->speedproc(drive, xfer_rate);
+ ide_set_xfer_rate(drive, xfer_rate);
ide_driveid_update(drive);
}
abort:
@@ -1724,8 +1719,7 @@ abort:
if (!err && xfer_rate) {
/* active-retuning-calls future */
- if ((HWIF(drive)->speedproc) != NULL)
- HWIF(drive)->speedproc(drive, xfer_rate);
+ ide_set_xfer_rate(driver, xfer_rate);
ide_driveid_update(drive);
}
abort:
diff --git a/drivers/ide/ide-tcq.c b/drivers/ide/ide-tcq.c
index 275b16b153ad..feff05e8397f 100644
--- a/drivers/ide/ide-tcq.c
+++ b/drivers/ide/ide-tcq.c
@@ -148,14 +148,14 @@ void ide_tcq_intr_timeout(unsigned long data)
ide_hwif_t *hwif = HWIF(drive);
unsigned long flags;
- printk("ide_tcq_intr_timeout: timeout waiting for %s interrupt\n", hwgroup->rq ? "completion" : "service");
+ printk(KERN_ERR "ide_tcq_intr_timeout: timeout waiting for %s interrupt\n", hwgroup->rq ? "completion" : "service");
spin_lock_irqsave(&ide_lock, flags);
if (!hwgroup->busy)
- printk("ide_tcq_intr_timeout: hwgroup not busy\n");
+ printk(KERN_ERR "ide_tcq_intr_timeout: hwgroup not busy\n");
if (hwgroup->handler == NULL)
- printk("ide_tcq_intr_timeout: missing isr!\n");
+ printk(KERN_ERR "ide_tcq_intr_timeout: missing isr!\n");
hwgroup->busy = 1;
spin_unlock_irqrestore(&ide_lock, flags);
@@ -261,7 +261,7 @@ ide_startstop_t ide_service(ide_drive_t *drive)
hwif->OUTB(WIN_QUEUED_SERVICE, IDE_COMMAND_REG);
if (ide_tcq_wait_altstat(drive, &stat, BUSY_STAT)) {
- printk("ide_service: BUSY clear took too long\n");
+ printk(KERN_ERR "ide_service: BUSY clear took too long\n");
ide_dump_status(drive, "ide_service", stat);
ide_tcq_invalidate_queue(drive);
return ide_stopped;
@@ -284,7 +284,7 @@ ide_startstop_t ide_service(ide_drive_t *drive)
feat = hwif->INB(IDE_NSECTOR_REG);
if (feat & REL) {
HWGROUP(drive)->rq = NULL;
- printk("%s: release in service\n", drive->name);
+ printk(KERN_ERR "%s: release in service\n", drive->name);
return ide_stopped;
}
@@ -307,7 +307,7 @@ ide_startstop_t ide_service(ide_drive_t *drive)
return HWIF(drive)->ide_dma_queued_start(drive);
}
- printk("ide_service: missing request for tag %d\n", tag);
+ printk(KERN_ERR "ide_service: missing request for tag %d\n", tag);
spin_unlock_irqrestore(&ide_lock, flags);
return ide_stopped;
}
@@ -347,14 +347,14 @@ ide_startstop_t ide_dmaq_complete(ide_drive_t *drive, struct request *rq, byte s
* must be end of I/O, check status and complete as necessary
*/
if (unlikely(!OK_STAT(stat, READY_STAT, drive->bad_wstat | DRQ_STAT))) {
- printk("ide_dmaq_intr: %s: error status %x\n",drive->name,stat);
+ printk(KERN_ERR "ide_dmaq_intr: %s: error status %x\n",drive->name,stat);
ide_dump_status(drive, "ide_dmaq_complete", stat);
ide_tcq_invalidate_queue(drive);
return ide_stopped;
}
if (dma_stat)
- printk("%s: bad DMA status (dma_stat=%x)\n", drive->name, dma_stat);
+ printk(KERN_WARNING "%s: bad DMA status (dma_stat=%x)\n", drive->name, dma_stat);
TCQ_PRINTK("ide_dmaq_complete: ending %p, tag %d\n", rq, rq->tag);
ide_end_request(drive, 1, rq->nr_sectors);
@@ -465,7 +465,7 @@ static int ide_tcq_configure(ide_drive_t *drive)
args->command_type = ide_cmd_type_parser(args);
if (ide_raw_taskfile(drive, args, NULL)) {
- printk("%s: failed to enable write cache\n", drive->name);
+ printk(KERN_WARNING "%s: failed to enable write cache\n", drive->name);
goto err;
}
@@ -479,7 +479,7 @@ static int ide_tcq_configure(ide_drive_t *drive)
args->command_type = ide_cmd_type_parser(args);
if (ide_raw_taskfile(drive, args, NULL)) {
- printk("%s: disabling release interrupt fail\n", drive->name);
+ printk(KERN_ERR "%s: disabling release interrupt fail\n", drive->name);
goto err;
}
@@ -493,7 +493,7 @@ static int ide_tcq_configure(ide_drive_t *drive)
args->command_type = ide_cmd_type_parser(args);
if (ide_raw_taskfile(drive, args, NULL)) {
- printk("%s: enabling service interrupt fail\n", drive->name);
+ printk(KERN_ERR "%s: enabling service interrupt fail\n", drive->name);
goto err;
}
#endif
@@ -518,7 +518,7 @@ static int ide_enable_queued(ide_drive_t *drive, int on)
*/
if (!on) {
if (drive->using_tcq)
- printk("%s: TCQ disabled\n", drive->name);
+ printk(KERN_INFO "%s: TCQ disabled\n", drive->name);
drive->using_tcq = 0;
return 0;
@@ -541,7 +541,7 @@ static int ide_enable_queued(ide_drive_t *drive, int on)
ide_tcq_check_autopoll(drive);
if (depth != drive->queue_depth)
- printk("%s: tagged command queueing enabled, command queue depth %d\n", drive->name, drive->queue_depth);
+ printk(KERN_INFO "%s: tagged command queueing enabled, command queue depth %d\n", drive->name, drive->queue_depth);
drive->using_tcq = 1;
return 0;
@@ -588,7 +588,7 @@ int __ide_dma_queued_on(ide_drive_t *drive)
return 1;
if (ata_pending_commands(drive)) {
- printk("ide-tcq; can't toggle tcq feature on busy drive\n");
+ printk(KERN_WARNING "ide-tcq; can't toggle tcq feature on busy drive\n");
return 1;
}
@@ -692,10 +692,10 @@ ide_startstop_t __ide_dma_queued_start(ide_drive_t *drive)
TCQ_PRINTK("ide_dma: setting up queued tag=%d\n", rq->tag);
if (!hwgroup->busy)
- printk("queued_rw: hwgroup not busy\n");
+ printk(KERN_ERR "queued_rw: hwgroup not busy\n");
if (ide_tcq_wait_dataphase(drive)) {
- printk("timeout waiting for data phase\n");
+ printk(KERN_WARNING "timeout waiting for data phase\n");
return ide_stopped;
}
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 331967b02ea7..dabd0c660ccc 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -222,37 +222,6 @@ EXPORT_SYMBOL(idefloppy);
EXPORT_SYMBOL(idetape);
EXPORT_SYMBOL(idescsi);
-#if (DISK_RECOVERY_TIME > 0)
-
-Error So the User Has To Fix the Compilation And Stop Hacking Port 0x43
-Does anyone ever use this anyway ??
-
-/*
- * For really screwy hardware (hey, at least it *can* be used with Linux)
- * we can enforce a minimum delay time between successive operations.
- */
-static unsigned long read_timer (ide_hwif_t *hwif)
-{
- unsigned long t, flags;
- int i;
-
- /* FIXME this is completely unsafe! */
- local_irq_save(flags);
- t = jiffies * 11932;
- outb_p(0, 0x43);
- i = inb_p(0x40);
- i |= inb_p(0x40) << 8;
- local_irq_restore(flags);
- return (t - i);
-}
-#endif /* DISK_RECOVERY_TIME */
-
-static inline void set_recovery_timer (ide_hwif_t *hwif)
-{
-#if (DISK_RECOVERY_TIME > 0)
- hwif->last_time = read_timer(hwif);
-#endif /* DISK_RECOVERY_TIME */
-}
/*
* Do not even *think* about calling this!
@@ -310,6 +279,7 @@ static void init_hwif_data (unsigned int index)
drive->max_failures = IDE_DEFAULT_MAX_FAILURES;
drive->using_dma = 0;
drive->is_flash = 0;
+ drive->vdma = 0;
INIT_LIST_HEAD(&drive->list);
}
}
@@ -372,7 +342,7 @@ int ide_system_bus_speed (void)
/* safe default value for VESA and PCI */
system_bus_speed = 50;
}
- printk("ide: Assuming %dMHz system bus speed "
+ printk(KERN_INFO "ide: Assuming %dMHz system bus speed "
"for PIO modes%s\n", system_bus_speed,
idebus_parameter ? "" : "; override with idebus=xx");
}
@@ -380,48 +350,6 @@ int ide_system_bus_speed (void)
}
/*
- * This is our end_request replacement function.
- */
-int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
-{
- struct request *rq;
- unsigned long flags;
- int ret = 1;
-
- spin_lock_irqsave(&ide_lock, flags);
- rq = HWGROUP(drive)->rq;
-
- BUG_ON(!(rq->flags & REQ_STARTED));
-
- if (!nr_sectors)
- nr_sectors = rq->hard_cur_sectors;
-
- /*
- * decide whether to reenable DMA -- 3 is a random magic for now,
- * if we DMA timeout more than 3 times, just stay in PIO
- */
- if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
- drive->state = 0;
- HWGROUP(drive)->hwif->ide_dma_on(drive);
- }
-
- if (!end_that_request_first(rq, uptodate, nr_sectors)) {
- add_disk_randomness(rq->rq_disk);
- if (!blk_rq_tagged(rq))
- blkdev_dequeue_request(rq);
- else
- blk_queue_end_tag(&drive->queue, rq);
- HWGROUP(drive)->rq = NULL;
- end_that_request_last(rq);
- ret = 0;
- }
- spin_unlock_irqrestore(&ide_lock, flags);
- return ret;
-}
-
-EXPORT_SYMBOL(ide_end_request);
-
-/*
* current_capacity() returns the capacity (in sectors) of a drive
* according to its current geometry/LBA settings.
*/
@@ -444,82 +372,6 @@ static inline u32 read_24 (ide_drive_t *drive)
}
/*
- * Clean up after success/failure of an explicit drive cmd
- */
-void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
-{
- ide_hwif_t *hwif = HWIF(drive);
- unsigned long flags;
- struct request *rq;
-
- spin_lock_irqsave(&ide_lock, flags);
- rq = HWGROUP(drive)->rq;
- spin_unlock_irqrestore(&ide_lock, flags);
-
- if (rq->flags & REQ_DRIVE_CMD) {
- u8 *args = (u8 *) rq->buffer;
- if (rq->errors == 0)
- rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-
- if (args) {
- args[0] = stat;
- args[1] = err;
- args[2] = hwif->INB(IDE_NSECTOR_REG);
- }
- } else if (rq->flags & REQ_DRIVE_TASK) {
- u8 *args = (u8 *) rq->buffer;
- if (rq->errors == 0)
- rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-
- if (args) {
- args[0] = stat;
- args[1] = err;
- args[2] = hwif->INB(IDE_NSECTOR_REG);
- args[3] = hwif->INB(IDE_SECTOR_REG);
- args[4] = hwif->INB(IDE_LCYL_REG);
- args[5] = hwif->INB(IDE_HCYL_REG);
- args[6] = hwif->INB(IDE_SELECT_REG);
- }
- } else if (rq->flags & REQ_DRIVE_TASKFILE) {
- ide_task_t *args = (ide_task_t *) rq->special;
- if (rq->errors == 0)
- rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-
- if (args) {
- if (args->tf_in_flags.b.data) {
- u16 data = hwif->INW(IDE_DATA_REG);
- args->tfRegister[IDE_DATA_OFFSET] = (data) & 0xFF;
- args->hobRegister[IDE_DATA_OFFSET_HOB] = (data >> 8) & 0xFF;
- }
- args->tfRegister[IDE_ERROR_OFFSET] = err;
- args->tfRegister[IDE_NSECTOR_OFFSET] = hwif->INB(IDE_NSECTOR_REG);
- args->tfRegister[IDE_SECTOR_OFFSET] = hwif->INB(IDE_SECTOR_REG);
- args->tfRegister[IDE_LCYL_OFFSET] = hwif->INB(IDE_LCYL_REG);
- args->tfRegister[IDE_HCYL_OFFSET] = hwif->INB(IDE_HCYL_REG);
- args->tfRegister[IDE_SELECT_OFFSET] = hwif->INB(IDE_SELECT_REG);
- args->tfRegister[IDE_STATUS_OFFSET] = stat;
-
- if (drive->addressing == 1) {
- hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG_HOB);
- args->hobRegister[IDE_FEATURE_OFFSET_HOB] = hwif->INB(IDE_FEATURE_REG);
- args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = hwif->INB(IDE_NSECTOR_REG);
- args->hobRegister[IDE_SECTOR_OFFSET_HOB] = hwif->INB(IDE_SECTOR_REG);
- args->hobRegister[IDE_LCYL_OFFSET_HOB] = hwif->INB(IDE_LCYL_REG);
- args->hobRegister[IDE_HCYL_OFFSET_HOB] = hwif->INB(IDE_HCYL_REG);
- }
- }
- }
-
- spin_lock_irqsave(&ide_lock, flags);
- blkdev_dequeue_request(rq);
- HWGROUP(drive)->rq = NULL;
- end_that_request_last(rq);
- spin_unlock_irqrestore(&ide_lock, flags);
-}
-
-EXPORT_SYMBOL(ide_end_drive_cmd);
-
-/*
* Error reporting, in human readable form (luxurious, but a memory hog).
*/
u8 ide_dump_status (ide_drive_t *drive, const char *msg, u8 stat)
@@ -529,7 +381,7 @@ u8 ide_dump_status (ide_drive_t *drive, const char *msg, u8 stat)
u8 err = 0;
local_irq_set(flags);
- printk("%s: %s: status=0x%02x", drive->name, msg, stat);
+ printk(KERN_WARNING "%s: %s: status=0x%02x", drive->name, msg, stat);
#if FANCY_STATUS_DUMPS
printk(" { ");
if (stat & BUSY_STAT) {
@@ -602,967 +454,7 @@ u8 ide_dump_status (ide_drive_t *drive, const char *msg, u8 stat)
EXPORT_SYMBOL(ide_dump_status);
-/*
- * try_to_flush_leftover_data() is invoked in response to a drive
- * unexpectedly having its DRQ_STAT bit set. As an alternative to
- * resetting the drive, this routine tries to clear the condition
- * by read a sector's worth of data from the drive. Of course,
- * this may not help if the drive is *waiting* for data from *us*.
- */
-void try_to_flush_leftover_data (ide_drive_t *drive)
-{
- int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS;
-
- if (drive->media != ide_disk)
- return;
- while (i > 0) {
- u32 buffer[16];
- u32 wcount = (i > 16) ? 16 : i;
-
- i -= wcount;
- HWIF(drive)->ata_input_data(drive, buffer, wcount);
- }
-}
-
-EXPORT_SYMBOL(try_to_flush_leftover_data);
-
-/*
- * FIXME Add an ATAPI error
- */
-
-/*
- * ide_error() takes action based on the error returned by the drive.
- */
-ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat)
-{
- ide_hwif_t *hwif;
- struct request *rq;
- u8 err;
-
- err = ide_dump_status(drive, msg, stat);
- if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
- return ide_stopped;
-
- hwif = HWIF(drive);
- /* retry only "normal" I/O: */
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
- rq->errors = 1;
- ide_end_drive_cmd(drive, stat, err);
- return ide_stopped;
- }
- if (rq->flags & REQ_DRIVE_TASKFILE) {
- rq->errors = 1;
- ide_end_drive_cmd(drive, stat, err);
-// ide_end_taskfile(drive, stat, err);
- return ide_stopped;
- }
-
- if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) {
- /* other bits are useless when BUSY */
- rq->errors |= ERROR_RESET;
- } else {
- if (drive->media != ide_disk)
- goto media_out;
-
- if (stat & ERR_STAT) {
- /* err has different meaning on cdrom and tape */
- if (err == ABRT_ERR) {
- if (drive->select.b.lba &&
- (hwif->INB(IDE_COMMAND_REG) == WIN_SPECIFY))
- /* some newer drives don't
- * support WIN_SPECIFY
- */
- return ide_stopped;
- } else if ((err & BAD_CRC) == BAD_CRC) {
- drive->crc_count++;
- /* UDMA crc error -- just retry the operation */
- } else if (err & (BBD_ERR | ECC_ERR)) {
- /* retries won't help these */
- rq->errors = ERROR_MAX;
- } else if (err & TRK0_ERR) {
- /* help it find track zero */
- rq->errors |= ERROR_RECAL;
- }
- }
-media_out:
- if ((stat & DRQ_STAT) && rq_data_dir(rq) != WRITE)
- try_to_flush_leftover_data(drive);
- }
- if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) {
- /* force an abort */
- hwif->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
- }
- if (rq->errors >= ERROR_MAX) {
- if (drive->driver != NULL)
- DRIVER(drive)->end_request(drive, 0, 0);
- else
- ide_end_request(drive, 0, 0);
- } else {
- if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
- ++rq->errors;
- return ide_do_reset(drive);
- }
- if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
- drive->special.b.recalibrate = 1;
- ++rq->errors;
- }
- return ide_stopped;
-}
-
-EXPORT_SYMBOL(ide_error);
-
-/*
- * Issue a simple drive command
- * The drive must be selected beforehand.
- */
-void ide_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, ide_handler_t *handler)
-{
- ide_hwif_t *hwif = HWIF(drive);
- if (HWGROUP(drive)->handler != NULL)
- BUG();
- ide_set_handler(drive, handler, WAIT_CMD, NULL);
- if (IDE_CONTROL_REG)
- hwif->OUTB(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */
- SELECT_MASK(drive,0);
- hwif->OUTB(nsect,IDE_NSECTOR_REG);
- hwif->OUTB(cmd,IDE_COMMAND_REG);
-}
-
-EXPORT_SYMBOL(ide_cmd);
-
-/*
- * drive_cmd_intr() is invoked on completion of a special DRIVE_CMD.
- */
-ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
-{
- struct request *rq = HWGROUP(drive)->rq;
- ide_hwif_t *hwif = HWIF(drive);
- u8 *args = (u8 *) rq->buffer;
- u8 stat = hwif->INB(IDE_STATUS_REG);
- int retries = 10;
-
- local_irq_enable();
- if ((stat & DRQ_STAT) && args && args[3]) {
- u8 io_32bit = drive->io_32bit;
- drive->io_32bit = 0;
- hwif->ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS);
- drive->io_32bit = io_32bit;
- while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
- udelay(100);
- }
-
- if (!OK_STAT(stat, READY_STAT, BAD_STAT))
- return DRIVER(drive)->error(drive, "drive_cmd", stat);
- /* calls ide_end_drive_cmd */
- ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
- return ide_stopped;
-}
-
-EXPORT_SYMBOL(drive_cmd_intr);
-
-/*
- * do_special() is used to issue WIN_SPECIFY, WIN_RESTORE, and WIN_SETMULT
- * commands to a drive. It used to do much more, but has been scaled back.
- */
-ide_startstop_t do_special (ide_drive_t *drive)
-{
- special_t *s = &drive->special;
-
-#ifdef DEBUG
- printk("%s: do_special: 0x%02x\n", drive->name, s->all);
-#endif
- if (s->b.set_tune) {
- s->b.set_tune = 0;
- if (HWIF(drive)->tuneproc != NULL)
- HWIF(drive)->tuneproc(drive, drive->tune_req);
- } else if (drive->driver != NULL) {
- return DRIVER(drive)->special(drive);
- } else if (s->all) {
- printk("%s: bad special flag: 0x%02x\n", drive->name, s->all);
- s->all = 0;
- }
- return ide_stopped;
-}
-
-EXPORT_SYMBOL(do_special);
-
-/*
- * execute_drive_cmd() issues a special drive command,
- * usually initiated by ioctl() from the external hdparm program.
- */
-ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq)
-{
- ide_hwif_t *hwif = HWIF(drive);
- if (rq->flags & REQ_DRIVE_TASKFILE) {
- ide_task_t *args = rq->special;
-
- if (!args)
- goto done;
-
- if (args->tf_out_flags.all != 0)
- return flagged_taskfile(drive, args);
- return do_rw_taskfile(drive, args);
- } else if (rq->flags & REQ_DRIVE_TASK) {
- u8 *args = rq->buffer;
- u8 sel;
-
- if (!args)
- goto done;
-#ifdef DEBUG
- printk("%s: DRIVE_TASK_CMD ", drive->name);
- printk("cmd=0x%02x ", args[0]);
- printk("fr=0x%02x ", args[1]);
- printk("ns=0x%02x ", args[2]);
- printk("sc=0x%02x ", args[3]);
- printk("lcyl=0x%02x ", args[4]);
- printk("hcyl=0x%02x ", args[5]);
- printk("sel=0x%02x\n", args[6]);
-#endif
- hwif->OUTB(args[1], IDE_FEATURE_REG);
- hwif->OUTB(args[3], IDE_SECTOR_REG);
- hwif->OUTB(args[4], IDE_LCYL_REG);
- hwif->OUTB(args[5], IDE_HCYL_REG);
- sel = (args[6] & ~0x10);
- if (drive->select.b.unit)
- sel |= 0x10;
- hwif->OUTB(sel, IDE_SELECT_REG);
- ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
- return ide_started;
- } else if (rq->flags & REQ_DRIVE_CMD) {
- u8 *args = rq->buffer;
-
- if (!args)
- goto done;
-#ifdef DEBUG
- printk("%s: DRIVE_CMD ", drive->name);
- printk("cmd=0x%02x ", args[0]);
- printk("sc=0x%02x ", args[1]);
- printk("fr=0x%02x ", args[2]);
- printk("xx=0x%02x\n", args[3]);
-#endif
- if (args[0] == WIN_SMART) {
- hwif->OUTB(0x4f, IDE_LCYL_REG);
- hwif->OUTB(0xc2, IDE_HCYL_REG);
- hwif->OUTB(args[2],IDE_FEATURE_REG);
- hwif->OUTB(args[1],IDE_SECTOR_REG);
- ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
- return ide_started;
- }
- hwif->OUTB(args[2],IDE_FEATURE_REG);
- ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
- return ide_started;
- }
-
-done:
- /*
- * NULL is actually a valid way of waiting for
- * all current requests to be flushed from the queue.
- */
-#ifdef DEBUG
- printk("%s: DRIVE_CMD (null)\n", drive->name);
-#endif
- ide_end_drive_cmd(drive,
- hwif->INB(IDE_STATUS_REG),
- hwif->INB(IDE_ERROR_REG));
- return ide_stopped;
-}
-
-EXPORT_SYMBOL(execute_drive_cmd);
-
-/*
- * start_request() initiates handling of a new I/O request
- * needed to reverse the perverted changes anonymously made back
- * 2.3.99-pre6
- */
-ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
-{
- ide_startstop_t startstop;
- unsigned long block;
-
- BUG_ON(!(rq->flags & REQ_STARTED));
-
-#ifdef DEBUG
- printk("%s: start_request: current=0x%08lx\n",
- HWIF(drive)->name, (unsigned long) rq);
-#endif
-
- /* bail early if we've exceeded max_failures */
- if (drive->max_failures && (drive->failures > drive->max_failures)) {
- goto kill_rq;
- }
-
- /*
- * bail early if we've sent a device to sleep, however how to wake
- * this needs to be a masked flag. FIXME for proper operations.
- */
- if (drive->suspend_reset)
- goto kill_rq;
-
- block = rq->sector;
- if (blk_fs_request(rq) &&
- (drive->media == ide_disk || drive->media == ide_floppy)) {
- block += drive->sect0;
- }
- /* Yecch - this will shift the entire interval,
- possibly killing some innocent following sector */
- if (block == 0 && drive->remap_0_to_1 == 1)
- block = 1; /* redirect MBR access to EZ-Drive partn table */
-
-#if (DISK_RECOVERY_TIME > 0)
- while ((read_timer() - HWIF(drive)->last_time) < DISK_RECOVERY_TIME);
-#endif
-
- SELECT_DRIVE(drive);
- if (ide_wait_stat(&startstop, drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) {
- printk("%s: drive not ready for command\n", drive->name);
- return startstop;
- }
- if (!drive->special.all) {
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK))
- return execute_drive_cmd(drive, rq);
- else if (rq->flags & REQ_DRIVE_TASKFILE)
- return execute_drive_cmd(drive, rq);
-
- if (drive->driver != NULL) {
- return (DRIVER(drive)->do_request(drive, rq, block));
- }
- printk("%s: media type %d not supported\n", drive->name, drive->media);
- goto kill_rq;
- }
- return do_special(drive);
-kill_rq:
- if (drive->driver != NULL)
- DRIVER(drive)->end_request(drive, 0, 0);
- else
- ide_end_request(drive, 0, 0);
- return ide_stopped;
-}
-
-EXPORT_SYMBOL(start_request);
-
-int restart_request (ide_drive_t *drive, struct request *rq)
-{
- (void) start_request(drive, rq);
- return 0;
-}
-
-EXPORT_SYMBOL(restart_request);
-
-/*
- * ide_stall_queue() can be used by a drive to give excess bandwidth back
- * to the hwgroup by sleeping for timeout jiffies.
- */
-void ide_stall_queue (ide_drive_t *drive, unsigned long timeout)
-{
- if (timeout > WAIT_WORSTCASE)
- timeout = WAIT_WORSTCASE;
- drive->sleep = timeout + jiffies;
-}
-
-EXPORT_SYMBOL(ide_stall_queue);
-
-#define WAKEUP(drive) ((drive)->service_start + 2 * (drive)->service_time)
-
-/*
- * choose_drive() selects the next drive which will be serviced.
- */
-static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup)
-{
- ide_drive_t *drive, *best;
-
-repeat:
- best = NULL;
- drive = hwgroup->drive;
- do {
- if (!blk_queue_empty(&drive->queue) && (!drive->sleep || time_after_eq(jiffies, drive->sleep))) {
- if (!best
- || (drive->sleep && (!best->sleep || 0 < (signed long)(best->sleep - drive->sleep)))
- || (!best->sleep && 0 < (signed long)(WAKEUP(best) - WAKEUP(drive))))
- {
- if (!blk_queue_plugged(&drive->queue))
- best = drive;
- }
- }
- } while ((drive = drive->next) != hwgroup->drive);
- if (best && best->nice1 && !best->sleep && best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) {
- long t = (signed long)(WAKEUP(best) - jiffies);
- if (t >= WAIT_MIN_SLEEP) {
- /*
- * We *may* have some time to spare, but first let's see if
- * someone can potentially benefit from our nice mood today..
- */
- drive = best->next;
- do {
- if (!drive->sleep
- && 0 < (signed long)(WAKEUP(drive) - (jiffies - best->service_time))
- && 0 < (signed long)((jiffies + t) - WAKEUP(drive)))
- {
- ide_stall_queue(best, IDE_MIN(t, 10 * WAIT_MIN_SLEEP));
- goto repeat;
- }
- } while ((drive = drive->next) != best);
- }
- }
- return best;
-}
-
-/*
- * Issue a new request to a drive from hwgroup
- * Caller must have already done spin_lock_irqsave(&ide_lock, ..);
- *
- * A hwgroup is a serialized group of IDE interfaces. Usually there is
- * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640)
- * may have both interfaces in a single hwgroup to "serialize" access.
- * Or possibly multiple ISA interfaces can share a common IRQ by being grouped
- * together into one hwgroup for serialized access.
- *
- * Note also that several hwgroups can end up sharing a single IRQ,
- * possibly along with many other devices. This is especially common in
- * PCI-based systems with off-board IDE controller cards.
- *
- * The IDE driver uses the single global ide_lock spinlock to protect
- * access to the request queues, and to protect the hwgroup->busy flag.
- *
- * The first thread into the driver for a particular hwgroup sets the
- * hwgroup->busy flag to indicate that this hwgroup is now active,
- * and then initiates processing of the top request from the request queue.
- *
- * Other threads attempting entry notice the busy setting, and will simply
- * queue their new requests and exit immediately. Note that hwgroup->busy
- * remains set even when the driver is merely awaiting the next interrupt.
- * Thus, the meaning is "this hwgroup is busy processing a request".
- *
- * When processing of a request completes, the completing thread or IRQ-handler
- * will start the next request from the queue. If no more work remains,
- * the driver will clear the hwgroup->busy flag and exit.
- *
- * The ide_lock (spinlock) is used to protect all access to the
- * hwgroup->busy flag, but is otherwise not needed for most processing in
- * the driver. This makes the driver much more friendlier to shared IRQs
- * than previous designs, while remaining 100% (?) SMP safe and capable.
- */
-/* --BenH: made non-static as ide-pmac.c uses it to kick the hwgroup back
- * into life on wakeup from machine sleep.
- */
-void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
-{
- ide_drive_t *drive;
- ide_hwif_t *hwif;
- struct request *rq;
- ide_startstop_t startstop;
-
- /* for atari only: POSSIBLY BROKEN HERE(?) */
- ide_get_lock(&ide_intr_lock, ide_intr, hwgroup);
-
- /* necessary paranoia: ensure IRQs are masked on local CPU */
- local_irq_disable();
-
- while (!hwgroup->busy) {
- hwgroup->busy = 1;
- drive = choose_drive(hwgroup);
- if (drive == NULL) {
- unsigned long sleep = 0;
- hwgroup->rq = NULL;
- drive = hwgroup->drive;
- do {
- if (drive->sleep && (!sleep || 0 < (signed long)(sleep - drive->sleep)))
- sleep = drive->sleep;
- } while ((drive = drive->next) != hwgroup->drive);
- if (sleep) {
- /*
- * Take a short snooze, and then wake up this hwgroup again.
- * This gives other hwgroups on the same a chance to
- * play fairly with us, just in case there are big differences
- * in relative throughputs.. don't want to hog the cpu too much.
- */
- if (time_before(sleep, jiffies + WAIT_MIN_SLEEP))
- sleep = jiffies + WAIT_MIN_SLEEP;
-#if 1
- if (timer_pending(&hwgroup->timer))
- printk("ide_set_handler: timer already active\n");
-#endif
- /* so that ide_timer_expiry knows what to do */
- hwgroup->sleeping = 1;
- mod_timer(&hwgroup->timer, sleep);
- /* we purposely leave hwgroup->busy==1
- * while sleeping */
- } else {
- /* Ugly, but how can we sleep for the lock
- * otherwise? perhaps from tq_disk?
- */
-
- /* for atari only */
- ide_release_lock(&ide_intr_lock);
- hwgroup->busy = 0;
- }
-
- /* no more work for this hwgroup (for now) */
- return;
- }
- hwif = HWIF(drive);
- if (hwgroup->hwif->sharing_irq &&
- hwif != hwgroup->hwif &&
- hwif->io_ports[IDE_CONTROL_OFFSET]) {
- /* set nIEN for previous hwif */
- SELECT_INTERRUPT(drive);
- }
- hwgroup->hwif = hwif;
- hwgroup->drive = drive;
- drive->sleep = 0;
- drive->service_start = jiffies;
-
-queue_next:
- if (!ata_can_queue(drive)) {
- if (!ata_pending_commands(drive))
- hwgroup->busy = 0;
-
- break;
- }
-
- if (blk_queue_plugged(&drive->queue)) {
- if (drive->using_tcq)
- break;
-
- printk("ide: huh? queue was plugged!\n");
- break;
- }
-
- /*
- * we know that the queue isn't empty, but this can happen
- * if the q->prep_rq_fn() decides to kill a request
- */
- rq = elv_next_request(&drive->queue);
- if (!rq) {
- hwgroup->busy = !!ata_pending_commands(drive);
- break;
- }
-
- if (!rq->bio && ata_pending_commands(drive))
- break;
-
- hwgroup->rq = rq;
-
- /*
- * Some systems have trouble with IDE IRQs arriving while
- * the driver is still setting things up. So, here we disable
- * the IRQ used by this interface while the request is being started.
- * This may look bad at first, but pretty much the same thing
- * happens anyway when any interrupt comes in, IDE or otherwise
- * -- the kernel masks the IRQ while it is being handled.
- */
- if (masked_irq && hwif->irq != masked_irq)
- disable_irq_nosync(hwif->irq);
- spin_unlock(&ide_lock);
- local_irq_enable();
- /* allow other IRQs while we start this request */
- startstop = start_request(drive, rq);
- spin_lock_irq(&ide_lock);
- if (masked_irq && hwif->irq != masked_irq)
- enable_irq(hwif->irq);
- if (startstop == ide_released)
- goto queue_next;
- if (startstop == ide_stopped)
- hwgroup->busy = 0;
- }
-}
-
-EXPORT_SYMBOL(ide_do_request);
-
-/*
- * Passes the stuff to ide_do_request
- */
-void do_ide_request(request_queue_t *q)
-{
- ide_do_request(q->queuedata, 0);
-}
-
-/*
- * un-busy the hwgroup etc, and clear any pending DMA status. we want to
- * retry the current request in pio mode instead of risking tossing it
- * all away
- */
-void ide_dma_timeout_retry(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = HWIF(drive);
- struct request *rq;
-
- /*
- * end current dma transaction
- */
- (void) hwif->ide_dma_end(drive);
-
- /*
- * complain a little, later we might remove some of this verbosity
- */
- printk("%s: timeout waiting for DMA\n", drive->name);
- (void) hwif->ide_dma_timeout(drive);
-
- /*
- * disable dma for now, but remember that we did so because of
- * a timeout -- we'll reenable after we finish this next request
- * (or rather the first chunk of it) in pio.
- */
- drive->retry_pio++;
- drive->state = DMA_PIO_RETRY;
- (void) hwif->ide_dma_off_quietly(drive);
-
- /*
- * un-busy drive etc (hwgroup->busy is cleared on return) and
- * make sure request is sane
- */
- rq = HWGROUP(drive)->rq;
- HWGROUP(drive)->rq = NULL;
-
- rq->errors = 0;
- rq->sector = rq->bio->bi_sector;
- rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
- rq->hard_cur_sectors = rq->current_nr_sectors;
- if (rq->bio)
- rq->buffer = NULL;
-}
-
-EXPORT_SYMBOL(ide_dma_timeout_retry);
-
-/*
- * ide_timer_expiry() is our timeout function for all drive operations.
- * But note that it can also be invoked as a result of a "sleep" operation
- * triggered by the mod_timer() call in ide_do_request.
- */
-void ide_timer_expiry (unsigned long data)
-{
- ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data;
- ide_handler_t *handler;
- ide_expiry_t *expiry;
- unsigned long flags;
- unsigned long wait;
-
- spin_lock_irqsave(&ide_lock, flags);
- del_timer(&hwgroup->timer);
-
- if ((handler = hwgroup->handler) == NULL) {
- /*
- * Either a marginal timeout occurred
- * (got the interrupt just as timer expired),
- * or we were "sleeping" to give other devices a chance.
- * Either way, we don't really want to complain about anything.
- */
- if (hwgroup->sleeping) {
- hwgroup->sleeping = 0;
- hwgroup->busy = 0;
- }
- } else {
- ide_drive_t *drive = hwgroup->drive;
- if (!drive) {
- printk("ide_timer_expiry: hwgroup->drive was NULL\n");
- hwgroup->handler = NULL;
- } else {
- ide_hwif_t *hwif;
- ide_startstop_t startstop = ide_stopped;
- if (!hwgroup->busy) {
- hwgroup->busy = 1; /* paranoia */
- printk("%s: ide_timer_expiry: hwgroup->busy was 0 ??\n", drive->name);
- }
- if ((expiry = hwgroup->expiry) != NULL) {
- /* continue */
- if ((wait = expiry(drive)) != 0) {
- /* reset timer */
- hwgroup->timer.expires = jiffies + wait;
- add_timer(&hwgroup->timer);
- spin_unlock_irqrestore(&ide_lock, flags);
- return;
- }
- }
- hwgroup->handler = NULL;
- /*
- * We need to simulate a real interrupt when invoking
- * the handler() function, which means we need to
- * globally mask the specific IRQ:
- */
- spin_unlock(&ide_lock);
- hwif = HWIF(drive);
-#if DISABLE_IRQ_NOSYNC
- disable_irq_nosync(hwif->irq);
-#else
- /* disable_irq_nosync ?? */
- disable_irq(hwif->irq);
-#endif /* DISABLE_IRQ_NOSYNC */
- /* local CPU only,
- * as if we were handling an interrupt */
- local_irq_disable();
- if (hwgroup->poll_timeout != 0) {
- startstop = handler(drive);
- } else if (drive_is_ready(drive)) {
- if (drive->waiting_for_dma)
- (void) hwgroup->hwif->ide_dma_lostirq(drive);
- (void)ide_ack_intr(hwif);
- printk("%s: lost interrupt\n", drive->name);
- startstop = handler(drive);
- } else {
- if (drive->waiting_for_dma) {
- startstop = ide_stopped;
- ide_dma_timeout_retry(drive);
- } else
- startstop = DRIVER(drive)->error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG));
- }
- set_recovery_timer(hwif);
- drive->service_time = jiffies - drive->service_start;
- enable_irq(hwif->irq);
- spin_lock_irq(&ide_lock);
- if (startstop == ide_stopped)
- hwgroup->busy = 0;
- }
- }
- ide_do_request(hwgroup, 0);
- spin_unlock_irqrestore(&ide_lock, flags);
-}
-
-EXPORT_SYMBOL(ide_timer_expiry);
-
-/*
- * There's nothing really useful we can do with an unexpected interrupt,
- * other than reading the status register (to clear it), and logging it.
- * There should be no way that an irq can happen before we're ready for it,
- * so we needn't worry much about losing an "important" interrupt here.
- *
- * On laptops (and "green" PCs), an unexpected interrupt occurs whenever the
- * drive enters "idle", "standby", or "sleep" mode, so if the status looks
- * "good", we just ignore the interrupt completely.
- *
- * This routine assumes __cli() is in effect when called.
- *
- * If an unexpected interrupt happens on irq15 while we are handling irq14
- * and if the two interfaces are "serialized" (CMD640), then it looks like
- * we could screw up by interfering with a new request being set up for irq15.
- *
- * In reality, this is a non-issue. The new command is not sent unless the
- * drive is ready to accept one, in which case we know the drive is not
- * trying to interrupt us. And ide_set_handler() is always invoked before
- * completing the issuance of any new drive command, so we will not be
- * accidentally invoked as a result of any valid command completion interrupt.
- *
- */
-static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
-{
- u8 stat;
- ide_hwif_t *hwif = hwgroup->hwif;
-
- /*
- * handle the unexpected interrupt
- */
- do {
- if (hwif->irq == irq) {
- stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
- if (!OK_STAT(stat, READY_STAT, BAD_STAT)) {
- /* Try to not flood the console with msgs */
- static unsigned long last_msgtime, count;
- ++count;
- if (time_after(jiffies, last_msgtime + HZ)) {
- last_msgtime = jiffies;
- printk("%s%s: unexpected interrupt, "
- "status=0x%02x, count=%ld\n",
- hwif->name,
- (hwif->next==hwgroup->hwif) ? "" : "(?)", stat, count);
- }
- }
- }
- } while ((hwif = hwif->next) != hwgroup->hwif);
-}
-
-/*
- * entry point for all interrupts, caller does __cli() for us
- */
-void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
-{
- unsigned long flags;
- ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id;
- ide_hwif_t *hwif;
- ide_drive_t *drive;
- ide_handler_t *handler;
- ide_startstop_t startstop;
-
- spin_lock_irqsave(&ide_lock, flags);
- hwif = hwgroup->hwif;
-
- if (!ide_ack_intr(hwif)) {
- spin_unlock_irqrestore(&ide_lock, flags);
- return;
- }
-
- if ((handler = hwgroup->handler) == NULL ||
- hwgroup->poll_timeout != 0) {
- /*
- * Not expecting an interrupt from this drive.
- * That means this could be:
- * (1) an interrupt from another PCI device
- * sharing the same PCI INT# as us.
- * or (2) a drive just entered sleep or standby mode,
- * and is interrupting to let us know.
- * or (3) a spurious interrupt of unknown origin.
- *
- * For PCI, we cannot tell the difference,
- * so in that case we just ignore it and hope it goes away.
- */
-#ifdef CONFIG_BLK_DEV_IDEPCI
- if (hwif->pci_dev && !hwif->pci_dev->vendor)
-#endif /* CONFIG_BLK_DEV_IDEPCI */
- {
- /*
- * Probably not a shared PCI interrupt,
- * so we can safely try to do something about it:
- */
- unexpected_intr(irq, hwgroup);
-#ifdef CONFIG_BLK_DEV_IDEPCI
- } else {
- /*
- * Whack the status register, just in case
- * we have a leftover pending IRQ.
- */
- (void) hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
-#endif /* CONFIG_BLK_DEV_IDEPCI */
- }
- spin_unlock_irqrestore(&ide_lock, flags);
- return;
- }
- drive = hwgroup->drive;
- if (!drive) {
- /*
- * This should NEVER happen, and there isn't much
- * we could do about it here.
- */
- spin_unlock_irqrestore(&ide_lock, flags);
- return;
- }
- if (!drive_is_ready(drive)) {
- /*
- * This happens regularly when we share a PCI IRQ with
- * another device. Unfortunately, it can also happen
- * with some buggy drives that trigger the IRQ before
- * their status register is up to date. Hopefully we have
- * enough advance overhead that the latter isn't a problem.
- */
- spin_unlock_irqrestore(&ide_lock, flags);
- return;
- }
- if (!hwgroup->busy) {
- hwgroup->busy = 1; /* paranoia */
- printk("%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name);
- }
- hwgroup->handler = NULL;
- del_timer(&hwgroup->timer);
- spin_unlock(&ide_lock);
-
- if (drive->unmask)
- local_irq_enable();
- /* service this interrupt, may set handler for next interrupt */
- startstop = handler(drive);
- spin_lock_irq(&ide_lock);
-
- /*
- * Note that handler() may have set things up for another
- * interrupt to occur soon, but it cannot happen until
- * we exit from this routine, because it will be the
- * same irq as is currently being serviced here, and Linux
- * won't allow another of the same (on any CPU) until we return.
- */
- set_recovery_timer(HWIF(drive));
- drive->service_time = jiffies - drive->service_start;
- if (startstop == ide_stopped) {
- if (hwgroup->handler == NULL) { /* paranoia */
- hwgroup->busy = 0;
- ide_do_request(hwgroup, hwif->irq);
- } else {
- printk("%s: ide_intr: huh? expected NULL handler "
- "on exit\n", drive->name);
- }
- }
- spin_unlock_irqrestore(&ide_lock, flags);
-}
-
-EXPORT_SYMBOL(ide_intr);
-
-/*
- * This function is intended to be used prior to invoking ide_do_drive_cmd().
- */
-void ide_init_drive_cmd (struct request *rq)
-{
- memset(rq, 0, sizeof(*rq));
- rq->flags = REQ_DRIVE_CMD;
-}
-
-EXPORT_SYMBOL(ide_init_drive_cmd);
-
-/*
- * This function issues a special IDE device request
- * onto the request queue.
- *
- * If action is ide_wait, then the rq is queued at the end of the
- * request queue, and the function sleeps until it has been processed.
- * This is for use when invoked from an ioctl handler.
- *
- * If action is ide_preempt, then the rq is queued at the head of
- * the request queue, displacing the currently-being-processed
- * request and this function returns immediately without waiting
- * for the new rq to be completed. This is VERY DANGEROUS, and is
- * intended for careful use by the ATAPI tape/cdrom driver code.
- *
- * If action is ide_next, then the rq is queued immediately after
- * the currently-being-processed-request (if any), and the function
- * returns without waiting for the new rq to be completed. As above,
- * This is VERY DANGEROUS, and is intended for careful use by the
- * ATAPI tape/cdrom driver code.
- *
- * If action is ide_end, then the rq is queued at the end of the
- * request queue, and the function returns immediately without waiting
- * for the new rq to be completed. This is again intended for careful
- * use by the ATAPI tape/cdrom driver code.
- */
-int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action)
-{
- unsigned long flags;
- ide_hwgroup_t *hwgroup = HWGROUP(drive);
- DECLARE_COMPLETION(wait);
- int insert_end = 1, err;
-
-#ifdef CONFIG_BLK_DEV_PDC4030
- if (HWIF(drive)->chipset == ide_pdc4030 && rq->buffer != NULL)
- return -ENOSYS; /* special drive cmds not supported */
-#endif
- rq->errors = 0;
- rq->rq_status = RQ_ACTIVE;
-
- rq->rq_disk = drive->disk;
-
- /*
- * we need to hold an extra reference to request for safe inspection
- * after completion
- */
- if (action == ide_wait) {
- rq->ref_count++;
- rq->waiting = &wait;
- }
-
- spin_lock_irqsave(&ide_lock, flags);
- if (action == ide_preempt) {
- hwgroup->rq = NULL;
- insert_end = 0;
- }
- __elv_add_request(&drive->queue, rq, insert_end, 0);
- ide_do_request(hwgroup, 0);
- spin_unlock_irqrestore(&ide_lock, flags);
- err = 0;
- if (action == ide_wait) {
- wait_for_completion(&wait);
- if (rq->errors)
- err = -EIO;
-
- blk_put_request(rq);
- }
-
- return err;
-}
-
-EXPORT_SYMBOL(ide_do_drive_cmd);
void ide_probe_module (void)
{
@@ -1632,11 +524,18 @@ ide_proc_entry_t generic_subdriver_entries[] = {
#define hwif_release_region(addr, num) \
((hwif->mmio) ? release_mem_region((addr),(num)) : release_region((addr),(num)))
-/*
- * Note that we only release the standard ports,
- * and do not even try to handle any extra ports
- * allocated for weird IDE interface chipsets.
+/**
+ * hwif_unregister - free IDE resources
+ *
+ * Note that we only release the standard ports,
+ * and do not even try to handle any extra ports
+ * allocated for weird IDE interface chipsets.
+ *
+ * Note also that we don't yet handle mmio resources here. More
+ * importantly our caller should be doing this so we need to
+ * restructure this as a helper function for drivers.
*/
+
void hwif_unregister (ide_hwif_t *hwif)
{
u32 i = 0;
@@ -1665,6 +564,28 @@ EXPORT_SYMBOL(hwif_unregister);
extern void init_hwif_data(unsigned int index);
+/**
+ * ide_unregister - free an ide interface
+ * @index: index of interface (will change soon to a pointer)
+ *
+ * Perform the final unregister of an IDE interface. At the moment
+ * we don't refcount interfaces so this will also get split up.
+ *
+ * Locking:
+ * The caller must not hold the IDE locks
+ * The drive present/vanishing is not yet properly locked
+ * Take care with the callbacks. These have been split to avoid
+ * deadlocking the IDE layer. The shutdown callback is called
+ * before we take the lock and free resources. It is up to the
+ * caller to be sure there is no pending I/O here, and that
+ * the interfce will not be reopened (present/vanishing locking
+ * isnt yet done btw). After we commit to the final kill we
+ * call the cleanup callback with the ide locks held.
+ *
+ * Unregister restores the hwif structures to the default state.
+ * This is raving bonkers.
+ */
+
void ide_unregister (unsigned int index)
{
ide_drive_t *drive, *d;
@@ -1675,7 +596,8 @@ void ide_unregister (unsigned int index)
ide_hwif_t old_hwif;
if (index >= MAX_HWIFS)
- return;
+ BUG();
+
spin_lock_irqsave(&ide_lock, flags);
hwif = &ide_hwifs[index];
if (!hwif->present)
@@ -1686,12 +608,21 @@ void ide_unregister (unsigned int index)
continue;
if (drive->usage)
goto abort;
- if (drive->driver != NULL && DRIVER(drive)->cleanup(drive))
+ if (drive->driver != NULL && DRIVER(drive)->shutdown(drive))
goto abort;
}
hwif->present = 0;
spin_unlock_irqrestore(&ide_lock, flags);
+
+ for (unit = 0; unit < MAX_DRIVES; ++unit) {
+ drive = &hwif->drives[unit];
+ if (!drive->present)
+ continue;
+ if (drive->driver != NULL)
+ DRIVER(drive)->cleanup(drive);
+ }
+
#ifdef CONFIG_PROC_FS
destroy_proc_ide_drives(hwif);
#endif
@@ -1752,7 +683,7 @@ void ide_unregister (unsigned int index)
else
hwgroup->hwif = HWIF(hwgroup->drive);
-#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
+#if !defined(CONFIG_DMA_NONPCI)
if (hwif->dma_base) {
(void) ide_release_dma(hwif);
@@ -1764,7 +695,7 @@ void ide_unregister (unsigned int index)
hwif->dma_vendor3 = 0;
hwif->dma_prdtable = 0;
}
-#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */
+#endif /* !(CONFIG_DMA_NONPCI) */
/*
* Remove us from the kernel's knowledge
@@ -1894,11 +825,21 @@ abort:
EXPORT_SYMBOL(ide_unregister);
-/*
- * Setup hw_regs_t structure described by parameters. You
- * may set up the hw structure yourself OR use this routine to
- * do it for you.
+/**
+ * ide_setup_ports - set up IDE interface ports
+ * @hw: register descriptions
+ * @base: base register
+ * @offsets: table of register offsets
+ * @ctrl: control register
+ * @ack_irq: IRQ ack
+ * @irq: interrupt lie
+ *
+ * Setup hw_regs_t structure described by parameters. You
+ * may set up the hw structure yourself OR use this routine to
+ * do it for you. This is basically a helper
+ *
*/
+
void ide_setup_ports ( hw_regs_t *hw,
ide_ioreg_t base, int *offsets,
ide_ioreg_t ctrl, ide_ioreg_t intr,
@@ -2004,6 +945,27 @@ int ide_register (int arg1, int arg2, int irq)
EXPORT_SYMBOL(ide_register);
+/**
+ * ide_add_setting - attach an IDE setting
+ * drive: drive the setting is for
+ * name: name of setting
+ * rw: set if writable
+ * read_ioctl: read function
+ * write_ioctl: write function
+ * data_type: form expected
+ * min: minimum
+ * max: maximum
+ * mul_factor: multiply by
+ * div_factor: divide by
+ * data: value
+ * set: handling for setting
+ *
+ * Add a setting to the IDE drive. Support automatic removal and allow
+ * all the work to be done by plugged in handlers. This code is also
+ * rather short on locking, but the current plan is to do the locking
+ * internally to the function.
+ */
+
void ide_add_setting (ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
{
ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL;
@@ -2038,6 +1000,14 @@ abort:
EXPORT_SYMBOL(ide_add_setting);
+/**
+ * ide_remove_setting - remove an ioctl setting
+ * @name: name of the property
+ *
+ * Remove a drive ioctl setting that was created by ide_add_setting.
+ * Again this needs the locking fixed
+ */
+
void ide_remove_setting (ide_drive_t *drive, char *name)
{
ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting;
@@ -2053,6 +1023,16 @@ void ide_remove_setting (ide_drive_t *drive, char *name)
EXPORT_SYMBOL(ide_remove_setting);
+/**
+ * ide_find_setting_by_ioctl - find a setting handler by its command
+ * @drive: drive to act for
+ * @cmd: ioctl command code
+ *
+ * Scan the drive handlers for an ioctl handler for this function.
+ * The handlers vary by drive and sometimes by drive state.
+ * Needs locking fixes.
+ */
+
static ide_settings_t *ide_find_setting_by_ioctl (ide_drive_t *drive, int cmd)
{
ide_settings_t *setting = drive->settings;
@@ -2065,6 +1045,16 @@ static ide_settings_t *ide_find_setting_by_ioctl (ide_drive_t *drive, int cmd)
return setting;
}
+/**
+ * ide_find_setting_by_name - find a setting handler by its name
+ * @drive: drive to act for
+ * @cmd: ioctl command code
+ *
+ * Scan the drive handlers handler matching the name for this function.
+ * The handlers vary by drive and sometimes by drive state.
+ * Needs locking fixes.
+ */
+
ide_settings_t *ide_find_setting_by_name (ide_drive_t *drive, char *name)
{
ide_settings_t *setting = drive->settings;
@@ -2077,6 +1067,17 @@ ide_settings_t *ide_find_setting_by_name (ide_drive_t *drive, char *name)
return setting;
}
+/**
+ * auto_remove_settings - remove driver settings on a device
+ * @drive: drive to clean
+ *
+ * Called when we change the driver bindings for a device, for
+ * example if the device is hot plugged. We must scrub the driver
+ * bindings that are thus no longer relevant to the device in case
+ * it changes from say a CD-ROM to a disk
+ * Needs locking fixes
+ */
+
static void auto_remove_settings (ide_drive_t *drive)
{
ide_settings_t *setting;
@@ -2128,7 +1129,7 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive)
local_irq_set(lflags);
if (time_after(jiffies, timeout)) {
local_irq_restore(lflags);
- printk("%s: channel busy\n", drive->name);
+ printk(KERN_ERR "%s: channel busy\n", drive->name);
return -EBUSY;
}
local_irq_restore(lflags);
@@ -2229,8 +1230,7 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
SETFEATURES_XFER, 0, NULL);
if (!err && arg) {
- if ((HWIF(drive)->speedproc) != NULL)
- HWIF(drive)->speedproc(drive, (u8) arg);
+ ide_set_xfer_rate(drive, (u8) arg);
ide_driveid_update(drive);
}
return err;
@@ -2312,7 +1312,7 @@ EXPORT_SYMBOL(system_bus_clock);
*/
int ide_replace_subdriver (ide_drive_t *drive, const char *driver)
{
- if (!drive->present || drive->usage)
+ if (!drive->present || drive->usage || drive->dead)
goto abort;
if (drive->driver != NULL && DRIVER(drive)->cleanup(drive))
goto abort;
@@ -2487,7 +1487,7 @@ int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd,
#if 1
spin_lock_irqsave(&ide_lock, flags);
if ( HWGROUP(drive)->handler != NULL) {
- printk("%s: ide_set_handler: handler not null; %p\n", drive->name, HWGROUP(drive)->handler);
+ printk(KERN_ERR "%s: ide_set_handler: handler not null; %p\n", drive->name, HWGROUP(drive)->handler);
(void) HWGROUP(drive)->handler(drive);
// HWGROUP(drive)->handler = NULL;
HWGROUP(drive)->expiry = NULL;
@@ -2702,7 +1702,7 @@ int __init ide_setup (char *s)
strncmp(s,"hd",2)) /* hdx= & hdxlun= */
return 0;
- printk("ide_setup: %s", s);
+ printk(KERN_INFO "ide_setup: %s", s);
init_ide_data ();
#ifdef CONFIG_BLK_DEV_IDEDOUBLER
@@ -3050,18 +2050,6 @@ static void __init probe_for_hwifs (void)
swarm_ide_probe();
}
#endif /* CONFIG_BLK_DEV_IDE_SWARM */
-#ifdef CONFIG_BLK_DEV_IDE_ICSIDE
- {
- extern void icside_init(void);
- icside_init();
- }
-#endif /* CONFIG_BLK_DEV_IDE_ICSIDE */
-#ifdef CONFIG_BLK_DEV_IDE_RAPIDE
- {
- extern void rapide_init(void);
- rapide_init();
- }
-#endif /* CONFIG_BLK_DEV_IDE_RAPIDE */
#ifdef CONFIG_BLK_DEV_GAYLE
{
extern void gayle_init(void);
@@ -3122,21 +2110,39 @@ void __init ide_init_builtin_drivers (void)
#endif
}
-static int default_standby (ide_drive_t *drive)
+/*
+ * Actually unregister the subdriver. Called with the
+ * request lock dropped.
+ */
+
+static int default_cleanup (ide_drive_t *drive)
{
- return 0;
+ return ide_unregister_subdriver(drive);
}
-static int default_suspend (ide_drive_t *drive)
-{
- return 0;
-}
-
-static int default_resume (ide_drive_t *drive)
+/*
+ * Check if we can unregister the subdriver. Called with the
+ * request lock held.
+ */
+
+static int default_shutdown(ide_drive_t *drive)
{
+ if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) {
+ return 1;
+ }
+ drive->dead = 1;
return 0;
}
+/*
+ * Default function to use for the cache flush operation. This
+ * must be replaced for disk devices (see ATA specification
+ * documents on cache flush and drive suspend rules)
+ *
+ * If we have no device attached or the device is not writable
+ * this handler is sufficient.
+ */
+
static int default_flushcache (ide_drive_t *drive)
{
return 0;
@@ -3193,9 +2199,8 @@ static void setup_driver_defaults (ide_drive_t *drive)
{
ide_driver_t *d = drive->driver;
- if (d->standby == NULL) d->standby = default_standby;
- if (d->suspend == NULL) d->suspend = default_suspend;
- if (d->resume == NULL) d->resume = default_resume;
+ if (d->cleanup == NULL) d->cleanup = default_cleanup;
+ if (d->shutdown == NULL) d->shutdown = default_shutdown;
if (d->flushcache == NULL) d->flushcache = default_flushcache;
if (d->do_request == NULL) d->do_request = default_do_request;
if (d->end_request == NULL) d->end_request = default_end_request;
@@ -3213,7 +2218,7 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio
spin_lock_irqsave(&ide_lock, flags);
if (version != IDE_SUBDRIVER_VERSION || !drive->present ||
- drive->driver != NULL || drive->usage) {
+ drive->driver != NULL || drive->usage || drive->dead) {
spin_unlock_irqrestore(&ide_lock, flags);
return 1;
}
@@ -3274,13 +2279,8 @@ static int ide_drive_remove(struct device * dev)
ide_drive_t * drive = container_of(dev,ide_drive_t,gendev);
ide_driver_t * driver = drive->driver;
- if (driver) {
- if (driver->standby)
- driver->standby(drive);
- if (driver->cleanup)
- driver->cleanup(drive);
- }
-
+ if (driver && driver->cleanup)
+ driver->cleanup(drive);
return 0;
}
@@ -3321,7 +2321,7 @@ void ide_unregister_driver(ide_driver_t *driver)
while(!list_empty(&driver->drives)) {
drive = list_entry(driver->drives.next, ide_drive_t, list);
if (driver->cleanup(drive)) {
- printk("%s: cleanup_module() called while still busy\n", drive->name);
+ printk(KERN_ERR "%s: cleanup_module() called while still busy\n", drive->name);
BUG();
}
/* We must remove proc entries defined in this module.
@@ -3395,7 +2395,7 @@ static void __init parse_options (char *line)
if ((next = strchr(line,' ')) != NULL)
*next++ = 0;
if (!ide_setup(line))
- printk ("Unknown option '%s'\n", line);
+ printk (KERN_INFO "Unknown option '%s'\n", line);
}
}
@@ -3411,10 +2411,10 @@ void cleanup_module (void)
for (index = 0; index < MAX_HWIFS; ++index) {
ide_unregister(index);
-#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
+#if !defined(CONFIG_DMA_NONPCI)
if (ide_hwifs[index].dma_base)
(void) ide_release_dma(&ide_hwifs[index]);
-#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */
+#endif /* !(CONFIG_DMA_NONPCI) */
}
#ifdef CONFIG_PROC_FS
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index f06536b7f373..24bae996123b 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -411,6 +411,8 @@ void ide_release(u_long arg)
DEBUG(0, "ide_release(0x%p)\n", link);
if (info->ndev) {
+ /* FIXME: if this fails we need to queue the cleanup somehow
+ -- need to investigate the required PCMCIA magic */
ide_unregister(info->hd);
/* deal with brain dead IDE resource management */
request_region(link->io.BasePort1, link->io.NumPorts1,
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
index 1c9791e1232a..e594ae249e82 100644
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -5,7 +5,9 @@ obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o
obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o
obj-$(CONFIG_BLK_DEV_CMD640) += cmd640.o
obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o
+obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o
obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o
+obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o
obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o
obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o
obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index 9901a587fbdf..a63ca2380205 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -292,7 +292,6 @@ static int aec62xx_tune_chipset (ide_drive_t *drive, u8 speed)
}
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
static int config_chipset_for_dma (ide_drive_t *drive)
{
u8 speed = ide_dma_speed(drive, aec62xx_ratemask(drive));
@@ -303,7 +302,6 @@ static int config_chipset_for_dma (ide_drive_t *drive)
(void) aec62xx_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio)
{
@@ -321,7 +319,6 @@ static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio)
(void) aec62xx_tune_chipset(drive, speed);
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -405,7 +402,6 @@ static int aec62xx_irq_timeout (ide_drive_t *drive)
#endif
return 0;
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
static unsigned int __init init_chipset_aec62xx (struct pci_dev *dev, const char *name)
{
@@ -457,7 +453,6 @@ static void __init init_hwif_aec62xx (ide_hwif_t *hwif)
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
hwif->ide_dma_check = &aec62xx_config_drive_xfer_rate;
hwif->ide_dma_lostirq = &aec62xx_irq_timeout;
hwif->ide_dma_timeout = &aec62xx_irq_timeout;
@@ -465,7 +460,6 @@ static void __init init_hwif_aec62xx (ide_hwif_t *hwif)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
static void __init init_dma_aec62xx (ide_hwif_t *hwif, unsigned long dmabase)
diff --git a/drivers/ide/pci/aec62xx.h b/drivers/ide/pci/aec62xx.h
index 174214afe509..f0dd168f04d0 100644
--- a/drivers/ide/pci/aec62xx.h
+++ b/drivers/ide/pci/aec62xx.h
@@ -14,7 +14,6 @@ struct chipset_bus_clock_list_entry {
};
struct chipset_bus_clock_list_entry aec6xxx_33_base [] = {
-#ifdef CONFIG_BLK_DEV_IDEDMA
{ XFER_UDMA_6, 0x31, 0x07 },
{ XFER_UDMA_5, 0x31, 0x06 },
{ XFER_UDMA_4, 0x31, 0x05 },
@@ -26,7 +25,6 @@ struct chipset_bus_clock_list_entry aec6xxx_33_base [] = {
{ XFER_MW_DMA_2, 0x31, 0x00 },
{ XFER_MW_DMA_1, 0x31, 0x00 },
{ XFER_MW_DMA_0, 0x0a, 0x00 },
-#endif /* CONFIG_BLK_DEV_IDEDMA */
{ XFER_PIO_4, 0x31, 0x00 },
{ XFER_PIO_3, 0x33, 0x00 },
{ XFER_PIO_2, 0x08, 0x00 },
@@ -36,7 +34,6 @@ struct chipset_bus_clock_list_entry aec6xxx_33_base [] = {
};
struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
-#ifdef CONFIG_BLK_DEV_IDEDMA
{ XFER_UDMA_6, 0x41, 0x06 },
{ XFER_UDMA_5, 0x41, 0x05 },
{ XFER_UDMA_4, 0x41, 0x04 },
@@ -48,7 +45,6 @@ struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
{ XFER_MW_DMA_2, 0x41, 0x00 },
{ XFER_MW_DMA_1, 0x42, 0x00 },
{ XFER_MW_DMA_0, 0x7a, 0x00 },
-#endif /* CONFIG_BLK_DEV_IDEDMA */
{ XFER_PIO_4, 0x41, 0x00 },
{ XFER_PIO_3, 0x43, 0x00 },
{ XFER_PIO_2, 0x78, 0x00 },
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index 396b0a7282e7..681e615578a9 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -450,7 +450,6 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, u8 xferspeed)
if (speed < XFER_SW_DMA_0)
ali15x3_tune_drive(drive, speed);
-#ifdef CONFIG_BLK_DEV_IDEDMA
} else {
pci_read_config_byte(dev, m5229_udma, &tmpbyte);
tmpbyte &= (0x0f << ((1-unit) << 2));
@@ -464,12 +463,10 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, u8 xferspeed)
tmpbyte |= 1;
pci_write_config_byte(dev, 0x4b, tmpbyte);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
return (ide_config_drive_speed(drive, speed));
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
/**
* config_chipset_for_dma - set up DMA mode
@@ -562,7 +559,6 @@ static int ali15x3_dma_write (ide_drive_t *drive)
return 1; /* try PIO instead of DMA */
return __ide_dma_write(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
/**
* init_chipset_ali15x3 - Initialise an ALi IDE controller
@@ -756,7 +752,6 @@ static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif)
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (m5229_revision >= 0x20) {
/*
* M1543C or newer for DMAing
@@ -770,7 +765,6 @@ static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif)
}
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
/**
@@ -854,6 +848,12 @@ extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
ide_pci_device_t *d = &ali15x3_chipsets[id->driver_data];
+
+ if(pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_IGP, NULL))
+ {
+ printk(KERN_ERR "Warning: ATI Radeon IGP Northbridge is not supported by Linux\n");
+ return 1;
+ }
#if defined(CONFIG_SPARC64)
d->init_hwif = init_hwif_common_ali15x3;
#endif /* CONFIG_SPARC64 */
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index c5b032dd9f51..ac05acd321bf 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -148,7 +148,6 @@ static int amd74xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
pio_timing &= ~(0x03 << drive->dn);
switch(speed) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_UDMA_7:
case XFER_UDMA_6:
speed = XFER_UDMA_5;
@@ -194,7 +193,6 @@ static int amd74xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_SW_DMA_0:
dma_pio_timing |= 0xA8;
break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4:
dma_pio_timing |= 0x20;
break;
@@ -215,9 +213,7 @@ static int amd74xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
pio_timing |= (0x03 << drive->dn);
-#ifdef CONFIG_BLK_DEV_IDEDMA
pci_write_config_byte(dev, drive_pci[drive->dn], ultra_timing);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
pci_write_config_byte(dev, drive_pci2[drive->dn], dma_pio_timing);
pci_write_config_byte(dev, 0x4c, pio_timing);
@@ -230,7 +226,6 @@ static void amd74xx_tune_drive (ide_drive_t *drive, u8 pio)
(void) amd74xx_tune_chipset(drive, (XFER_PIO_0 + pio));
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
/*
* This allows the configuration of ide_pci chipset registers
* for cards that learn about the drive's UDMA, DMA, PIO capabilities
@@ -290,14 +285,11 @@ no_dma_set:
}
return hwif->ide_dma_on(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
static unsigned int __init init_chipset_amd74xx (struct pci_dev *dev, const char *name)
{
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (!amd74xx_swdma_check(dev))
printk("%s: disabling single-word DMA support (revision < C4)\n", name);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
#if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS)
if (!amd74xx_proc) {
@@ -348,11 +340,7 @@ static unsigned int __init ata66_amd74xx (ide_hwif_t *hwif)
default:
break;
}
-#ifdef CONFIG_AMD74XX_OVERRIDE
- return(1);
-#else
return (unsigned int) ata66;
-#endif /* CONFIG_AMD74XX_OVERRIDE */
}
static void __init init_hwif_amd74xx (ide_hwif_t *hwif)
@@ -373,7 +361,6 @@ static void __init init_hwif_amd74xx (ide_hwif_t *hwif)
if (amd74xx_swdma_check(hwif->pci_dev))
hwif->swdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (!(hwif->udma_four))
hwif->udma_four = ata66_amd74xx(hwif);
hwif->ide_dma_check = &amd74xx_config_drive_xfer_rate;
@@ -381,7 +368,6 @@ static void __init init_hwif_amd74xx (ide_hwif_t *hwif)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
static void __init init_dma_amd74xx (ide_hwif_t *hwif, unsigned long dmabase)
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
index b81456941bc1..b4c661d86f5e 100644
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -751,7 +751,7 @@ int __init ide_probe_for_cmd640x (void)
*/
put_cmd640_reg(0x5b, 0xbd);
if (get_cmd640_reg(0x5b) != 0xbd) {
- printk("ide: cmd640 init failed: wrong value in reg 0x5b\n");
+ printk(KERN_ERR "ide: cmd640 init failed: wrong value in reg 0x5b\n");
return 0;
}
put_cmd640_reg(0x5b, 0);
@@ -836,7 +836,7 @@ int __init ide_probe_for_cmd640x (void)
cmd_hwif1->tuneproc = &cmd640_tune_drive;
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
}
- printk("%s: %sserialized, secondary interface %s\n", cmd_hwif1->name,
+ printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name,
cmd_hwif0->serialized ? "" : "not ", port2);
/*
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index 50b8d6582241..a90b00af79e1 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -383,18 +383,15 @@ static void config_chipset_for_pio (ide_drive_t *drive, u8 set_speed)
static int cmd64x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
-#ifdef CONFIG_BLK_DEV_IDEDMA
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u8 unit = (drive->select.b.unit & 0x01);
u8 regU = 0, pciU = (hwif->channel) ? UDIDETCR1 : UDIDETCR0;
u8 regD = 0, pciD = (hwif->channel) ? BMIDESR1 : BMIDESR0;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
u8 speed = ide_rate_filter(cmd64x_ratemask(drive), xferspeed);
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (speed > XFER_PIO_4) {
(void) pci_read_config_byte(dev, pciD, &regD);
(void) pci_read_config_byte(dev, pciU, &regU);
@@ -405,10 +402,8 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
(void) pci_read_config_byte(dev, pciD, &regD);
(void) pci_read_config_byte(dev, pciU, &regU);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
switch(speed) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); break;
case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break;
case XFER_UDMA_3: regU |= (unit ? 0x8A : 0x25); break;
@@ -421,7 +416,6 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_SW_DMA_2: regD |= (unit ? 0x40 : 0x10); break;
case XFER_SW_DMA_1: regD |= (unit ? 0x80 : 0x20); break;
case XFER_SW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4: cmd64x_tuneproc(drive, 4); break;
case XFER_PIO_3: cmd64x_tuneproc(drive, 3); break;
case XFER_PIO_2: cmd64x_tuneproc(drive, 2); break;
@@ -432,29 +426,26 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
return 1;
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (speed > XFER_PIO_4) {
(void) pci_write_config_byte(dev, pciU, regU);
regD |= (unit ? 0x40 : 0x20);
(void) pci_write_config_byte(dev, pciD, regD);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
return (ide_config_drive_speed(drive, speed));
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
static int config_chipset_for_dma (ide_drive_t *drive)
{
u8 speed = ide_dma_speed(drive, cmd64x_ratemask(drive));
- config_chipset_for_pio(drive, (!(speed)));
+ config_chipset_for_pio(drive, !speed);
- if ((!(speed)))
+ if (!speed)
return 0;
- if (HWIF(drive)->speedproc(drive, speed))
- return 0;
+ if(ide_set_xfer_rate(drive, speed))
+ return 0;
if (!drive->init_speed)
drive->init_speed = speed;
@@ -593,7 +584,6 @@ static int cmd646_1_ide_dma_end (ide_drive_t *drive)
/* verify good DMA status */
return (dma_stat & 7) != 4;
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
static unsigned int __init init_chipset_cmd64x (struct pci_dev *dev, const char *name)
{
@@ -732,7 +722,6 @@ static void __init init_hwif_cmd64x (ide_hwif_t *hwif)
if (dev->device == PCI_DEVICE_ID_CMD_648)
hwif->ultra_mask = 0x1f;
-#ifdef CONFIG_BLK_DEV_IDEDMA
hwif->ide_dma_check = &cmd64x_config_drive_for_dma;
if (!(hwif->udma_four))
hwif->udma_four = ata66_cmd64x(hwif);
@@ -755,7 +744,6 @@ static void __init init_hwif_cmd64x (ide_hwif_t *hwif)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
static void __init init_dma_cmd64x (ide_hwif_t *hwif, unsigned long dmabase)
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
new file mode 100644
index 000000000000..4abc70b056aa
--- /dev/null
+++ b/drivers/ide/pci/cs5520.c
@@ -0,0 +1,323 @@
+/*
+ * IDE tuning and bus mastering support for the CS5510/CS5520
+ * chipsets
+ *
+ * The CS5510/CS5520 are slightly unusual devices. Unlike the
+ * typical IDE controllers they do bus mastering with the drive in
+ * PIO mode and smarter silicon.
+ *
+ * The practical upshot of this is that we must always tune the
+ * drive for the right PIO mode. We must also ignore all the blacklists
+ * and the drive bus mastering DMA information.
+ *
+ * *** This driver is strictly experimental ***
+ *
+ * (c) Copyright Red Hat Inc 2002
+ *
+ * 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, 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.
+ *
+ * For the avoidance of doubt the "preferred form" of this code is one which
+ * is in an open non patent encumbered format. Where cryptographic key signing
+ * forms part of the process of creating an executable the information
+ * including keys needed to generate an equivalently functional executable
+ * are deemed to be part of the source code.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "ide_modes.h"
+#include "cs5520.h"
+
+#if defined(DISPLAY_CS5520_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static u8 cs5520_proc = 0;
+static struct pci_dev *bmide_dev;
+
+static int cs5520_get_info(char *buffer, char **addr, off_t offset, int count)
+{
+ char *p = buffer;
+ unsigned long bmiba = pci_resource_start(bmide_dev, 2);
+ u8 c0 = 0, c1 = 0;
+ u16 reg16;
+ u32 reg32;
+
+ /*
+ * at that point bibma+0x2 et bibma+0xa are byte registers
+ * to investigate:
+ */
+ c0 = inb((unsigned short)bmiba + 0x02);
+ c1 = inb((unsigned short)bmiba + 0x0a);
+
+ p += sprintf(p, "\nCyrix CS55x0 IDE\n");
+ p += sprintf(p, "--------------- Primary Channel "
+ "---------------- Secondary Channel "
+ "-------------\n");
+ p += sprintf(p, " %sabled "
+ " %sabled\n",
+ (c0&0x80) ? "dis" : " en",
+ (c1&0x80) ? "dis" : " en");
+
+ p += sprintf(p, "\n\nTimings: \n");
+
+ pci_read_config_word(bmide_dev, 0x62, &reg16);
+ p += sprintf(p, "8bit CAT/CRT : %04x\n", reg16);
+ pci_read_config_dword(bmide_dev, 0x64, &reg32);
+ p += sprintf(p, "16bit Primary : %08x\n", reg32);
+ pci_read_config_dword(bmide_dev, 0x68, &reg32);
+ p += sprintf(p, "16bit Secondary: %08x\n", reg32);
+
+ return p-buffer;
+}
+
+#endif
+
+struct pio_clocks
+{
+ int address;
+ int assert;
+ int recovery;
+};
+
+struct pio_clocks cs5520_pio_clocks[]={
+ {3, 6, 11},
+ {2, 5, 6},
+ {1, 4, 3},
+ {1, 3, 2},
+ {1, 2, 1}
+};
+
+static int cs5520_tune_chipset(ide_drive_t *drive, u8 xferspeed)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ struct pci_dev *pdev = hwif->pci_dev;
+ u8 speed = min((u8)XFER_PIO_4, xferspeed);
+ int pio = speed;
+ u8 reg;
+ int controller = drive->dn > 1 ? 1 : 0;
+ int error;
+
+ switch(speed)
+ {
+ case XFER_PIO_4:
+ case XFER_PIO_3:
+ case XFER_PIO_2:
+ case XFER_PIO_1:
+ case XFER_PIO_0:
+ pio -= XFER_PIO_0;
+ break;
+ default:
+ pio = 0;
+ printk(KERN_ERR "cs55x0: bad ide timing.\n");
+ }
+
+ printk("PIO clocking = %d\n", pio);
+
+ /* FIXME: if DMA = 1 do we need to set the DMA bit here ? */
+
+ /* 8bit command timing for channel */
+ pci_write_config_byte(pdev, 0x62 + controller,
+ (cs5520_pio_clocks[pio].recovery << 4) |
+ (cs5520_pio_clocks[pio].assert));
+
+ /* FIXME: should these use address ? */
+ /* Data read timing */
+ pci_write_config_byte(pdev, 0x64 + 4*controller + (drive->dn&1),
+ (cs5520_pio_clocks[pio].recovery << 4) |
+ (cs5520_pio_clocks[pio].assert));
+ /* Write command timing */
+ pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1),
+ (cs5520_pio_clocks[pio].recovery << 4) |
+ (cs5520_pio_clocks[pio].assert));
+
+ /* Set the DMA enable/disable flag */
+ reg = inb(hwif->dma_base + 0x02 + 8*controller);
+ reg |= 1<<((drive->dn&1)+5);
+ outb(reg, hwif->dma_base + 0x02 + 8*controller);
+
+ error = ide_config_drive_speed(drive, speed);
+ /* ATAPI is harder so leave it for now */
+ if(!error && drive->media == ide_disk)
+ error = hwif->ide_dma_on(drive);
+}
+
+static void cs5520_tune_drive(ide_drive_t *drive, u8 pio)
+{
+ pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+ cs5520_tune_chipset(drive, (XFER_PIO_0 + pio));
+}
+
+static int cs5520_config_drive_xfer_rate(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+
+ /* Tune the drive for PIO modes up to PIO 4 */
+ cs5520_tune_drive(drive, 4);
+ /* Then tell the core to use DMA operations */
+ return hwif->ide_dma_on(drive);
+}
+
+
+static unsigned int __devinit init_chipset_cs5520(struct pci_dev *dev, const char *name)
+{
+#if defined(DISPLAY_CS5520_TIMINGS) && defined(CONFIG_PROC_FS)
+ if (!cs5520_proc) {
+ cs5520_proc = 1;
+ bmide_dev = dev;
+ ide_pci_register_host_proc(&cs5520_procs[0]);
+ }
+#endif /* DISPLAY_CS5520_TIMINGS && CONFIG_PROC_FS */
+ return 0;
+}
+
+/*
+ * We provide a callback for our nonstandard DMA location
+ */
+
+static void __devinit cs5520_init_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif)
+{
+ u32 bmide = pci_resource_start(dev, 2); /* Not the usual 4 */
+ if(hwif->mate && hwif->mate->dma_base) /* Second channel at primary + 8 */
+ bmide += 8;
+ ide_setup_dma(hwif, bmide, 8);
+}
+
+/*
+ * We wrap the DMA activate to set the vdma flag. This is needed
+ * so that the IDE DMA layer issues PIO not DMA commands over the
+ * DMA channel
+ */
+
+static int cs5520_dma_on(ide_drive_t *drive)
+{
+ drive->vdma = 1;
+ return 0;
+}
+
+static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
+{
+ hwif->tuneproc = &cs5520_tune_drive;
+ hwif->speedproc = &cs5520_tune_chipset;
+ hwif->ide_dma_check = &cs5520_config_drive_xfer_rate;
+ hwif->ide_dma_on = &cs5520_dma_on;
+
+ if(!noautodma)
+ hwif->autodma = 1;
+
+ if(!hwif->dma_base)
+ {
+ hwif->drives[0].autotune = 1;
+ hwif->drives[1].autotune = 1;
+ return;
+ }
+
+ hwif->atapi_dma = 0;
+ hwif->ultra_mask = 0;
+ hwif->swdma_mask = 0;
+ hwif->mwdma_mask = 0;
+
+ hwif->drives[0].autodma = hwif->autodma;
+ hwif->drives[1].autodma = hwif->autodma;
+}
+
+/*
+ * The 5510/5520 are a bit weird. They don't quite set up the way
+ * the PCI helper layer expects so we must do much of the set up
+ * work longhand.
+ */
+
+static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ ata_index_t index;
+ ide_pci_device_t *d = &cyrix_chipsets[id->driver_data];
+
+ ide_setup_pci_noise(dev, d);
+
+ /* We must not grab the entire device, it has 'ISA' space in its
+ BARS too and we will freak out other bits of the kernel */
+ if(pci_enable_device_bars(dev, 1<<2))
+ {
+ printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name);
+ return 1;
+ }
+ pci_set_master(dev);
+ pci_set_dma_mask(dev, 0xFFFFFFFF);
+ init_chipset_cs5520(dev, d->name);
+
+ index.all = 0xf0f0;
+
+ /*
+ * Now the chipset is configured we can let the core
+ * do all the device setup for us
+ */
+
+ ide_pci_setup_ports(dev, d, 1, 14, &index);
+
+ printk("Index.b %d %d\n", index.b.low, index.b.high);
+ mdelay(2000);
+ if((index.b.low & 0xf0) != 0xf0)
+ probe_hwif_init(&ide_hwifs[index.b.low]);
+ if((index.b.high & 0xf0) != 0xf0)
+ probe_hwif_init(&ide_hwifs[index.b.high]);
+
+ return 0;
+}
+
+static struct pci_device_id cs5520_pci_tbl[] __devinitdata = {
+ { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+ { 0, },
+};
+
+static struct pci_driver driver = {
+ .name = "CyrixIDE",
+ .id_table = cs5520_pci_tbl,
+ .probe = cs5520_init_one,
+};
+
+static int cs5520_ide_init(void)
+{
+ return ide_pci_register_driver(&driver);
+}
+
+static void cs5520_ide_exit(void)
+{
+ return ide_pci_unregister_driver(&driver);
+}
+
+module_init(cs5520_ide_init);
+module_exit(cs5520_ide_exit);
+
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("PCI driver module for Cyrix 5510/5520 IDE");
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
+
diff --git a/drivers/ide/pci/cs5520.h b/drivers/ide/pci/cs5520.h
new file mode 100644
index 000000000000..efb3e6cd3a63
--- /dev/null
+++ b/drivers/ide/pci/cs5520.h
@@ -0,0 +1,66 @@
+#ifndef CS5520_H
+#define CS5520_H
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+
+#define DISPLAY_CS5520_TIMINGS
+
+#if defined(DISPLAY_CS5520_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static u8 cs5520_proc;
+
+static int cs5520_get_info(char *, char **, off_t, int);
+
+static ide_pci_host_proc_t cs5520_procs[] __initdata = {
+ {
+ name: "cs5520",
+ set: 1,
+ get_info: cs5520_get_info,
+ parent: NULL,
+ },
+};
+#endif /* defined(DISPLAY_CS5520_TIMINGS) && defined(CONFIG_PROC_FS) */
+
+static unsigned int init_chipset_cs5520(struct pci_dev *, const char *);
+static void init_hwif_cs5520(ide_hwif_t *);
+static void cs5520_init_setup_dma(struct pci_dev *dev, struct ide_pci_device_s *d, ide_hwif_t *hwif);
+
+static ide_pci_device_t cyrix_chipsets[] __devinitdata = {
+ {
+ vendor: PCI_VENDOR_ID_CYRIX,
+ device: PCI_DEVICE_ID_CYRIX_5510,
+ name: "Cyrix 5510",
+ init_chipset: init_chipset_cs5520,
+ init_setup_dma: cs5520_init_setup_dma,
+ init_iops: NULL,
+ init_hwif: init_hwif_cs5520,
+ isa_ports: 1,
+ channels: 2,
+ autodma: AUTODMA,
+ bootable: ON_BOARD,
+ extra: 0,
+ },
+ {
+ vendor: PCI_VENDOR_ID_CYRIX,
+ device: PCI_DEVICE_ID_CYRIX_5520,
+ name: "Cyrix 5520",
+ init_chipset: init_chipset_cs5520,
+ init_setup_dma: cs5520_init_setup_dma,
+ init_iops: NULL,
+ init_hwif: init_hwif_cs5520,
+ isa_ports: 1,
+ channels: 2,
+ autodma: AUTODMA,
+ bootable: ON_BOARD,
+ extra: 0,
+ }
+};
+
+
+#endif /* CS5520_H */
+
+
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index b153e1a2fabb..a5061e308eb8 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -135,8 +135,6 @@ static void cs5530_tuneproc (ide_drive_t *drive, u8 pio) /* pio=255 means "autot
}
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
-
/**
* cs5530_config_dma - select/set DMA and UDMA modes
* @drive: drive to tune
@@ -256,7 +254,6 @@ static int cs5530_config_dma (ide_drive_t *drive)
*/
return hwif->ide_dma_on(drive); /* success */
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
/**
* init_chipset_5530 - set up 5530 bridge
@@ -396,13 +393,11 @@ static void __init init_hwif_cs5530 (ide_hwif_t *hwif)
hwif->ultra_mask = 0x07;
hwif->mwdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
hwif->ide_dma_check = &cs5530_config_dma;
if (!noautodma)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
/**
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index a368d97d3371..b0311fbe2f34 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -123,10 +123,10 @@ static void compute_clocks (u8 pio, pio_clocks_t *p_pclk)
p_pclk->time_8 = (u8)clk1;
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
/*
* set DMA mode a specific channel for CY82C693
*/
+
static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
{
u8 index = 0, data = 0;
@@ -213,7 +213,6 @@ int cy82c693_ide_dma_on (ide_drive_t *drive)
}
return __ide_dma_on(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
/*
* tune ide drive - set PIO mode
@@ -405,13 +404,11 @@ void __init init_hwif_cy82c693(ide_hwif_t *hwif)
hwif->mwdma_mask = 0x04;
hwif->swdma_mask = 0x04;
-#ifdef CONFIG_BLK_DEV_IDEDMA
hwif->ide_dma_on = &cy82c693_ide_dma_on;
if (!noautodma)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
static __initdata ide_hwif_t *primary;
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index 046fafa2227a..921645609662 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -50,12 +50,10 @@ static void __init init_hwif_generic (ide_hwif_t *hwif)
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (!noautodma)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
static void init_dma_generic (ide_hwif_t *hwif, unsigned long dmabase)
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index d4962f53e6c0..e78765e15589 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -159,13 +159,13 @@ static void hpt34x_tune_drive (ide_drive_t *drive, u8 pio)
(void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio));
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
/*
* This allows the configuration of ide_pci chipset registers
* for cards that learn about the drive's UDMA, DMA, PIO capabilities
* after the drive is reported by the OS. Initally for designed for
* HPT343 UDMA chipset by HighPoint|Triones Technologies, Inc.
*/
+
static int config_chipset_for_dma (ide_drive_t *drive)
{
u8 speed = ide_dma_speed(drive, hpt34x_ratemask(drive));
@@ -224,7 +224,6 @@ no_dma_set:
#endif /* CONFIG_HPT34X_AUTODMA */
return hwif->ide_dma_on(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
/*
* If the BIOS does not set the IO base addaress to XX00, 343 will fail.
@@ -306,13 +305,11 @@ static void __init init_hwif_hpt34x (ide_hwif_t *hwif)
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
hwif->ide_dma_check = &hpt34x_config_drive_xfer_rate;
if (!noautodma)
hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
static void __init init_dma_hpt34x (ide_hwif_t *hwif, unsigned long dmabase)
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 994eee278da3..bf24fd8add64 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -216,7 +216,6 @@ static u8 hpt3xx_ratemask (ide_drive_t *drive)
static u8 hpt3xx_ratefilter (ide_drive_t *drive, u8 speed)
{
-#ifdef CONFIG_BLK_DEV_IDEDMA
struct pci_dev *dev = HWIF(drive)->pci_dev;
u8 mode = hpt3xx_ratemask(drive);
@@ -264,9 +263,6 @@ static u8 hpt3xx_ratefilter (ide_drive_t *drive, u8 speed)
break;
}
return speed;
-#else
- return min(speed, (u8)XFER_PIO_4);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
static int check_in_drive_lists (ide_drive_t *drive, const char **list)
@@ -297,7 +293,7 @@ static void hpt366_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
struct pci_dev *dev = HWIF(drive)->pci_dev;
u8 speed = hpt3xx_ratefilter(drive, xferspeed);
-// u8 speed = ide_rate_filter(hpt3xx_ratemask(drive), xferspeed);
+// u8 speed = ide_rate_filter(hpt3xx_ratemask(drive), xferspeed);
u8 regtime = (drive->select.b.unit & 0x01) ? 0x44 : 0x40;
u8 regfast = (HWIF(drive)->channel) ? 0x55 : 0x51;
u8 drive_fast = 0;
@@ -444,7 +440,6 @@ static void hpt3xx_tune_drive (ide_drive_t *drive, u8 pio)
(void) hpt3xx_tune_chipset(drive, (XFER_PIO_0 + pio));
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
/*
* This allows the configuration of ide_pci chipset registers
* for cards that learn about the drive's UDMA, DMA, PIO capabilities
@@ -654,7 +649,6 @@ static int hpt374_ide_dma_end (ide_drive_t *drive)
pci_write_config_byte(dev, mscreg, msc_stat|0x30);
return __ide_dma_end(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
/*
* Since SUN Cobalt is attempting to do this operation, I should disclose
@@ -1030,7 +1024,6 @@ static void __init init_hwif_hpt366 (ide_hwif_t *hwif)
hwif->ultra_mask = 0x7f;
hwif->mwdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (!(hwif->udma_four))
hwif->udma_four = ((ata66 & regmask) ? 0 : 1);
hwif->ide_dma_check = &hpt366_config_drive_xfer_rate;
@@ -1053,7 +1046,6 @@ static void __init init_hwif_hpt366 (ide_hwif_t *hwif)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
static void __init init_dma_hpt366 (ide_hwif_t *hwif, unsigned long dmabase)
diff --git a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c
index e914b39f6850..78f8b9b79105 100644
--- a/drivers/ide/pci/it8172.c
+++ b/drivers/ide/pci/it8172.c
@@ -151,7 +151,6 @@ static int it8172_tune_chipset (ide_drive_t *drive, u8 xferspeed)
*/
switch(speed) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_UDMA_4:
case XFER_UDMA_2: //u_speed = 2 << (drive->dn * 4); break;
case XFER_UDMA_5:
@@ -162,7 +161,6 @@ static int it8172_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_MW_DMA_1:
case XFER_MW_DMA_0:
case XFER_SW_DMA_2: break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4:
case XFER_PIO_3:
case XFER_PIO_2:
@@ -183,7 +181,6 @@ static int it8172_tune_chipset (ide_drive_t *drive, u8 xferspeed)
return (ide_config_drive_speed(drive, speed));
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
static int it8172_config_chipset_for_dma (ide_drive_t *drive)
{
u8 speed = ide_dma_speed(drive, it8172_ratemask(drive));
@@ -239,7 +236,6 @@ no_dma_set:
}
return hwif->ide_dma_on(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
static unsigned int __init init_chipset_it8172 (struct pci_dev *dev, const char *name)
{
@@ -282,13 +278,11 @@ static void __init init_hwif_it8172 (ide_hwif_t *hwif)
hwif->mwdma_mask = 0x06;
hwif->swdma_mask = 0x04;
-#ifdef CONFIG_BLK_DEV_IDEDMA
hwif->ide_dma_check = &it8172_config_drive_xfer_rate;
if (!noautodma)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* !CONFIG_BLK_DEV_IDEDMA */
}
static void __init init_dma_it8172 (ide_hwif_t *hwif, unsigned long dmabase)
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
index 2db48b09bd61..8454a0e4b8ce 100644
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -83,7 +83,6 @@ static void ns87415_selectproc (ide_drive_t *drive)
ns87415_prepare_drive (drive, drive->using_dma);
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
static int ns87415_ide_dma_end (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -132,7 +131,6 @@ static int ns87415_ide_dma_check (ide_drive_t *drive)
return HWIF(drive)->ide_dma_off_quietly(drive);
return __ide_dma_check(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
static void __init init_hwif_ns87415 (ide_hwif_t *hwif)
{
@@ -209,7 +207,6 @@ static void __init init_hwif_ns87415 (ide_hwif_t *hwif)
if (!hwif->dma_base)
return;
-#ifdef CONFIG_BLK_DEV_IDEDMA
hwif->OUTB(0x60, hwif->dma_status);
hwif->ide_dma_read = &ns87415_ide_dma_read;
hwif->ide_dma_write = &ns87415_ide_dma_write;
@@ -220,7 +217,6 @@ static void __init init_hwif_ns87415 (ide_hwif_t *hwif)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
static void __init init_dma_ns87415 (ide_hwif_t *hwif, unsigned long dmabase)
diff --git a/drivers/ide/pci/nvidia.c b/drivers/ide/pci/nvidia.c
index 65c9f87a1487..fc9338765406 100644
--- a/drivers/ide/pci/nvidia.c
+++ b/drivers/ide/pci/nvidia.c
@@ -38,7 +38,7 @@ static struct pci_dev *bmide_dev;
static int nforce_get_info (char *buffer, char **addr, off_t offset, int count)
{
char *p = buffer;
- u32 bibma = pci_resource_start(bmide_dev, 4);
+ unsigned long bibma = pci_resource_start(bmide_dev, 4);
u8 c0 = 0, c1 = 0;
/*
@@ -109,7 +109,6 @@ static int nforce_tune_chipset (ide_drive_t *drive, u8 xferspeed)
pio_timing &= ~(0x03 << drive->dn);
switch(speed) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_UDMA_7:
case XFER_UDMA_6:
speed = XFER_UDMA_5;
@@ -155,7 +154,6 @@ static int nforce_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_SW_DMA_0:
dma_pio_timing |= 0xA8;
break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4:
dma_pio_timing |= 0x20;
break;
@@ -176,9 +174,7 @@ static int nforce_tune_chipset (ide_drive_t *drive, u8 xferspeed)
pio_timing |= (0x03 << drive->dn);
-#ifdef CONFIG_BLK_DEV_IDEDMA
pci_write_config_byte(dev, drive_pci[drive->dn], ultra_timing);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
pci_write_config_byte(dev, drive_pci2[drive->dn], dma_pio_timing);
pci_write_config_byte(dev, 0x5c, pio_timing);
@@ -191,7 +187,6 @@ static void nforce_tune_drive (ide_drive_t *drive, u8 pio)
(void) nforce_tune_chipset(drive, (XFER_PIO_0 + pio));
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
/*
* This allows the configuration of ide_pci chipset registers
* for cards that learn about the drive's UDMA, DMA, PIO capabilities
@@ -251,9 +246,8 @@ no_dma_set:
}
return hwif->ide_dma_on(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-unsigned int __init init_chipset_nforce (struct pci_dev *dev, const char *name)
+static unsigned int __init init_chipset_nforce (struct pci_dev *dev, const char *name)
{
#if defined(DISPLAY_NFORCE_TIMINGS) && defined(CONFIG_PROC_FS)
if (!nforce_proc) {
@@ -318,7 +312,6 @@ static void __init init_hwif_nforce (ide_hwif_t *hwif)
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (!(hwif->udma_four))
hwif->udma_four = ata66_nforce(hwif);
hwif->ide_dma_check = &nforce_config_drive_xfer_rate;
@@ -326,7 +319,6 @@ static void __init init_hwif_nforce (ide_hwif_t *hwif)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
/* FIXME - not needed */
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
index ce01ae01d410..85720602813d 100644
--- a/drivers/ide/pci/opti621.c
+++ b/drivers/ide/pci/opti621.c
@@ -343,13 +343,10 @@ static void __init init_hwif_opti621 (ide_hwif_t *hwif)
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (!noautodma)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-
}
static void __init init_dma_opti621 (ide_hwif_t *hwif, unsigned long dmabase)
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index fe23fe04a2ab..aa19afbb86b7 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -165,7 +165,6 @@ static int pdcnew_tune_chipset (ide_drive_t *drive, u8 xferspeed)
pci_read_config_byte(dev, (drive_pci), &AP);
pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
} else {
if ((BP & 0xF0) && (CP & 0x0F)) {
/* clear DMA modes of upper 842 bits of B Register */
@@ -177,7 +176,6 @@ static int pdcnew_tune_chipset (ide_drive_t *drive, u8 xferspeed)
pci_write_config_byte(dev, (drive_pci)|0x02, CP &~0x0F);
pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
pci_read_config_byte(dev, (drive_pci), &AP);
@@ -185,7 +183,6 @@ static int pdcnew_tune_chipset (ide_drive_t *drive, u8 xferspeed)
pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
switch(speed) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_UDMA_6: speed = XFER_UDMA_5;
case XFER_UDMA_5:
case XFER_UDMA_4: TB = 0x20; TC = 0x01; break;
@@ -199,7 +196,6 @@ static int pdcnew_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break;
case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break;
case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4: TA = 0x01; TB = 0x04; break;
case XFER_PIO_3: TA = 0x02; TB = 0x06; break;
case XFER_PIO_2: TA = 0x03; TB = 0x08; break;
@@ -211,11 +207,9 @@ static int pdcnew_tune_chipset (ide_drive_t *drive, u8 xferspeed)
if (speed < XFER_SW_DMA_0) {
pci_write_config_byte(dev, (drive_pci), AP|TA);
pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
-#ifdef CONFIG_BLK_DEV_IDEDMA
} else {
pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
#if PDC202XX_DECODE_REGISTER_INFO
@@ -243,28 +237,18 @@ static int pdcnew_tune_chipset (ide_drive_t *drive, u8 xferspeed)
static int pdcnew_new_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
ide_hwif_t *hwif = HWIF(drive);
-#ifdef CONFIG_BLK_DEV_IDEDMA
u32 indexreg = hwif->dma_vendor1;
u32 datareg = hwif->dma_vendor3;
-#else /* !CONFIG_BLK_DEV_IDEDMA */
- struct pci_dev *dev = hwif->pci_dev;
- u32 high_16 = pci_resource_start(dev, 4);
- u32 indexreg = high_16 + (hwif->channel ? 0x09 : 0x01);
- u32 datareg = (indexreg + 2);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
u8 thold = 0x10;
u8 adj = (drive->dn%2) ? 0x08 : 0x00;
u8 speed = ide_rate_filter(pdcnew_ratemask(drive), xferspeed);
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (speed == XFER_UDMA_2) {
hwif->OUTB((thold + adj), indexreg);
hwif->OUTB((hwif->INB(datareg) & 0x7f), datareg);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
switch (speed) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_UDMA_7:
speed = XFER_UDMA_6;
case XFER_UDMA_6: set_ultra(0x1a, 0x01, 0xcb); break;
@@ -277,7 +261,6 @@ static int pdcnew_new_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_MW_DMA_2: set_ata2(0x69, 0x25); break;
case XFER_MW_DMA_1: set_ata2(0x6b, 0x27); break;
case XFER_MW_DMA_0: set_ata2(0xdf, 0x5f); break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4: set_pio(0x23, 0x09, 0x25); break;
case XFER_PIO_3: set_pio(0x27, 0x0d, 0x35); break;
case XFER_PIO_2: set_pio(0x23, 0x26, 0x64); break;
@@ -301,7 +284,7 @@ static int config_chipset_for_pio (ide_drive_t *drive, u8 pio)
{
u8 speed = 0;
- pio = (pio == 5) ? 4 : pio;
+ if (pio == 5) pio = 4;
speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL);
return ((int) pdcnew_tune_chipset(drive, speed));
@@ -312,8 +295,6 @@ static void pdcnew_tune_drive (ide_drive_t *drive, u8 pio)
(void) config_chipset_for_pio(drive, pio);
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
-
static u8 pdcnew_new_cable_detect (ide_hwif_t *hwif)
{
hwif->OUTB(0x0b, hwif->dma_vendor1);
@@ -458,8 +439,6 @@ static int pdcnew_ide_dma_timeout(ide_drive_t *drive)
return __ide_dma_timeout(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-
static void pdcnew_new_reset (ide_drive_t *drive)
{
/*
@@ -471,12 +450,8 @@ static void pdcnew_new_reset (ide_drive_t *drive)
static void pdcnew_reset_host (ide_hwif_t *hwif)
{
-#ifdef CONFIG_BLK_DEV_IDEDMA
// unsigned long high_16 = hwif->dma_base - (8*(hwif->channel));
unsigned long high_16 = hwif->dma_master;
-#else /* !CONFIG_BLK_DEV_IDEDMA */
- unsigned long high_16 = pci_resource_start(hwif->pci_dev, 4);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
u8 udma_speed_flag = hwif->INB(high_16|0x001f);
hwif->OUTB((udma_speed_flag | 0x10), (high_16|0x001f));
@@ -571,8 +546,6 @@ static void __init init_hwif_pdc202new (ide_hwif_t *hwif)
hwif->ultra_mask = 0x7f;
hwif->mwdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
-
hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate;
hwif->ide_dma_lostirq = &pdcnew_ide_dma_lostirq;
hwif->ide_dma_timeout = &pdcnew_ide_dma_timeout;
@@ -581,7 +554,6 @@ static void __init init_hwif_pdc202new (ide_hwif_t *hwif)
if (!noautodma)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
#if PDC202_DEBUG_CABLE
printk("%s: %s-pin cable\n",
hwif->name, hwif->udma_four ? "80" : "40");
diff --git a/drivers/ide/pci/pdc202xx_new.h b/drivers/ide/pci/pdc202xx_new.h
index f49a149a8651..c5e7d5ee0a79 100644
--- a/drivers/ide/pci/pdc202xx_new.h
+++ b/drivers/ide/pci/pdc202xx_new.h
@@ -26,41 +26,6 @@ const static char *pdc_quirk_drives[] = {
NULL
};
-static inline u8 *pdcnew_pio_verbose (u32 drive_pci)
-{
- if ((drive_pci & 0x000ff000) == 0x000ff000) return("NOTSET");
- if ((drive_pci & 0x00000401) == 0x00000401) return("PIO 4");
- if ((drive_pci & 0x00000602) == 0x00000602) return("PIO 3");
- if ((drive_pci & 0x00000803) == 0x00000803) return("PIO 2");
- if ((drive_pci & 0x00000C05) == 0x00000C05) return("PIO 1");
- if ((drive_pci & 0x00001309) == 0x00001309) return("PIO 0");
- return("PIO ?");
-}
-
-static inline u8 *pdcnew_dma_verbose (u32 drive_pci)
-{
- if ((drive_pci & 0x00036000) == 0x00036000) return("MWDMA 2");
- if ((drive_pci & 0x00046000) == 0x00046000) return("MWDMA 1");
- if ((drive_pci & 0x00056000) == 0x00056000) return("MWDMA 0");
- if ((drive_pci & 0x00056000) == 0x00056000) return("SWDMA 2");
- if ((drive_pci & 0x00068000) == 0x00068000) return("SWDMA 1");
- if ((drive_pci & 0x000BC000) == 0x000BC000) return("SWDMA 0");
- return("PIO---");
-}
-
-static inline u8 *pdcnew_ultra_verbose (u32 drive_pci, u16 slow_cable)
-{
- if ((drive_pci & 0x000ff000) == 0x000ff000)
- return("NOTSET");
- if ((drive_pci & 0x00012000) == 0x00012000)
- return((slow_cable) ? "UDMA 2" : "UDMA 4");
- if ((drive_pci & 0x00024000) == 0x00024000)
- return((slow_cable) ? "UDMA 1" : "UDMA 3");
- if ((drive_pci & 0x00036000) == 0x00036000)
- return("UDMA 0");
- return(pdcnew_dma_verbose(drive_pci));
-}
-
/* A Register */
#define SYNC_ERRDY_EN 0xC0
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index cda54754c993..48540a9e6794 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -264,7 +264,6 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
pci_read_config_byte(dev, (drive_pci), &AP);
pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
} else {
if ((BP & 0xF0) && (CP & 0x0F)) {
/* clear DMA modes of upper 842 bits of B Register */
@@ -276,7 +275,6 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
pci_write_config_byte(dev, (drive_pci)|0x02, CP &~0x0F);
pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
pci_read_config_byte(dev, (drive_pci), &AP);
@@ -284,7 +282,6 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
switch(speed) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_UDMA_6: speed = XFER_UDMA_5;
case XFER_UDMA_5:
case XFER_UDMA_4: TB = 0x20; TC = 0x01; break;
@@ -298,7 +295,6 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break;
case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break;
case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4: TA = 0x01; TB = 0x04; break;
case XFER_PIO_3: TA = 0x02; TB = 0x06; break;
case XFER_PIO_2: TA = 0x03; TB = 0x08; break;
@@ -310,11 +306,9 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
if (speed < XFER_SW_DMA_0) {
pci_write_config_byte(dev, (drive_pci), AP|TA);
pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
-#ifdef CONFIG_BLK_DEV_IDEDMA
} else {
pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
#if PDC202XX_DECODE_REGISTER_INFO
@@ -347,23 +341,16 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
* 180, 120, 90, 90, 90, 60, 30
* 11, 5, 4, 3, 2, 1, 0
*/
-static int config_chipset_for_pio (ide_drive_t *drive, u8 pio)
+static void config_chipset_for_pio (ide_drive_t *drive, u8 pio)
{
u8 speed = 0;
- pio = (pio == 5) ? 4 : pio;
+ if (pio == 5) pio = 4;
speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL);
- return ((int) pdc202xx_tune_chipset(drive, speed));
+ pdc202xx_tune_chipset(drive, speed);
}
-static void pdc202xx_tune_drive (ide_drive_t *drive, u8 pio)
-{
- (void) config_chipset_for_pio(drive, pio);
-}
-
-#ifdef CONFIG_BLK_DEV_IDEDMA
-
static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
{
u16 CIS = 0, mask = (hwif->channel) ? (1<<11) : (1<<10);
@@ -618,8 +605,6 @@ static int pdc202xx_ide_dma_timeout(ide_drive_t *drive)
return __ide_dma_timeout(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-
static void pdc202xx_reset_host (ide_hwif_t *hwif)
{
#ifdef CONFIG_BLK_DEV_IDEDMA
@@ -692,12 +677,8 @@ void pdc202xx_reset (ide_drive_t *drive)
static int pdc202xx_tristate (ide_drive_t * drive, int state)
{
ide_hwif_t *hwif = HWIF(drive);
-#ifdef CONFIG_BLK_DEV_IDEDMA
// unsigned long high_16 = hwif->dma_base - (8*(hwif->channel));
unsigned long high_16 = hwif->dma_master;
-#else /* !CONFIG_BLK_DEV_IDEDMA */
- unsigned long high_16 = pci_resource_start(hwif->pci_dev, 4);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
u8 sc1f = hwif->INB(high_16|0x001f);
if (!hwif)
@@ -761,7 +742,7 @@ static unsigned int __init init_chipset_pdc202xx (struct pci_dev *dev, const cha
static void __init init_hwif_pdc202xx (ide_hwif_t *hwif)
{
hwif->autodma = 0;
- hwif->tuneproc = &pdc202xx_tune_drive;
+ hwif->tuneproc = &config_chipset_for_pio;
hwif->quirkproc = &pdc202xx_quirkproc;
if (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20265)
@@ -783,8 +764,6 @@ static void __init init_hwif_pdc202xx (ide_hwif_t *hwif)
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
-
hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate;
hwif->ide_dma_lostirq = &pdc202xx_ide_dma_lostirq;
hwif->ide_dma_timeout = &pdc202xx_ide_dma_timeout;
@@ -800,7 +779,6 @@ static void __init init_hwif_pdc202xx (ide_hwif_t *hwif)
if (!noautodma)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
#if PDC202_DEBUG_CABLE
printk("%s: %s-pin cable\n",
hwif->name, hwif->udma_four ? "80" : "40");
diff --git a/drivers/ide/pci/pdcadma.c b/drivers/ide/pci/pdcadma.c
index 30fcc63038dd..6f2c56e3717a 100644
--- a/drivers/ide/pci/pdcadma.c
+++ b/drivers/ide/pci/pdcadma.c
@@ -55,7 +55,6 @@ static int pdcadma_get_info (char *buffer, char **addr, off_t offset, int count)
}
#endif /* defined(DISPLAY_PDCADMA_TIMINGS) && defined(CONFIG_PROC_FS) */
-#ifdef CONFIG_BLK_DEV_IDEDMA
/*
* pdcadma_dma functions() initiates/aborts (U)DMA read/write
* operations on a drive.
@@ -82,8 +81,6 @@ static int pdcadma_get_info (char *buffer, char **addr, off_t offset, int count)
#endif
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-
static unsigned int __init init_chipset_pdcadma (struct pci_dev *dev, const char *name)
{
#if defined(DISPLAY_PDCADMA_TIMINGS) && defined(CONFIG_PROC_FS)
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index 87ad4e277bae..59a90b03f285 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -373,7 +373,7 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u8 maslave = hwif->channel ? 0x42 : 0x40;
- u8 speed = ide_rate_filter(piix_ratemask(drive), xferspeed);
+ u8 speed = ide_rate_filter(piix_ratemask(drive), xferspeed);
int a_speed = 3 << (drive->dn * 4);
int u_flag = 1 << drive->dn;
int v_flag = 0x01 << drive->dn;
@@ -392,7 +392,6 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
pci_read_config_byte(dev, 0x55, &reg55);
switch(speed) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_UDMA_4:
case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break;
case XFER_UDMA_5:
@@ -402,7 +401,6 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_SW_DMA_2: break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4:
case XFER_PIO_3:
case XFER_PIO_2:
@@ -444,8 +442,6 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
return (ide_config_drive_speed(drive, speed));
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
-
/**
* piix_config_drive_for_dma - configure drive for DMA
* @drive: IDE drive to configure
@@ -518,7 +514,6 @@ no_dma_set:
}
return hwif->ide_dma_on(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
/**
* init_chipset_piix - set up the PIIX chipset
@@ -570,10 +565,8 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char
static void __init init_hwif_piix (ide_hwif_t *hwif)
{
-#ifdef CONFIG_BLK_DEV_IDEDMA
u8 reg54h = 0, reg55h = 0, ata66 = 0;
u8 mask = hwif->channel ? 0xc0 : 0x30;
-#endif /* !CONFIG_BLK_DEV_IDEDMA */
#ifndef CONFIG_IA64
if (!hwif->irq)
@@ -599,7 +592,6 @@ static void __init init_hwif_piix (ide_hwif_t *hwif)
hwif->mwdma_mask = 0x06;
hwif->swdma_mask = 0x04;
-#ifdef CONFIG_BLK_DEV_IDEDMA
switch(hwif->pci_dev->device) {
case PCI_DEVICE_ID_INTEL_82371MX:
hwif->mwdma_mask = 0x80;
@@ -630,7 +622,6 @@ static void __init init_hwif_piix (ide_hwif_t *hwif)
hwif->drives[1].autodma = hwif->autodma;
hwif->drives[0].autodma = hwif->autodma;
-#endif /* !CONFIG_BLK_DEV_IDEDMA */
}
/**
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
new file mode 100644
index 000000000000..abfbd453bf9b
--- /dev/null
+++ b/drivers/ide/pci/sc1200.c
@@ -0,0 +1,593 @@
+/*
+ * linux/drivers/ide/sc1200.c Version 0.9 24-Oct-2002
+ *
+ * Copyright (C) 2000-2002 Mark Lord <mlord@pobox.com>
+ * May be copied or modified under the terms of the GNU General Public License
+ *
+ * Development of this chipset driver was funded
+ * by the nice folks at National Semiconductor.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+#include <linux/pm.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "ide_modes.h"
+#include "sc1200.h"
+
+#define DISPLAY_SC1200_TIMINGS
+
+#if defined(DISPLAY_SC1200_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static int sc1200_get_info(char *, char **, off_t, int);
+extern int (*sc1200_display_info)(char *, char **, off_t, int); /* ide-proc.c */
+extern char *ide_media_verbose(ide_drive_t *);
+static u8 sc1200_proc = 0;
+
+#define SC1200_REV_A 0x00
+#define SC1200_REV_B1 0x01
+#define SC1200_REV_B3 0x02
+#define SC1200_REV_C1 0x03
+#define SC1200_REV_D1 0x04
+
+#define PCI_CLK_33 0x00
+#define PCI_CLK_48 0x01
+#define PCI_CLK_66 0x02
+#define PCI_CLK_33A 0x03
+
+static unsigned short sc1200_get_pci_clock (void)
+{
+ unsigned char chip_id, silicon_revision;
+ unsigned int pci_clock;
+ /*
+ * Check the silicon revision, as not all versions of the chip
+ * have the register with the fast PCI bus timings.
+ */
+ chip_id = inb (0x903c);
+ silicon_revision = inb (0x903d);
+
+ // Read the fast pci clock frequency
+ if (chip_id == 0x04 && silicon_revision < SC1200_REV_B1) {
+ pci_clock = PCI_CLK_33;
+ } else {
+ // check clock generator configuration (cfcc)
+ // the clock is in bits 8 and 9 of this word
+
+ pci_clock = inw (0x901e);
+ pci_clock >>= 8;
+ pci_clock &= 0x03;
+ if (pci_clock == PCI_CLK_33A)
+ pci_clock = PCI_CLK_33;
+ }
+ return pci_clock;
+}
+
+static struct pci_dev *bmide_dev;
+
+static int sc1200_get_info (char *buffer, char **addr, off_t offset, int count)
+{
+ char *p = buffer;
+ u32 bibma = pci_resource_start(bmide_dev, 4);
+ u8 c0 = 0, c1 = 0;
+
+ /*
+ * at that point bibma+0x2 et bibma+0xa are byte registers
+ * to investigate:
+ */
+
+ c0 = inb_p((unsigned short)bibma + 0x02);
+ c1 = inb_p((unsigned short)bibma + 0x0a);
+
+ p += sprintf(p, "\n National SCx200 Chipset.\n");
+ p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
+ p += sprintf(p, " %sabled %sabled\n",
+ (c0&0x80) ? "dis" : " en",
+ (c1&0x80) ? "dis" : " en");
+ p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
+ p += sprintf(p, "DMA enabled: %s %s %s %s\n",
+ (c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
+ (c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
+
+ p += sprintf(p, "UDMA\n");
+ p += sprintf(p, "DMA\n");
+ p += sprintf(p, "PIO\n");
+
+ return p-buffer;
+}
+#endif /* DISPLAY_SC1200_TIMINGS && CONFIG_PROC_FS */
+
+extern char *ide_xfer_verbose (byte xfer_rate);
+
+/*
+ * Set a new transfer mode at the drive
+ */
+int sc1200_set_xfer_mode (ide_drive_t *drive, byte mode)
+{
+ printk("%s: sc1200_set_xfer_mode(%s)\n", drive->name, ide_xfer_verbose(mode));
+ return ide_config_drive_speed(drive, mode);
+}
+
+/*
+ * Here are the standard PIO mode 0-4 timings for each "format".
+ * Format-0 uses fast data reg timings, with slower command reg timings.
+ * Format-1 uses fast timings for all registers, but won't work with all drives.
+ */
+static const unsigned int sc1200_pio_timings[4][5] =
+ {{0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010}, // format0 33Mhz
+ {0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010}, // format1, 33Mhz
+ {0xfaa3f4f3, 0xc23232b2, 0x513101c1, 0x31213121, 0x10211021}, // format1, 48Mhz
+ {0xfff4fff4, 0xf35353d3, 0x814102f1, 0x42314231, 0x11311131}}; // format1, 66Mhz
+
+/*
+ * After chip reset, the PIO timings are set to 0x00009172, which is not valid.
+ */
+//#define SC1200_BAD_PIO(timings) (((timings)&~0x80000000)==0x00009172)
+
+static int sc1200_autoselect_dma_mode (ide_drive_t *drive)
+{
+ int udma_ok = 1, mode = 0;
+ ide_hwif_t *hwif = HWIF(drive);
+ int unit = drive->select.b.unit;
+ ide_drive_t *mate = &hwif->drives[unit^1];
+ struct hd_driveid *id = drive->id;
+
+ /*
+ * The SC1200 specifies that two drives sharing a cable cannot
+ * mix UDMA/MDMA. It has to be one or the other, for the pair,
+ * though different timings can still be chosen for each drive.
+ * We could set the appropriate timing bits on the fly,
+ * but that might be a bit confusing. So, for now we statically
+ * handle this requirement by looking at our mate drive to see
+ * what it is capable of, before choosing a mode for our own drive.
+ */
+ if (mate->present) {
+ struct hd_driveid *mateid = mate->id;
+ if (mateid && (mateid->capability & 1) && !hwif->ide_dma_bad_drive(mate)) {
+ if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7))
+ udma_ok = 1;
+ else if ((mateid->field_valid & 2) && (mateid->dma_mword & 7))
+ udma_ok = 0;
+ else
+ udma_ok = 1;
+ }
+ }
+ /*
+ * Now see what the current drive is capable of,
+ * selecting UDMA only if the mate said it was ok.
+ */
+ if (id && (id->capability & 1) && hwif->autodma && !hwif->ide_dma_bad_drive(drive)) {
+ if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) {
+ if (id->dma_ultra & 4)
+ mode = XFER_UDMA_2;
+ else if (id->dma_ultra & 2)
+ mode = XFER_UDMA_1;
+ else if (id->dma_ultra & 1)
+ mode = XFER_UDMA_0;
+ }
+ if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) {
+ if (id->dma_mword & 4)
+ mode = XFER_MW_DMA_2;
+ else if (id->dma_mword & 2)
+ mode = XFER_MW_DMA_1;
+ else if (id->dma_mword & 1)
+ mode = XFER_MW_DMA_0;
+ }
+ }
+ return mode;
+}
+
+/*
+ * sc1200_config_dma2() handles selection/setting of DMA/UDMA modes
+ * for both the chipset and drive.
+ */
+static int sc1200_config_dma2 (ide_drive_t *drive, int mode)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ int unit = drive->select.b.unit;
+ unsigned int reg, timings;
+ unsigned short pci_clock;
+ unsigned int basereg = hwif->channel ? 0x50 : 0x40;
+
+ /*
+ * Default to DMA-off in case we run into trouble here.
+ */
+ hwif->ide_dma_off_quietly(drive); /* turn off DMA while we fiddle */
+ outb(inb(hwif->dma_base+2)&~(unit?0x40:0x20), hwif->dma_base+2); /* clear DMA_capable bit */
+
+ /*
+ * Tell the drive to switch to the new mode; abort on failure.
+ */
+ if (!mode || sc1200_set_xfer_mode(drive, mode)) {
+ printk("SC1200: set xfer mode failure\n");
+ return 1; /* failure */
+ }
+
+ pci_clock = sc1200_get_pci_clock();
+
+ /*
+ * Now tune the chipset to match the drive:
+ *
+ * Note that each DMA mode has several timings associated with it.
+ * The correct timing depends on the fast PCI clock freq.
+ */
+ timings = 0;
+ switch (mode) {
+ case XFER_UDMA_0:
+ switch (pci_clock) {
+ case PCI_CLK_33: timings = 0x00921250; break;
+ case PCI_CLK_48: timings = 0x00932470; break;
+ case PCI_CLK_66: timings = 0x009436a1; break;
+ }
+ break;
+ case XFER_UDMA_1:
+ switch (pci_clock) {
+ case PCI_CLK_33: timings = 0x00911140; break;
+ case PCI_CLK_48: timings = 0x00922260; break;
+ case PCI_CLK_66: timings = 0x00933481; break;
+ }
+ break;
+ case XFER_UDMA_2:
+ switch (pci_clock) {
+ case PCI_CLK_33: timings = 0x00911030; break;
+ case PCI_CLK_48: timings = 0x00922140; break;
+ case PCI_CLK_66: timings = 0x00923261; break;
+ }
+ break;
+ case XFER_MW_DMA_0:
+ switch (pci_clock) {
+ case PCI_CLK_33: timings = 0x00077771; break;
+ case PCI_CLK_48: timings = 0x000bbbb2; break;
+ case PCI_CLK_66: timings = 0x000ffff3; break;
+ }
+ break;
+ case XFER_MW_DMA_1:
+ switch (pci_clock) {
+ case PCI_CLK_33: timings = 0x00012121; break;
+ case PCI_CLK_48: timings = 0x00024241; break;
+ case PCI_CLK_66: timings = 0x00035352; break;
+ }
+ break;
+ case XFER_MW_DMA_2:
+ switch (pci_clock) {
+ case PCI_CLK_33: timings = 0x00002020; break;
+ case PCI_CLK_48: timings = 0x00013131; break;
+ case PCI_CLK_66: timings = 0x00015151; break;
+ }
+ break;
+ }
+
+ if (timings == 0) {
+ printk("%s: sc1200_config_dma: huh? mode=%02x clk=%x \n", drive->name, mode, pci_clock);
+ return 1; /* failure */
+ }
+
+ if (unit == 0) { /* are we configuring drive0? */
+ pci_read_config_dword(hwif->pci_dev, basereg+4, &reg);
+ timings |= reg & 0x80000000; /* preserve PIO format bit */
+ pci_write_config_dword(hwif->pci_dev, basereg+4, timings);
+ } else {
+ pci_write_config_dword(hwif->pci_dev, basereg+12, timings);
+ }
+
+ outb(inb(hwif->dma_base+2)|(unit?0x40:0x20), hwif->dma_base+2); /* set DMA_capable bit */
+
+ /*
+ * Finally, turn DMA on in software, and exit.
+ */
+ return hwif->ide_dma_on(drive); /* success */
+}
+
+/*
+ * sc1200_config_dma() handles selection/setting of DMA/UDMA modes
+ * for both the chipset and drive.
+ */
+static int sc1200_config_dma (ide_drive_t *drive)
+{
+ return sc1200_config_dma2(drive, sc1200_autoselect_dma_mode(drive));
+}
+
+
+/* Replacement for the standard ide_dma_end action in
+ * dma_proc.
+ *
+ * returns 1 on error, 0 otherwise
+ */
+int sc1200_ide_dma_end (ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ unsigned long dma_base = hwif->dma_base;
+ byte dma_stat;
+
+ dma_stat = inb(dma_base+2); /* get DMA status */
+
+ if (!(dma_stat & 4))
+ printk(" ide_dma_end dma_stat=%0x err=%x newerr=%x\n",
+ dma_stat, ((dma_stat&7)!=4), ((dma_stat&2)==2));
+
+ outb(dma_stat|0x1b, dma_base+2); /* clear the INTR & ERROR bits */
+ outb(inb(dma_base)&~1, dma_base); /* !! DO THIS HERE !! stop DMA */
+
+ drive->waiting_for_dma = 0;
+ ide_destroy_dmatable(drive); /* purge DMA mappings */
+
+ return (dma_stat & 7) != 4; /* verify good DMA status */
+}
+
+/*
+ * sc1200_tuneproc() handles selection/setting of PIO modes
+ * for both the chipset and drive.
+ *
+ * All existing BIOSs for this chipset guarantee that all drives
+ * will have valid default PIO timings set up before we get here.
+ */
+static void sc1200_tuneproc (ide_drive_t *drive, byte pio) /* mode=255 means "autotune" */
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ unsigned int format;
+ static byte modes[5] = {XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, XFER_PIO_4};
+ int mode = -1;
+
+ switch (pio) {
+ case 200: mode = XFER_UDMA_0; break;
+ case 201: mode = XFER_UDMA_1; break;
+ case 202: mode = XFER_UDMA_2; break;
+ case 100: mode = XFER_MW_DMA_0; break;
+ case 101: mode = XFER_MW_DMA_1; break;
+ case 102: mode = XFER_MW_DMA_2; break;
+ }
+ if (mode != -1) {
+ printk("SC1200: %s: changing (U)DMA mode\n", drive->name);
+ (void)sc1200_config_dma2(drive, mode);
+ return;
+ }
+
+ pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+ printk("SC1200: %s: setting PIO mode%d\n", drive->name, pio);
+ if (!sc1200_set_xfer_mode(drive, modes[pio])) {
+ unsigned int basereg = hwif->channel ? 0x50 : 0x40;
+ pci_read_config_dword (hwif->pci_dev, basereg+4, &format);
+ format = (format >> 31) & 1;
+ if (format)
+ format += sc1200_get_pci_clock();
+ pci_write_config_dword(hwif->pci_dev, basereg + (drive->select.b.unit << 3), sc1200_pio_timings[format][pio]);
+ }
+}
+
+static ide_hwif_t *lookup_pci_dev (ide_hwif_t *prev, struct pci_dev *dev)
+{
+ int h;
+
+ for (h = 0; h < MAX_HWIFS; h++) {
+ ide_hwif_t *hwif = &ide_hwifs[h];
+ if (prev) {
+ if (hwif == prev)
+ prev = NULL; // found previous, now look for next match
+ } else {
+ if (hwif && hwif->pci_dev == dev)
+ return hwif; // found next match
+ }
+ }
+ return NULL; // not found
+}
+
+typedef struct sc1200_saved_state_s {
+ __u32 regs[4];
+} sc1200_saved_state_t;
+
+static int sc1200_save_state (struct pci_dev *dev, u32 state)
+{
+ ide_hwif_t *hwif = NULL;
+
+printk("SC1200: save_state(%u)\n", state);
+ if (state != 0)
+ return 0; // we only save state when going from full power to less
+ //
+ // Loop over all interfaces that are part of this PCI device:
+ //
+ while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) {
+ sc1200_saved_state_t *ss;
+ unsigned int basereg, r;
+ //
+ // allocate a permanent save area, if not already allocated
+ //
+ ss = (sc1200_saved_state_t *)hwif->config_data;
+ if (ss == NULL) {
+ ss = kmalloc(sizeof(sc1200_saved_state_t), GFP_KERNEL);
+ if (ss == NULL)
+ return -ENOMEM;
+ (sc1200_saved_state_t *)hwif->config_data = ss;
+ }
+ ss = (sc1200_saved_state_t *)hwif->config_data;
+ //
+ // Save timing registers: this may be unnecessary if BIOS also does it
+ //
+ basereg = hwif->channel ? 0x50 : 0x40;
+ for (r = 0; r < 4; ++r) {
+ pci_read_config_dword (hwif->pci_dev, basereg + (r<<2), &ss->regs[r]);
+ }
+ }
+ return 0;
+}
+
+static int sc1200_suspend (struct pci_dev *dev, u32 state)
+{
+ ide_hwif_t *hwif = NULL;
+
+ printk("SC1200: suspend(%u)\n", state);
+ /* You don't need to iterate over disks -- sysfs should have done that for you already */
+
+ pci_disable_device(dev);
+ pci_set_power_state(dev,state);
+ dev->current_state = state;
+ return 0;
+}
+
+static int sc1200_resume (struct pci_dev *dev)
+{
+ ide_hwif_t *hwif = NULL;
+
+printk("SC1200: resume\n");
+ pci_set_power_state(dev,0); // bring chip back from sleep state
+ dev->current_state = 0;
+ pci_enable_device(dev);
+ //
+ // loop over all interfaces that are part of this pci device:
+ //
+ while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) {
+ unsigned int basereg, r, d, format;
+ sc1200_saved_state_t *ss = (sc1200_saved_state_t *)hwif->config_data;
+printk("%s: SC1200: resume\n", hwif->name);
+
+ //
+ // Restore timing registers: this may be unnecessary if BIOS also does it
+ //
+ basereg = hwif->channel ? 0x50 : 0x40;
+ if (ss != NULL) {
+ for (r = 0; r < 4; ++r) {
+ pci_write_config_dword(hwif->pci_dev, basereg + (r<<2), ss->regs[r]);
+ }
+ }
+ //
+ // Re-program drive PIO modes
+ //
+ pci_read_config_dword(hwif->pci_dev, basereg+4, &format);
+ format = (format >> 31) & 1;
+ if (format)
+ format += sc1200_get_pci_clock();
+ for (d = 0; d < 2; ++d) {
+ ide_drive_t *drive = &(hwif->drives[d]);
+ if (drive->present) {
+ unsigned int pio, timings;
+ pci_read_config_dword(hwif->pci_dev, basereg+(drive->select.b.unit << 3), &timings);
+ for (pio = 0; pio <= 4; ++pio) {
+ if (sc1200_pio_timings[format][pio] == timings)
+ break;
+ }
+ if (pio > 4)
+ pio = 255; /* autotune */
+ (void)sc1200_tuneproc(drive, pio);
+ }
+ }
+ //
+ // Re-program drive DMA modes
+ //
+ for (d = 0; d < MAX_DRIVES; ++d) {
+ ide_drive_t *drive = &(hwif->drives[d]);
+ if (drive->present && !hwif->ide_dma_bad_drive(drive)) {
+ int was_using_dma = drive->using_dma;
+ hwif->ide_dma_off_quietly(drive);
+ sc1200_config_dma(drive);
+ if (!was_using_dma && drive->using_dma) {
+ hwif->ide_dma_off_quietly(drive);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ * Initialize the sc1200 bridge for reliable IDE DMA operation.
+ */
+static unsigned int __init init_chipset_sc1200 (struct pci_dev *dev, const char *name)
+{
+#if defined(DISPLAY_SC1200_TIMINGS) && defined(CONFIG_PROC_FS)
+ if (!bmide_dev) {
+ sc1200_proc = 1;
+ bmide_dev = dev;
+ ide_pci_register_host_proc(&sc1200_procs[0]);
+ }
+#endif /* DISPLAY_SC1200_TIMINGS && CONFIG_PROC_FS */
+ return 0;
+}
+
+/*
+ * This gets invoked by the IDE driver once for each channel,
+ * and performs channel-specific pre-initialization before drive probing.
+ */
+static void __init init_hwif_sc1200 (ide_hwif_t *hwif)
+{
+ if (hwif->mate)
+ hwif->serialized = hwif->mate->serialized = 1;
+ hwif->autodma = 0;
+ if (hwif->dma_base) {
+ hwif->ide_dma_check = &sc1200_config_dma;
+ hwif->ide_dma_end = &sc1200_ide_dma_end;
+ if (!noautodma)
+ hwif->autodma = 1;
+ hwif->tuneproc = &sc1200_tuneproc;
+ }
+ hwif->atapi_dma = 1;
+ hwif->ultra_mask = 0x07;
+ hwif->mwdma_mask = 0x07;
+
+ hwif->drives[0].autodma = hwif->autodma;
+ hwif->drives[1].autodma = hwif->autodma;
+}
+
+static void __init init_dma_sc1200 (ide_hwif_t *hwif, unsigned long dmabase)
+{
+ ide_setup_dma(hwif, dmabase, 8);
+}
+
+extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
+
+
+static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ ide_pci_device_t *d = &sc1200_chipsets[id->driver_data];
+ if (dev->device != d->device)
+ BUG();
+ ide_setup_pci_device(dev, d);
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static struct pci_device_id sc1200_pci_tbl[] __devinitdata = {
+ { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { 0, },
+};
+
+static struct pci_driver driver = {
+ .name = "SC1200 IDE",
+ .id_table = sc1200_pci_tbl,
+ .probe = sc1200_init_one,
+ .save_state = sc1200_save_state,
+ .suspend = sc1200_suspend,
+ .resume = sc1200_resume,
+};
+
+static int sc1200_ide_init(void)
+{
+ return ide_pci_register_driver(&driver);
+}
+
+static void sc1200_ide_exit(void)
+{
+ ide_pci_unregister_driver(&driver);
+}
+
+module_init(sc1200_ide_init);
+module_exit(sc1200_ide_exit);
+
+MODULE_AUTHOR("Mark Lord");
+MODULE_DESCRIPTION("PCI driver module for NS SC1200 IDE");
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
diff --git a/drivers/ide/pci/sc1200.h b/drivers/ide/pci/sc1200.h
new file mode 100644
index 000000000000..812190ca7f36
--- /dev/null
+++ b/drivers/ide/pci/sc1200.h
@@ -0,0 +1,54 @@
+#ifndef SC1200_H
+#define SC1200_H
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+
+#define DISPLAY_SC1200_TIMINGS
+
+#if defined(DISPLAY_SC1200_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static u8 sc1200_proc;
+
+static int sc1200_get_info(char *, char **, off_t, int);
+
+static ide_pci_host_proc_t sc1200_procs[] __initdata = {
+ {
+ name: "sc1200",
+ set: 1,
+ get_info: sc1200_get_info,
+ parent: NULL,
+ },
+};
+#endif /* DISPLAY_SC1200_TIMINGS && CONFIG_PROC_FS */
+
+static unsigned int init_chipset_sc1200(struct pci_dev *, const char *);
+static void init_hwif_sc1200(ide_hwif_t *);
+static void init_dma_sc1200(ide_hwif_t *, unsigned long);
+
+static ide_pci_device_t sc1200_chipsets[] __devinitdata = {
+ { /* 0 */
+ vendor: PCI_VENDOR_ID_NS,
+ device: PCI_DEVICE_ID_NS_SCx200_IDE,
+ name: "SC1200",
+ init_chipset: init_chipset_sc1200,
+ init_iops: NULL,
+ init_hwif: init_hwif_sc1200,
+ init_dma: init_dma_sc1200,
+ channels: 2,
+ autodma: AUTODMA,
+ enablebits: {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+ bootable: ON_BOARD,
+ extra: 0,
+ },{
+ vendor: 0,
+ device: 0,
+ channels: 0,
+ bootable: EOL,
+ }
+};
+
+#endif /* SC1200_H */
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index cc927007899c..1b7c6837f258 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -251,7 +251,7 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
- u8 speed = ide_rate_filter(svwks_ratemask(drive), xferspeed);
+ u8 speed = ide_rate_filter(svwks_ratemask(drive), xferspeed);
u8 pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
u8 unit = (drive->select.b.unit & 0x01);
u8 csb5 = svwks_csb_check(dev);
@@ -259,6 +259,13 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
u8 dma_timing = 0, pio_timing = 0;
u16 csb5_pio = 0;
+ /* If we are about to put a disk into UDMA mode we screwed up.
+ Our code assumes we never _ever_ do this on an OSB4 */
+
+ if(dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4 &&
+ drive->media != ide_disk && speed >= XFER_UDMA_0)
+ BUG();
+
pci_read_config_byte(dev, drive_pci[drive->dn], &pio_timing);
pci_read_config_byte(dev, drive_pci2[drive->dn], &dma_timing);
pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing);
@@ -331,7 +338,6 @@ oem_setup_failed:
csb5_pio |= ((speed - XFER_PIO_0) << (4*drive->dn));
break;
-#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_MW_DMA_0:
@@ -351,7 +357,6 @@ oem_setup_failed:
dma_timing |= dma_modes[2];
ultra_timing |= ((udma_modes[speed - XFER_UDMA_0]) << (4*unit));
ultra_enable |= (0x01 << drive->dn);
-#endif
default:
break;
}
@@ -360,11 +365,9 @@ oem_setup_failed:
if (csb5)
pci_write_config_word(dev, 0x4A, csb5_pio);
-#ifdef CONFIG_BLK_DEV_IDEDMA
pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing);
pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing);
pci_write_config_byte(dev, 0x54, ultra_enable);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
return (ide_config_drive_speed(drive, speed));
}
@@ -412,7 +415,6 @@ static void svwks_tune_drive (ide_drive_t *drive, u8 pio)
(void) svwks_tune_chipset(drive, (XFER_PIO_0 + pio));
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
static int config_chipset_for_dma (ide_drive_t *drive)
{
u8 speed = ide_dma_speed(drive, svwks_ratemask(drive));
@@ -470,6 +472,12 @@ no_dma_set:
static int svwks_ide_dma_end (ide_drive_t *drive)
{
+ /*
+ * We never place the OSB4 into a UDMA mode with a disk
+ * medium, that means the UDMA "all my data is 4 byte shifted"
+ * problem cannot occur.
+ */
+#if 0
ide_hwif_t *hwif = HWIF(drive);
u8 dma_stat = hwif->INB(hwif->dma_status);
@@ -483,9 +491,9 @@ static int svwks_ide_dma_end (ide_drive_t *drive)
while(1)
cpu_relax();
}
+#endif
return __ide_dma_end(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
static unsigned int __init init_chipset_svwks (struct pci_dev *dev, const char *name)
{
@@ -703,7 +711,6 @@ static void __init init_hwif_svwks (ide_hwif_t *hwif)
return;
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
hwif->ide_dma_check = &svwks_config_drive_xfer_rate;
if (hwif->pci_dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE)
hwif->ide_dma_end = &svwks_ide_dma_end;
@@ -719,7 +726,6 @@ static void __init init_hwif_svwks (ide_hwif_t *hwif)
hwif->drives[1].autotune = (!(dma_stat & 0x40));
// hwif->drives[0].autodma = hwif->autodma;
// hwif->drives[1].autodma = hwif->autodma;
-#endif /* !CONFIG_BLK_DEV_IDEDMA */
}
/*
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index d1d21b1e65a7..bdc8cd8848fa 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -205,7 +205,6 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed)
siimage_tuneproc(drive, (speed - XFER_PIO_0));
mode |= ((unit) ? 0x10 : 0x01);
break;
-#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_MW_DMA_0:
@@ -226,7 +225,6 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed)
mode |= ((unit) ? 0x30 : 0x03);
config_siimage_chipset_for_pio(drive, 0);
break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
default:
return 1;
}
@@ -246,7 +244,6 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed)
return (ide_config_drive_speed(drive, speed));
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
static int config_chipset_for_dma (ide_drive_t *drive)
{
u8 speed = ide_dma_speed(drive, siimage_ratemask(drive));
@@ -256,7 +253,7 @@ static int config_chipset_for_dma (ide_drive_t *drive)
if ((!(speed)))
return 0;
- if (HWIF(drive)->speedproc(drive, speed))
+ if (ide_set_xfer_rate(drive, speed))
return 0;
if (!drive->init_speed)
@@ -392,7 +389,6 @@ static int siimage_mmio_ide_dma_verbose (ide_drive_t *drive)
#endif
return temp;
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
static int siimage_busproc (ide_drive_t * drive, int state)
{
@@ -811,7 +807,6 @@ static void __init init_hwif_siimage (ide_hwif_t *hwif)
if (hwif->pci_dev->device != PCI_DEVICE_ID_SII_3112)
hwif->atapi_dma = 1;
-#ifdef CONFIG_BLK_DEV_IDEDMA
hwif->ide_dma_check = &siimage_config_drive_for_dma;
if (!(hwif->udma_four))
hwif->udma_four = ata66_siimage(hwif);
@@ -827,7 +822,6 @@ static void __init init_hwif_siimage (ide_hwif_t *hwif)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
static void __init init_dma_siimage (ide_hwif_t *hwif, unsigned long dmabase)
diff --git a/drivers/ide/pci/siimage.h b/drivers/ide/pci/siimage.h
index 9ff6e6df969e..4cf10245c666 100644
--- a/drivers/ide/pci/siimage.h
+++ b/drivers/ide/pci/siimage.h
@@ -62,14 +62,14 @@ inline void sii_insl (u32 port, void *addr, u32 count)
// while (count--) { *(u32 *)addr = readl(port); addr += 4; }
}
-inline void sii_outb (u8 addr, u32 port)
+inline void sii_outb (u8 value, u32 port)
{
- writeb(addr, port);
+ writeb(value, port);
}
-inline void sii_outw (u16 addr, u32 port)
+inline void sii_outw (u16 value, u32 port)
{
- writew(addr, port);
+ writew(value, port);
}
inline void sii_outsw (u32 port, void *addr, u32 count)
@@ -77,9 +77,9 @@ inline void sii_outsw (u32 port, void *addr, u32 count)
while (count--) { writew(*(u16 *)addr, port); addr += 2; }
}
-inline void sii_outl (u32 addr, u32 port)
+inline void sii_outl (u32 value, u32 port)
{
- writel(addr, port);
+ writel(value, port);
}
inline void sii_outsl (u32 port, void *addr, u32 count)
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index fa6f13a8feec..c91a7f93c6d5 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -703,7 +703,6 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
/* Config chip for mode */
switch(speed) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_UDMA_6:
case XFER_UDMA_5:
case XFER_UDMA_4:
@@ -745,7 +744,6 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_SW_DMA_1:
case XFER_SW_DMA_0:
break;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4));
case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3));
case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2));
@@ -764,7 +762,6 @@ static void sis5513_tune_drive (ide_drive_t *drive, u8 pio)
(void) config_chipset_for_pio(drive, pio);
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
/*
* ((id->hw_config & 0x4000|0x2000) && (HWIF(drive)->udma_four))
*/
@@ -835,8 +832,6 @@ static int sis5513_config_xfer_rate (ide_drive_t *drive)
return sis5513_config_drive_xfer_rate(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-
/* Chip detection and general config */
static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char *name)
{
@@ -999,7 +994,6 @@ static void __init init_hwif_sis5513 (ide_hwif_t *hwif)
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (!host_dev)
return;
@@ -1013,7 +1007,6 @@ static void __init init_hwif_sis5513 (ide_hwif_t *hwif)
}
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif
return;
}
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
index 8c556300a354..de9faa971441 100644
--- a/drivers/ide/pci/trm290.c
+++ b/drivers/ide/pci/trm290.c
@@ -176,7 +176,6 @@ static void trm290_selectproc (ide_drive_t *drive)
trm290_prepare_drive(drive, drive->using_dma);
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
static int trm290_ide_dma_write (ide_drive_t *drive /*, struct request *rq */)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -297,7 +296,6 @@ static int trm290_ide_dma_test_irq (ide_drive_t *drive)
status = hwif->INW(hwif->dma_status);
return (status == 0x00ff);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
/*
* Invoked from ide-dma.c at boot time.
@@ -344,13 +342,11 @@ void __init init_hwif_trm290 (ide_hwif_t *hwif)
ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
-#ifdef CONFIG_BLK_DEV_IDEDMA
hwif->ide_dma_write = &trm290_ide_dma_write;
hwif->ide_dma_read = &trm290_ide_dma_read;
hwif->ide_dma_begin = &trm290_ide_dma_begin;
hwif->ide_dma_end = &trm290_ide_dma_end;
hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
hwif->selectproc = &trm290_selectproc;
hwif->autodma = 0; /* play it safe for now */
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 6e53179decdd..7cbe88bd047b 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -383,8 +383,6 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
via_set_drive(drive, XFER_PIO_0 + MIN(pio, 5));
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
-
/**
* via82cxxx_ide_dma_check - set up for DMA if possible
* @drive: IDE drive to set up
@@ -411,8 +409,6 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive)
return HWIF(drive)->ide_dma_off_quietly(drive);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-
/**
* init_chipset_via82cxxx - initialization handler
* @dev: PCI device
@@ -608,7 +604,6 @@ static void __init init_hwif_via82cxxx(ide_hwif_t *hwif)
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (!(hwif->udma_four))
hwif->udma_four = ((via_enabled & via_80w) >> hwif->channel) & 1;
hwif->ide_dma_check = &via82cxxx_ide_dma_check;
@@ -616,7 +611,6 @@ static void __init init_hwif_via82cxxx(ide_hwif_t *hwif)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
}
/**
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index fb93c85a0078..90a92dbe79d2 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -10,6 +10,7 @@
* Split the set up function into multiple functions
* Use pci_set_master
* Fix misreporting of I/O v MMIO problems
+ * Initial fixups for simplex devices
*/
/*
@@ -42,6 +43,8 @@
* based on io_base port if possible. Return the matching hwif,
* or a new hwif. If we find an error (clashing, out of devices, etc)
* return NULL
+ *
+ * FIXME: we need to handle mmio matches here too
*/
static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char *name)
@@ -144,34 +147,9 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name)
return -EOPNOTSUPP;
}
}
-
-#if 0
- /*
- * At this point we have enabled the device, but may previously
- * have done a BAR4 enable alone. We should be prepared to assign
- * resources here.
- */
-
- /*
- * Setup base registers for IDE command/control
- * spaces for each interface:
- */
- for (reg = 0; reg < 4; reg++) {
- struct resource *res = dev->resource + reg;
- if ((res->flags & IORESOURCE_IO) == 0)
- continue;
- if (!res->start) {
- if(pci_assign_resource(dev, reg)) {
- printk(KERN_ERR "%s: Missing I/O address #%d\n", name, reg);
- return -ENXIO;
- }
- }
- }
-#endif
return 0;
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
#ifdef CONFIG_BLK_DEV_IDEDMA_FORCED
/*
* Long lost data from 2.0.34 that is now in 2.0.39
@@ -192,9 +170,6 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name)
* Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space:
* If need be we set up the DMA base. Where a device has a partner that
* is already in DMA mode we check and enforce IDE simplex rules.
- *
- * FIXME: currently we are sometimes enforicng simplex when it is not
- * needed. We fail the safe way but why is it occurring ??
*/
static unsigned long __init ide_get_or_set_dma_base (ide_hwif_t *hwif)
@@ -274,7 +249,14 @@ second_chance_to_dma:
simplex_stat = hwif->INB(dma_base + 2);
if (simplex_stat & 0x80) {
/* simplex device? */
-
+#if 0
+/*
+ * At this point we haven't probed the drives so we can't make the
+ * appropriate decision. Really we should defer this problem
+ * until we tune the drive then try to grab DMA ownership if we want
+ * to be the DMA end. This has to be become dynamic to handle hot
+ * plug.
+ */
/* Don't enable DMA on a simplex channel with no drives */
if (!hwif->drives[0].present && !hwif->drives[1].present)
{
@@ -283,7 +265,9 @@ second_chance_to_dma:
dma_base = 0;
}
/* If our other channel has DMA then we cannot */
- else if(hwif->mate && hwif->mate->dma_base)
+ else
+#endif
+ if(hwif->mate && hwif->mate->dma_base)
{
printk(KERN_INFO "%s: simplex device: "
"DMA disabled\n",
@@ -295,9 +279,8 @@ second_chance_to_dma:
}
return dma_base;
}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-static void ide_setup_pci_noise (struct pci_dev *dev, ide_pci_device_t *d)
+void ide_setup_pci_noise (struct pci_dev *dev, ide_pci_device_t *d)
{
if ((d->vendor != dev->vendor) && (d->device != dev->device)) {
printk(KERN_INFO "%s: unknown IDE controller at PCI slot "
@@ -309,6 +292,9 @@ static void ide_setup_pci_noise (struct pci_dev *dev, ide_pci_device_t *d)
}
}
+EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
+
+
/**
* ide_pci_enable - do PCI enables
* @dev: PCI device
@@ -414,8 +400,7 @@ static int ide_pci_check_iomem(struct pci_dev *dev, ide_pci_device_t *d, int bar
"<andre@linux-ide.org>.\n", d->name);
return -EINVAL;
}
-
-
+
/**
* ide_hwif_configure - configure an IDE interface
* @dev: PCI device holding interface
@@ -434,16 +419,19 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d,
unsigned long ctl = 0, base = 0;
ide_hwif_t *hwif;
- /* Possibly we should fail if these checks report true */
- ide_pci_check_iomem(dev, d, 2*port);
- ide_pci_check_iomem(dev, d, 2*port+1);
+ if(!d->isa_ports)
+ {
+ /* Possibly we should fail if these checks report true */
+ ide_pci_check_iomem(dev, d, 2*port);
+ ide_pci_check_iomem(dev, d, 2*port+1);
- ctl = pci_resource_start(dev, 2*port+1);
- base = pci_resource_start(dev, 2*port);
- if ((ctl && !base) || (base && !ctl)) {
- printk(KERN_ERR "%s: inconsistent baseregs (BIOS) "
- "for port %d, skipping\n", d->name, port);
- return NULL;
+ ctl = pci_resource_start(dev, 2*port+1);
+ base = pci_resource_start(dev, 2*port);
+ if ((ctl && !base) || (base && !ctl)) {
+ printk(KERN_ERR "%s: inconsistent baseregs (BIOS) "
+ "for port %d, skipping\n", d->name, port);
+ return NULL;
+ }
}
if (!ctl)
{
@@ -500,8 +488,9 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi
* Set up BM-DMA capability
* (PnP BIOS should have done this)
*/
- if ((d->device != PCI_DEVICE_ID_CYRIX_5530_IDE)
- && (d->vendor != PCI_VENDOR_ID_CYRIX)) {
+ if (!((d->device == PCI_DEVICE_ID_CYRIX_5530_IDE && d->vendor == PCI_VENDOR_ID_CYRIX)
+ ||(d->device == PCI_DEVICE_ID_NS_SCx200_IDE && d->vendor == PCI_VENDOR_ID_NS)))
+ {
/*
* default DMA off if we had to
* configure it here
@@ -575,75 +564,33 @@ static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, in
return ret;
}
-/*
- * ide_setup_pci_device() looks at the primary/secondary interfaces
- * on a PCI IDE device and, if they are enabled, prepares the IDE driver
- * for use with them. This generic code works for most PCI chipsets.
+/**
+ * ide_pci_setup_ports - configure ports/devices on PCI IDE
+ * @dev: PCI device
+ * @d: IDE pci device info
+ * @autodma: Should we enable DMA
+ * @pciirq: IRQ line
+ * @index: ata index to update
*
- * One thing that is not standardized is the location of the
- * primary/secondary interface "enable/disable" bits. For chipsets that
- * we "know" about, this information is in the ide_pci_device_t struct;
- * for all other chipsets, we just assume both interfaces are enabled.
+ * Scan the interfaces attached to this device and do any
+ * neccessary per port setup. Attach the devices and ask the
+ * generic DMA layer to do its work for us.
+ *
+ * Normally called automaticall from do_ide_pci_setup_device,
+ * but is also used directly as a helper function by some controllers
+ * where the chipset setup is not the default PCI IDE one.
*/
-static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d, u8 noisy)
+
+void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int autodma, int pciirq, ata_index_t *index)
{
- u32 port, at_least_one_hwif_enabled = 0, autodma = 0;
- int pciirq = 0;
- int tried_config = 0;
- int drive0_tune, drive1_tune;
- ata_index_t index;
- u8 tmp = 0;
+ int port;
+ int at_least_one_hwif_enabled = 0;
ide_hwif_t *hwif, *mate = NULL;
static int secondpdc = 0;
+ int drive0_tune, drive1_tune;
+ u8 tmp;
- index.all = 0xf0f0;
-
- if((autodma = ide_setup_pci_controller(dev, d, noisy, &tried_config)) < 0)
- return index;
-
- /*
- * Can we trust the reported IRQ?
- */
- pciirq = dev->irq;
-
- if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) {
- if (noisy)
- printk(KERN_INFO "%s: not 100%% native mode: "
- "will probe irqs later\n", d->name);
- /*
- * This allows offboard ide-pci cards the enable a BIOS,
- * verify interrupt settings of split-mirror pci-config
- * space, place chipset into init-mode, and/or preserve
- * an interrupt if the card is not native ide support.
- */
- pciirq = (d->init_chipset) ? d->init_chipset(dev, d->name) : 0;
- } else if (tried_config) {
- if (noisy)
- printk(KERN_INFO "%s: will probe irqs later\n", d->name);
- pciirq = 0;
- } else if (!pciirq) {
- if (noisy)
- printk(KERN_WARNING "%s: bad irq (%d): will probe later\n",
- d->name, pciirq);
- pciirq = 0;
- } else {
- if (d->init_chipset)
- {
- if(d->init_chipset(dev, d->name) < 0)
- return index;
- }
- if (noisy)
-#ifdef __sparc__
- printk(KERN_INFO "%s: 100%% native mode on irq %s\n",
- d->name, __irq_itoa(pciirq));
-#else
- printk(KERN_INFO "%s: 100%% native mode on irq %d\n",
- d->name, pciirq);
-#endif
- }
-
- if(pciirq < 0) /* Error not an IRQ */
- return index;
+ index->all = 0xf0f0;
/*
* Set up the IDE ports
@@ -671,7 +618,7 @@ static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_
controller_ok:
if (d->channels <= port)
- return index;
+ break;
if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)
continue;
@@ -680,25 +627,27 @@ controller_ok:
hwif->gendev.parent = &dev->dev;
if (hwif->channel) {
- index.b.high = hwif->index;
+ index->b.high = hwif->index;
} else {
- index.b.low = hwif->index;
+ index->b.low = hwif->index;
}
if (d->init_iops)
d->init_iops(hwif);
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (d->autodma == NODMA)
goto bypass_legacy_dma;
if (d->autodma == NOAUTODMA)
autodma = 0;
if (autodma)
hwif->autodma = 1;
- ide_hwif_setup_dma(dev, d, hwif);
+
+ if(d->init_setup_dma)
+ d->init_setup_dma(dev, d, hwif);
+ else
+ ide_hwif_setup_dma(dev, d, hwif);
bypass_legacy_dma:
-#endif /* CONFIG_BLK_DEV_IDEDMA */
drive0_tune = hwif->drives[0].autotune;
drive1_tune = hwif->drives[1].autotune;
@@ -708,7 +657,13 @@ bypass_legacy_dma:
* for each enabled hwif
*/
d->init_hwif(hwif);
-
+
+ /*
+ * This is in the wrong place. The driver may
+ * do set up based on the autotune value and this
+ * will then trash it. Torben please move it and
+ * propogate the fixes into the drivers
+ */
if (drive0_tune == IDE_TUNE_BIOS) /* biostimings */
hwif->drives[0].autotune = IDE_TUNE_BIOS;
if (drive1_tune == IDE_TUNE_BIOS)
@@ -719,6 +674,76 @@ bypass_legacy_dma:
}
if (!at_least_one_hwif_enabled)
printk(KERN_INFO "%s: neither IDE port enabled (BIOS)\n", d->name);
+}
+
+EXPORT_SYMBOL_GPL(ide_pci_setup_ports);
+
+/*
+ * ide_setup_pci_device() looks at the primary/secondary interfaces
+ * on a PCI IDE device and, if they are enabled, prepares the IDE driver
+ * for use with them. This generic code works for most PCI chipsets.
+ *
+ * One thing that is not standardized is the location of the
+ * primary/secondary interface "enable/disable" bits. For chipsets that
+ * we "know" about, this information is in the ide_pci_device_t struct;
+ * for all other chipsets, we just assume both interfaces are enabled.
+ */
+static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d, u8 noisy)
+{
+ int autodma = 0;
+ int pciirq = 0;
+ int tried_config = 0;
+ ata_index_t index;
+
+ if((autodma = ide_setup_pci_controller(dev, d, noisy, &tried_config)) < 0)
+ return index;
+
+ /*
+ * Can we trust the reported IRQ?
+ */
+ pciirq = dev->irq;
+
+ if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) {
+ if (noisy)
+ printk(KERN_INFO "%s: not 100%% native mode: "
+ "will probe irqs later\n", d->name);
+ /*
+ * This allows offboard ide-pci cards the enable a BIOS,
+ * verify interrupt settings of split-mirror pci-config
+ * space, place chipset into init-mode, and/or preserve
+ * an interrupt if the card is not native ide support.
+ */
+ pciirq = (d->init_chipset) ? d->init_chipset(dev, d->name) : 0;
+ } else if (tried_config) {
+ if (noisy)
+ printk(KERN_INFO "%s: will probe irqs later\n", d->name);
+ pciirq = 0;
+ } else if (!pciirq) {
+ if (noisy)
+ printk(KERN_WARNING "%s: bad irq (%d): will probe later\n",
+ d->name, pciirq);
+ pciirq = 0;
+ } else {
+ if (d->init_chipset)
+ {
+ if(d->init_chipset(dev, d->name) < 0)
+ return index;
+ }
+ if (noisy)
+#ifdef __sparc__
+ printk(KERN_INFO "%s: 100%% native mode on irq %s\n",
+ d->name, __irq_itoa(pciirq));
+#else
+ printk(KERN_INFO "%s: 100%% native mode on irq %d\n",
+ d->name, pciirq);
+#endif
+ }
+
+ if(pciirq < 0) /* Error not an IRQ */
+ return index;
+
+ ide_pci_setup_ports(dev, d, autodma, pciirq, &index);
+
return index;
}
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c
index c61b602d1088..f335ee1610b6 100644
--- a/drivers/input/gameport/fm801-gp.c
+++ b/drivers/input/gameport/fm801-gp.c
@@ -116,7 +116,7 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
gameport_register_port(&gp->gameport);
printk(KERN_INFO "gameport: %s at pci%s speed %d kHz\n",
- pci->name, pci->slot_name, gp->gameport.speed);
+ pci->dev.name, pci->slot_name, gp->gameport.speed);
return 0;
}
diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c
index 795ae1e965c5..5fdf017d6e71 100644
--- a/drivers/input/gameport/ns558.c
+++ b/drivers/input/gameport/ns558.c
@@ -236,7 +236,7 @@ static void ns558_pnp_probe(struct pci_dev *dev)
port->gameport.id.version = 0x100;
sprintf(port->phys, "isapnp%d.%d/gameport0", PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
- sprintf(port->name, "%s", dev->name[0] ? dev->name : "NS558 PnP Gameport");
+ sprintf(port->name, "%s", dev->dev.name[0] ? dev->dev.name : "NS558 PnP Gameport");
gameport_register_port(&port->gameport);
diff --git a/drivers/input/gameport/vortex.c b/drivers/input/gameport/vortex.c
index 071c046722bc..d9d0101ea399 100644
--- a/drivers/input/gameport/vortex.c
+++ b/drivers/input/gameport/vortex.c
@@ -127,7 +127,7 @@ static int __devinit vortex_probe(struct pci_dev *dev, const struct pci_device_i
vortex->gameport.cooked_read = vortex_cooked_read;
vortex->gameport.open = vortex_open;
- vortex->gameport.name = dev->name;
+ vortex->gameport.name = dev->dev.name;
vortex->gameport.phys = vortex->phys;
vortex->gameport.id.bustype = BUS_PCI;
vortex->gameport.id.vendor = dev->vendor;
@@ -146,7 +146,7 @@ static int __devinit vortex_probe(struct pci_dev *dev, const struct pci_device_i
gameport_register_port(&vortex->gameport);
printk(KERN_INFO "gameport: %s at pci%s speed %d kHz\n",
- dev->name, dev->slot_name, vortex->gameport.speed);
+ dev->dev.name, dev->slot_name, vortex->gameport.speed);
return 0;
}
diff --git a/drivers/isdn/hardware/eicon/mi_pc.h b/drivers/isdn/hardware/eicon/mi_pc.h
index ed7eae679c8f..9f7b35443c27 100644
--- a/drivers/isdn/hardware/eicon/mi_pc.h
+++ b/drivers/isdn/hardware/eicon/mi_pc.h
@@ -65,7 +65,7 @@
#define _MP_LED1 0x04 /* 1 = on */
#define _MP_DSP_RESET 0x02 /* active lo */
#define _MP_RISC_RESET 0x81 /* active hi, bit 7 for compatibility with old boards */
-/* CPU exeption context structure in MP shared ram after trap */
+/* CPU exception context structure in MP shared ram after trap */
typedef struct mp_xcptcontext_s MP_XCPTC;
struct mp_xcptcontext_s {
dword sr;
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index a3bb66d0873f..65942c9c025e 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -8,7 +8,6 @@
#include <linux/module.h>
#include <linux/vmalloc.h>
-#include <linux/compatmac.h>
#include <linux/miscdevice.h>
#include <linux/dm-ioctl.h>
#include <linux/init.h>
@@ -16,6 +15,8 @@
#include <linux/blk.h>
#include <linux/slab.h>
+#include <asm/uaccess.h>
+
#define DM_DRIVER_EMAIL "dm@uk.sistina.com"
/*-----------------------------------------------------------------
@@ -177,6 +178,7 @@ static void free_cell(struct hash_cell *hc)
static int register_with_devfs(struct hash_cell *hc)
{
struct gendisk *disk = dm_disk(hc->md);
+
hc->devfs_entry =
devfs_register(_dev_dir, hc->name, DEVFS_FL_CURRENT_OWNER,
disk->major, disk->first_minor,
@@ -459,12 +461,12 @@ static int __info(struct mapped_device *md, struct dm_ioctl *param)
if (!bdev)
return -ENXIO;
- if (disk->policy)
- param->flags |= DM_READONLY_FLAG;
-
param->open_count = bdev->bd_openers;
bdput(bdev);
+ if (disk->policy)
+ param->flags |= DM_READONLY_FLAG;
+
table = dm_get_table(md);
param->target_count = dm_table_get_num_targets(table);
dm_table_put(table);
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 4178ac4ea1c3..2e6e77e8b759 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -146,6 +146,25 @@ static int setup_btree_index(int l, struct dm_table *t)
return 0;
}
+static void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size)
+{
+ unsigned long size;
+ void *addr;
+
+ /*
+ * Check that we're not going to overflow.
+ */
+ if (nmemb > (ULONG_MAX / elem_size))
+ return NULL;
+
+ size = nmemb * elem_size;
+ addr = vmalloc(size);
+ if (addr)
+ memset(addr, 0, size);
+
+ return addr;
+}
+
/*
* highs, and targets are managed as dynamic arrays during a
* table load.
@@ -159,9 +178,8 @@ static int alloc_targets(struct dm_table *t, int num)
/*
* Allocate both the target array and offset array at once.
*/
- n_highs = (sector_t *) vcalloc(sizeof(struct dm_target) +
- sizeof(sector_t),
- num);
+ n_highs = (sector_t *) dm_vcalloc(sizeof(struct dm_target) +
+ sizeof(sector_t), num);
if (!n_highs)
return -ENOMEM;
@@ -624,7 +642,7 @@ static int setup_indexes(struct dm_table *t)
total += t->counts[i];
}
- indexes = (sector_t *) vcalloc(total, (unsigned long) NODE_SIZE);
+ indexes = (sector_t *) dm_vcalloc(total, (unsigned long) NODE_SIZE);
if (!indexes)
return -ENOMEM;
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 60e457ff1987..00859b7abf6a 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -15,7 +15,7 @@
#include <linux/slab.h>
static const char *_name = DM_NAME;
-#define MAX_DEVICES 256
+#define MAX_DEVICES (1 << KDEV_MINOR_BITS)
#define SECTOR_SHIFT 9
static int major = 0;
@@ -41,8 +41,6 @@ struct deferred_io {
struct mapped_device {
struct rw_semaphore lock;
-
- kdev_t kdev;
atomic_t holders;
unsigned long flags;
@@ -485,13 +483,25 @@ static int dm_request(request_queue_t *q, struct bio *bio)
return 0;
}
+/*-----------------------------------------------------------------
+ * A bitset is used to keep track of allocated minor numbers.
+ *---------------------------------------------------------------*/
+static spinlock_t _minor_lock = SPIN_LOCK_UNLOCKED;
+static unsigned long _minor_bits[MAX_DEVICES / BITS_PER_LONG];
+
+static void free_minor(int minor)
+{
+ spin_lock(&_minor_lock);
+ clear_bit(minor, _minor_bits);
+ spin_unlock(&_minor_lock);
+}
+
/*
* See if the device with a specific minor # is free.
*/
-static int specific_dev(int minor, struct mapped_device *md)
+static int specific_minor(int minor)
{
- struct gendisk *disk;
- int part;
+ int r = -EBUSY;
if (minor >= MAX_DEVICES) {
DMWARN("request for a mapped_device beyond MAX_DEVICES (%d)",
@@ -499,26 +509,27 @@ static int specific_dev(int minor, struct mapped_device *md)
return -EINVAL;
}
- disk = get_gendisk(MKDEV(_major, minor), &part);
- if (disk) {
- put_disk(disk);
- return -EBUSY;
- }
+ spin_lock(&_minor_lock);
+ if (!test_and_set_bit(minor, _minor_bits))
+ r = minor;
+ spin_unlock(&_minor_lock);
- return minor;
+ return r;
}
-static int any_old_dev(struct mapped_device *md)
+static int next_free_minor(void)
{
- int i;
+ int minor, r = -EBUSY;
- for (i = 0; i < MAX_DEVICES; i++)
- if (specific_dev(i, md) >= 0) {
- DMWARN("allocating minor = %d", i);
- return i;
- }
+ spin_lock(&_minor_lock);
+ minor = find_first_zero_bit(_minor_bits, MAX_DEVICES);
+ if (minor != MAX_DEVICES) {
+ set_bit(minor, _minor_bits);
+ r = minor;
+ }
+ spin_unlock(&_minor_lock);
- return -EBUSY;
+ return r;
}
/*
@@ -534,15 +545,15 @@ static struct mapped_device *alloc_dev(int minor)
}
/* get a minor number for the dev */
- minor = (minor < 0) ? any_old_dev(md) : specific_dev(minor, md);
+ minor = (minor < 0) ? next_free_minor() : specific_minor(minor);
if (minor < 0) {
kfree(md);
return NULL;
}
+ DMWARN("allocating minor %d.", minor);
memset(md, 0, sizeof(*md));
init_rwsem(&md->lock);
- md->kdev = mk_kdev(_major, minor);
atomic_set(&md->holders, 1);
md->queue.queuedata = md;
@@ -550,6 +561,7 @@ static struct mapped_device *alloc_dev(int minor)
md->disk = alloc_disk(1);
if (!md->disk) {
+ free_minor(md->disk->first_minor);
kfree(md);
return NULL;
}
@@ -569,6 +581,7 @@ static struct mapped_device *alloc_dev(int minor)
static void free_dev(struct mapped_device *md)
{
+ free_minor(md->disk->first_minor);
del_gendisk(md->disk);
put_disk(md->disk);
kfree(md);
@@ -749,6 +762,10 @@ int dm_resume(struct mapped_device *md)
return 0;
}
+/*
+ * The gendisk is only valid as long as you have a reference
+ * count on 'md'.
+ */
struct gendisk *dm_disk(struct mapped_device *md)
{
return md->disk;
diff --git a/drivers/media/dvb/av7110/Makefile b/drivers/media/dvb/av7110/Makefile
index e5b0d694d6d9..301a732168f7 100644
--- a/drivers/media/dvb/av7110/Makefile
+++ b/drivers/media/dvb/av7110/Makefile
@@ -6,5 +6,7 @@ dvb-ttpci-objs := saa7146_core.o saa7146_v4l.o av7110.o av7110_ir.o
obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
+
include $(TOPDIR)/Rules.make
diff --git a/drivers/media/dvb/av7110/av7110.c b/drivers/media/dvb/av7110/av7110.c
index 32613db23ad2..0a8971b2f017 100644
--- a/drivers/media/dvb/av7110/av7110.c
+++ b/drivers/media/dvb/av7110/av7110.c
@@ -89,7 +89,7 @@ static int outcom(av7110_t *av7110, int type, int com, int num, ...);
static void SetMode(av7110_t *av7110, int mode);
void pes_to_ts(u8 const *buf, long int length, u16 pid, p2t_t *p);
-void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, dvb_demux_feed_t *feed);
+void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, struct dvb_demux_feed *feed);
static u32 vidmem = 0;
static u32 vidlow = 0;
@@ -392,9 +392,9 @@ static int arm_thread(void *data)
static int
-record_cb(pes2ts_t *p2t, u8 *buf, size_t len)
+record_cb(dvb_filter_pes2ts_t *p2t, u8 *buf, size_t len)
{
- dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) p2t->priv;
+ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) p2t->priv;
if (!(dvbdmxfeed->ts_type & TS_PACKET))
return 0;
@@ -404,13 +404,13 @@ record_cb(pes2ts_t *p2t, u8 *buf, size_t len)
return dvbdmxfeed->cb.ts(buf, len, 0, 0,
&dvbdmxfeed->feed.ts, DMX_OK);
else
- return pes2ts(p2t, buf, len);
+ return dvb_filter_pes2ts(p2t, buf, len);
}
static int
-pes2ts_cb(void *priv, unsigned char *data)
+dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
{
- dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) priv;
+ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) priv;
dvbdmxfeed->cb.ts(data, 188, 0, 0,
&dvbdmxfeed->feed.ts,
@@ -420,9 +420,9 @@ pes2ts_cb(void *priv, unsigned char *data)
static int
AV_StartRecord(av7110_t *av7110, int av,
- dvb_demux_feed_t *dvbdmxfeed)
+ struct dvb_demux_feed *dvbdmxfeed)
{
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
if (av7110->playing||(av7110->rec_mode&av))
return -EBUSY;
@@ -432,20 +432,30 @@ AV_StartRecord(av7110_t *av7110, int av,
switch (av7110->rec_mode) {
case RP_AUDIO:
- pes2ts_init(&av7110->p2t[0], dvbdmx->pesfilter[0]->pid,
- pes2ts_cb, (void *)dvbdmx->pesfilter[0]);
+ dvb_filter_pes2ts_init (&av7110->p2t[0],
+ dvbdmx->pesfilter[0]->pid,
+ dvb_filter_pes2ts_cb,
+ (void *)dvbdmx->pesfilter[0]);
outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
break;
+
case RP_VIDEO:
- pes2ts_init(&av7110->p2t[1], dvbdmx->pesfilter[1]->pid,
- pes2ts_cb, (void *)dvbdmx->pesfilter[1]);
+ dvb_filter_pes2ts_init (&av7110->p2t[1],
+ dvbdmx->pesfilter[1]->pid,
+ dvb_filter_pes2ts_cb,
+ (void *)dvbdmx->pesfilter[1]);
outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
break;
+
case RP_AV:
- pes2ts_init(&av7110->p2t[0], dvbdmx->pesfilter[0]->pid,
- pes2ts_cb, (void *)dvbdmx->pesfilter[0]);
- pes2ts_init(&av7110->p2t[1], dvbdmx->pesfilter[1]->pid,
- pes2ts_cb, (void *)dvbdmx->pesfilter[1]);
+ dvb_filter_pes2ts_init (&av7110->p2t[0],
+ dvbdmx->pesfilter[0]->pid,
+ dvb_filter_pes2ts_cb,
+ (void *)dvbdmx->pesfilter[0]);
+ dvb_filter_pes2ts_init (&av7110->p2t[1],
+ dvbdmx->pesfilter[1]->pid,
+ dvb_filter_pes2ts_cb,
+ (void *)dvbdmx->pesfilter[1]);
outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
break;
}
@@ -463,8 +473,8 @@ AV_StartPlay(av7110_t *av7110, int av)
outcom(av7110, COMTYPE_REC_PLAY, __Stop, 0);
if (av7110->playing == RP_NONE) {
- reset_ipack(&av7110->ipack[0]);
- reset_ipack(&av7110->ipack[1]);
+ dvb_filter_ipack_reset(&av7110->ipack[0]);
+ dvb_filter_ipack_reset(&av7110->ipack[1]);
}
av7110->playing|=av;
@@ -814,7 +824,7 @@ void CI_handle(av7110_t *av7110, u8 *data, u16 len)
static inline int
DvbDmxFilterCallback(u8 * buffer1, size_t buffer1_len,
u8 * buffer2, size_t buffer2_len,
- dvb_demux_filter_t *dvbdmxfilter,
+ struct dvb_demux_filter *dvbdmxfilter,
dmx_success_t success,
av7110_t *av7110)
{
@@ -896,7 +906,7 @@ static void fidbirq(struct saa7146* saa, void *data)
// FIXME: use bottom half or tasklet
if (av7110->feeding && mem[0]==0x47)
- DvbDmxSWFilterPackets(&av7110->demux, mem, 512);
+ dvb_dmx_swfilter_packets(&av7110->demux, mem, 512);
}
#else
static
@@ -922,7 +932,7 @@ void fidbirq (unsigned long data)
} else {
if (av7110->ttbp>1000*188 && av7110->ttbp<1024*188) {
if (av7110->feeding)
- DvbDmxSWFilterPackets(&av7110->demux,
+ dvb_dmx_swfilter_packets(&av7110->demux,
mem+av7110->ttbp,
1024- av7110->ttbp / 188);
}
@@ -937,7 +947,7 @@ void fidbirq (unsigned long data)
// FIXME: use bottom half or tasklet
if (av7110->feeding && mem[0]==0x47)
- DvbDmxSWFilterPackets(&av7110->demux, mem, num);
+ dvb_dmx_swfilter_packets(&av7110->demux, mem, num);
}
#endif
@@ -1001,7 +1011,7 @@ void debiirq (unsigned long data)
switch (type&0xff) {
case DATA_TS_RECORD:
- DvbDmxSWFilterPackets(&av7110->demux,
+ dvb_dmx_swfilter_packets(&av7110->demux,
(const u8 *)av7110->debi_virt,
av7110->debilen/188);
spin_lock(&av7110->debilock);
@@ -2008,8 +2018,8 @@ firmversion(av7110_t *av7110)
av7110->arm_app=(buf[6] << 16) + buf[7];
av7110->avtype=(buf[8] << 16) + buf[9];
- printk ("av7110 (%d): AV711%d - firm %08x, rtsl %08x, vid %08x, app %08x\n",
- av7110->saa->dvb_adapter->num, av7110->avtype, av7110->arm_fw,
+ printk ("DVB: AV711%d(%d) - firm %08x, rtsl %08x, vid %08x, app %08x\n",
+ av7110->avtype, av7110->saa->dvb_adapter->num, av7110->arm_fw,
av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app);
return;
@@ -2483,9 +2493,12 @@ dvb_play(av7110_t *av7110, const u8 *buf,
if (umem) {
if (copy_from_user(av7110->kbuf[type], buf, n))
return -EFAULT;
- instant_repack(av7110->kbuf[type], n, &av7110->ipack[type]);
- } else
- instant_repack((u8 *)buf, n, &av7110->ipack[type]);
+ dvb_filter_instant_repack(av7110->kbuf[type], n,
+ &av7110->ipack[type]);
+ } else {
+ dvb_filter_instant_repack((u8 *)buf, n,
+ &av7110->ipack[type]);
+ }
todo -= n;
buf += n;
}
@@ -2517,7 +2530,8 @@ dvb_aplay(av7110_t *av7110, const u8 *buf,
n=IPACKS*2;
if (copy_from_user(av7110->kbuf[type], buf, n))
return -EFAULT;
- instant_repack(av7110->kbuf[type], n, &av7110->ipack[type]);
+ dvb_filter_instant_repack(av7110->kbuf[type], n,
+ &av7110->ipack[type]);
// memcpy(dvb->kbuf[type], buf, n);
todo -= n;
buf += n;
@@ -2525,7 +2539,7 @@ dvb_aplay(av7110_t *av7110, const u8 *buf,
return count-todo;
}
-void init_p2t(p2t_t *p, dvb_demux_feed_t *feed)
+void init_p2t(p2t_t *p, struct dvb_demux_feed *feed)
{
memset(p->pes,0,TS_SIZE);
p->counter = 0;
@@ -2721,7 +2735,7 @@ int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length)
void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
- dvb_demux_feed_t *feed)
+ struct dvb_demux_feed *feed)
{
int l, pes_start;
@@ -3104,7 +3118,7 @@ static int dvb_mmap(struct file* file, struct vm_area_struct *vma)
static unsigned int dvb_audio_poll(struct file *file, poll_table *wait)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
unsigned int mask=0;
@@ -3124,24 +3138,24 @@ static unsigned int dvb_audio_poll(struct file *file, poll_table *wait)
static struct file_operations dvb_fops = {
- ioctl: dvb_ioctl,
- mmap: dvb_mmap,
- llseek: no_llseek
+ .ioctl = dvb_ioctl,
+ .mmap = dvb_mmap,
+ .llseek = no_llseek
};
/* template for video_device-structure */
static struct video_device dvb_template = {
- owner: THIS_MODULE,
- name: "DVB Board",
- type: VID_TYPE_TUNER |
+ .owner = THIS_MODULE,
+ .name = "DVB Board",
+ .type = VID_TYPE_TUNER |
VID_TYPE_CAPTURE |
VID_TYPE_OVERLAY |
VID_TYPE_CLIPPING |
VID_TYPE_FRAMERAM |
VID_TYPE_SCALES,
- hardware: VID_HARDWARE_SAA7146,
- fops: &dvb_fops
+ .hardware = VID_HARDWARE_SAA7146,
+ .fops = &dvb_fops
};
@@ -3182,9 +3196,9 @@ static inline int vid_unregister(av7110_t *av7110)
******************************************************************************/
static int
-StartHWFilter(dvb_demux_filter_t *dvbdmxfilter)
+StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
{
- dvb_demux_feed_t *dvbdmxfeed=dvbdmxfilter->feed;
+ struct dvb_demux_feed *dvbdmxfeed=dvbdmxfilter->feed;
av7110_t *av7110=(av7110_t *) dvbdmxfeed->demux->priv;
u16 buf[20];
int ret, i;
@@ -3220,7 +3234,7 @@ StartHWFilter(dvb_demux_filter_t *dvbdmxfilter)
}
static int
-StopHWFilter(dvb_demux_filter_t *dvbdmxfilter)
+StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
{
av7110_t *av7110=(av7110_t *) dvbdmxfilter->feed->demux->priv;
u16 buf[3];
@@ -3252,9 +3266,9 @@ StopHWFilter(dvb_demux_filter_t *dvbdmxfilter)
static int
-dvb_write_to_decoder(dvb_demux_feed_t *dvbdmxfeed, u8 *buf, size_t count)
+dvb_write_to_decoder(struct dvb_demux_feed *dvbdmxfeed, u8 *buf, size_t count)
{
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
av7110_t *av7110=(av7110_t *) dvbdmx->priv;
ipack *ipack=&av7110->ipack[dvbdmxfeed->pes_type];
@@ -3277,7 +3291,7 @@ dvb_write_to_decoder(dvb_demux_feed_t *dvbdmxfeed, u8 *buf, size_t count)
return -1;
}
if (buf[1]&0x40)
- send_ipack_rest(ipack);
+ dvb_filter_ipack_flush(ipack);
if (buf[3]&0x20) { // adaptation field?
count-=buf[4]+1;
@@ -3287,14 +3301,15 @@ dvb_write_to_decoder(dvb_demux_feed_t *dvbdmxfeed, u8 *buf, size_t count)
}
}
- instant_repack(buf+4, count-4, &av7110->ipack[dvbdmxfeed->pes_type]);
+ dvb_filter_instant_repack(buf+4, count-4,
+ &av7110->ipack[dvbdmxfeed->pes_type]);
return 0;
}
static void
-dvb_feed_start_pid(dvb_demux_feed_t *dvbdmxfeed)
+dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
{
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
av7110_t *av7110=(av7110_t *) dvbdmx->priv;
u16 *pid=dvbdmx->pids, npids[5];
int i;
@@ -3329,9 +3344,9 @@ dvb_feed_start_pid(dvb_demux_feed_t *dvbdmxfeed)
}
static void
-dvb_feed_stop_pid(dvb_demux_feed_t *dvbdmxfeed)
+dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
{
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
av7110_t *av7110=(av7110_t *) dvbdmx->priv;
u16 *pid=dvbdmx->pids, npids[5];
int i;
@@ -3365,9 +3380,9 @@ dvb_feed_stop_pid(dvb_demux_feed_t *dvbdmxfeed)
}
static int
-dvb_start_feed(dvb_demux_feed_t *dvbdmxfeed)
+dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
{
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
av7110_t *av7110=(av7110_t *) dvbdmx->priv;
if (!dvbdmx->dmx.frontend)
@@ -3425,9 +3440,9 @@ dvb_start_feed(dvb_demux_feed_t *dvbdmxfeed)
static int
-dvb_stop_feed(dvb_demux_feed_t *dvbdmxfeed)
+dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
{
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
av7110_t *av7110=(av7110_t *) dvbdmx->priv;
if (av7110->saa->card_type>=DVB_CARD_TT_BUDGET)
@@ -3468,8 +3483,8 @@ dvb_stop_feed(dvb_demux_feed_t *dvbdmxfeed)
static void
restart_feeds(av7110_t *av7110)
{
- dvb_demux_t *dvbdmx=&av7110->demux;
- dvb_demux_feed_t *feed;
+ struct dvb_demux *dvbdmx=&av7110->demux;
+ struct dvb_demux_feed *feed;
int mode;
int i;
@@ -3660,7 +3675,7 @@ ci_ll_read(ring_buffer_t *cibuf, struct file *file, char *buf, size_t count, lof
static int
dvb_ca_open(struct inode *inode, struct file *file)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
int err=dvb_generic_open(inode, file);
@@ -3673,7 +3688,7 @@ dvb_ca_open(struct inode *inode, struct file *file)
static unsigned
int dvb_ca_poll(struct file *file, poll_table *wait)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
unsigned int mask=0;
@@ -3702,7 +3717,7 @@ static int
dvb_ca_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
unsigned long arg=(unsigned long) parg;
@@ -3716,7 +3731,7 @@ dvb_ca_ioctl(struct inode *inode, struct file *file,
case CA_GET_CAP:
{
- ca_cap_t cap;
+ ca_caps_t cap;
cap.slot_num=2;
#ifdef NEW_CI
@@ -3788,7 +3803,7 @@ static ssize_t
dvb_ca_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos);
@@ -3797,7 +3812,7 @@ dvb_ca_write(struct file *file, const char *buf,
static ssize_t
dvb_ca_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
@@ -3812,7 +3827,7 @@ dvb_ca_read(struct file *file, char *buf, size_t count, loff_t *ppos)
static unsigned int dvb_video_poll(struct file *file, poll_table *wait)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
unsigned int mask=0;
@@ -3834,7 +3849,7 @@ static ssize_t
dvb_video_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
if (av7110->videostate.stream_source!=VIDEO_SOURCE_MEMORY)
@@ -3847,7 +3862,7 @@ static ssize_t
dvb_audio_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
if (av7110->audiostate.stream_source!=AUDIO_SOURCE_MEMORY) {
@@ -3876,7 +3891,7 @@ play_iframe(av7110_t *av7110, u8 *buf, unsigned int len, int nonblock)
for (i=0; i<n; i++)
dvb_play(av7110, buf, len, 0, 1, 1);
- send_ipack_rest(&av7110->ipack[1]);
+ dvb_filter_ipack_flush(&av7110->ipack[1]);
}
@@ -3884,7 +3899,7 @@ static int
dvb_video_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
unsigned long arg=(unsigned long) parg;
int ret=0;
@@ -4041,7 +4056,7 @@ dvb_video_ioctl(struct inode *inode, struct file *file,
case VIDEO_CLEAR_BUFFER:
ring_buffer_flush(&av7110->avout);
- reset_ipack(&av7110->ipack[1]);
+ dvb_filter_ipack_reset(&av7110->ipack[1]);
if (av7110->playing==RP_AV) {
outcom(av7110, COMTYPE_REC_PLAY,
@@ -4073,7 +4088,7 @@ static int
dvb_audio_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
unsigned long arg=(unsigned long) parg;
int ret=0;
@@ -4164,7 +4179,7 @@ dvb_audio_ioctl(struct inode *inode, struct file *file,
case AUDIO_CLEAR_BUFFER:
ring_buffer_flush(&av7110->aout);
- reset_ipack(&av7110->ipack[0]);
+ dvb_filter_ipack_reset(&av7110->ipack[0]);
if (av7110->playing==RP_AV)
outcom(av7110, COMTYPE_REC_PLAY,
__Play, 2, AV_PES, 0);
@@ -4192,7 +4207,7 @@ static int
dvb_osd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
#ifdef CONFIG_DVB_AV7110_OSD
@@ -4204,7 +4219,7 @@ dvb_osd_ioctl(struct inode *inode, struct file *file,
static int dvb_video_open(struct inode *inode, struct file *file)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
int err;
@@ -4220,7 +4235,7 @@ static int dvb_video_open(struct inode *inode, struct file *file)
static int dvb_video_release(struct inode *inode, struct file *file)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
AV_Stop(av7110, RP_VIDEO);
@@ -4229,7 +4244,7 @@ static int dvb_video_release(struct inode *inode, struct file *file)
static int dvb_audio_open(struct inode *inode, struct file *file)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
int err=dvb_generic_open(inode, file);
@@ -4242,7 +4257,7 @@ static int dvb_audio_open(struct inode *inode, struct file *file)
static int dvb_audio_release(struct inode *inode, struct file *file)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
av7110_t *av7110=(av7110_t *) dvbdev->priv;
AV_Stop(av7110, RP_AUDIO);
@@ -4256,75 +4271,70 @@ static int dvb_audio_release(struct inode *inode, struct file *file)
******************************************************************************/
static struct file_operations dvb_video_fops = {
- owner: THIS_MODULE,
- read: 0,
- write: dvb_video_write,
- ioctl: dvb_generic_ioctl,
- open: dvb_video_open,
- release: dvb_video_release,
- poll: dvb_video_poll,
+ .owner = THIS_MODULE,
+ .write = dvb_video_write,
+ .ioctl = dvb_generic_ioctl,
+ .open = dvb_video_open,
+ .release = dvb_video_release,
+ .poll = dvb_video_poll,
};
-static dvb_device_t dvbdev_video = {
- priv: 0,
- users: 1,
- writers: 1,
- fops: &dvb_video_fops,
- kernel_ioctl: dvb_video_ioctl,
+static struct dvb_device dvbdev_video = {
+ .priv = 0,
+ .users = 1,
+ .writers = 1,
+ .fops = &dvb_video_fops,
+ .kernel_ioctl = dvb_video_ioctl,
};
static struct file_operations dvb_audio_fops = {
- owner: THIS_MODULE,
- read: 0,
- write: dvb_audio_write,
- ioctl: dvb_generic_ioctl,
- open: dvb_audio_open,
- release: dvb_audio_release,
- poll: dvb_audio_poll,
+ .owner = THIS_MODULE,
+ .write = dvb_audio_write,
+ .ioctl = dvb_generic_ioctl,
+ .open = dvb_audio_open,
+ .release = dvb_audio_release,
+ .poll = dvb_audio_poll,
};
-static dvb_device_t dvbdev_audio = {
- priv: 0,
- users: 1,
- writers: 1,
- fops: &dvb_audio_fops,
- kernel_ioctl: dvb_audio_ioctl,
+static struct dvb_device dvbdev_audio = {
+ .priv = 0,
+ .users = 1,
+ .writers = 1,
+ .fops = &dvb_audio_fops,
+ .kernel_ioctl = dvb_audio_ioctl,
};
static struct file_operations dvb_ca_fops = {
- owner: THIS_MODULE,
- read: dvb_ca_read,
- write: dvb_ca_write,
- ioctl: dvb_generic_ioctl,
- open: dvb_ca_open,
- release: dvb_generic_release,
- poll: dvb_ca_poll,
+ .owner = THIS_MODULE,
+ .read = dvb_ca_read,
+ .write = dvb_ca_write,
+ .ioctl = dvb_generic_ioctl,
+ .open = dvb_ca_open,
+ .release = dvb_generic_release,
+ .poll = dvb_ca_poll,
};
-static dvb_device_t dvbdev_ca = {
- priv: 0,
- users: 1,
- writers: 1,
- fops: &dvb_ca_fops,
- kernel_ioctl: dvb_ca_ioctl,
+static struct dvb_device dvbdev_ca = {
+ .priv = 0,
+ .users = 1,
+ .writers = 1,
+ .fops = &dvb_ca_fops,
+ .kernel_ioctl = dvb_ca_ioctl,
};
static struct file_operations dvb_osd_fops = {
- owner: THIS_MODULE,
- read: 0,
- write: 0,
- ioctl: dvb_generic_ioctl,
- open: dvb_generic_open,
- release: dvb_generic_release,
- poll: 0,
+ .owner = THIS_MODULE,
+ .ioctl = dvb_generic_ioctl,
+ .open = dvb_generic_open,
+ .release = dvb_generic_release,
};
-static dvb_device_t dvbdev_osd = {
- priv: 0,
- users: 1,
- writers: 1,
- fops: &dvb_osd_fops,
- kernel_ioctl: dvb_osd_ioctl,
+static struct dvb_device dvbdev_osd = {
+ .priv = 0,
+ .users = 1,
+ .writers = 1,
+ .fops = &dvb_osd_fops,
+ .kernel_ioctl = dvb_osd_ioctl,
};
@@ -4359,7 +4369,7 @@ dvb_register(av7110_t *av7110)
{
int ret, i;
dmx_frontend_t *dvbfront=&av7110->hw_frontend;
- dvb_demux_t *dvbdemux=&av7110->demux;
+ struct dvb_demux *dvbdemux=&av7110->demux;
if (av7110->registered)
return -1;
@@ -4414,7 +4424,7 @@ dvb_register(av7110_t *av7110)
DMX_SECTION_FILTERING|
DMX_MEMORY_BASED_FILTERING);
- DvbDmxInit(&av7110->demux);
+ dvb_dmx_init(&av7110->demux);
dvbfront->id="hw_frontend";
@@ -4426,7 +4436,7 @@ dvb_register(av7110_t *av7110)
av7110->dmxdev.demux=&dvbdemux->dmx;
av7110->dmxdev.capabilities=0;
- DmxDevInit(&av7110->dmxdev, av7110->dvb_adapter);
+ dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter);
}
if (av7110->saa->card_type>=DVB_CARD_TT_BUDGET) {
@@ -4443,7 +4453,7 @@ dvb_register(av7110_t *av7110)
DMX_SECTION_FILTERING|
DMX_MEMORY_BASED_FILTERING);
- DvbDmxInit(&av7110->demux);
+ dvb_dmx_init(&av7110->demux);
dvbfront->id="hw_frontend";
dvbfront->vendor="VLSI";
@@ -4454,7 +4464,7 @@ dvb_register(av7110_t *av7110)
av7110->dmxdev.demux=&dvbdemux->dmx;
av7110->dmxdev.capabilities=0;
- DmxDevInit(&av7110->dmxdev, av7110->dvb_adapter);
+ dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter);
}
ret=dvbdemux->dmx.add_frontend(&dvbdemux->dmx,
@@ -4505,7 +4515,7 @@ dvb_register(av7110_t *av7110)
static void
dvb_unregister(av7110_t *av7110)
{
- dvb_demux_t *dvbdemux=&av7110->demux;
+ struct dvb_demux *dvbdemux=&av7110->demux;
if (!av7110->registered)
return;
@@ -4516,8 +4526,8 @@ dvb_unregister(av7110_t *av7110)
dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
- DmxDevRelease(&av7110->dmxdev);
- DvbDmxRelease(&av7110->demux);
+ dvb_dmxdev_release(&av7110->dmxdev);
+ dvb_dmx_release(&av7110->demux);
if (av7110->saa->card_type==DVB_CARD_TT_SIEMENS)
dvb_remove_frontend_notifier (av7110->dvb_adapter,
@@ -4584,9 +4594,9 @@ int av7110_attach (struct saa7146 *saa, void **av7110_ptr)
av7110->vidmode=VIDEO_MODE_PAL;
- init_ipack(&av7110->ipack[0], IPACKS, play_audio_cb);
+ dvb_filter_ipack_init(&av7110->ipack[0], IPACKS, play_audio_cb);
av7110->ipack[0].data=(void *) av7110;
- init_ipack(&av7110->ipack[1], IPACKS, play_video_cb);
+ dvb_filter_ipack_init(&av7110->ipack[1], IPACKS, play_video_cb);
av7110->ipack[1].data=(void *) av7110;
@@ -4705,8 +4715,8 @@ int av7110_detach (struct saa7146 *saa, void** av7110_ptr)
saa7146_write(av7110->saa_mem, ISR,(MASK_19 | MASK_03));
ci_ll_release(&av7110->ci_rbuffer, &av7110->ci_wbuffer);
- free_ipack(&av7110->ipack[0]);
- free_ipack(&av7110->ipack[1]);
+ dvb_filter_ipack_free(&av7110->ipack[0]);
+ dvb_filter_ipack_free(&av7110->ipack[1]);
vfree(av7110->iobuf);
pci_free_consistent(av7110->saa->device, 8192, av7110->debi_virt,
av7110->debi_bus);
diff --git a/drivers/media/dvb/av7110/av7110.h b/drivers/media/dvb/av7110/av7110.h
index 4ba483deaaa2..a4e8acaf7cd6 100644
--- a/drivers/media/dvb/av7110/av7110.h
+++ b/drivers/media/dvb/av7110/av7110.h
@@ -479,7 +479,7 @@ typedef struct p2t_s {
u8 counter;
long int pos;
int frags;
- dvb_demux_feed_t *feed;
+ struct dvb_demux_feed *feed;
} p2t_t;
@@ -561,7 +561,7 @@ typedef struct av7110_s {
int vidmode;
dmxdev_t dmxdev;
- dvb_demux_t demux;
+ struct dvb_demux demux;
char demux_id[16];
dmx_frontend_t hw_frontend;
@@ -580,9 +580,9 @@ typedef struct av7110_s {
#define TRICK_FREEZE 3
struct audio_status audiostate;
- dvb_demux_filter_t *handle2filter[32];
+ struct dvb_demux_filter *handle2filter[32];
p2t_t p2t_filter[MAXFILT];
- pes2ts_t p2t[2];
+ dvb_filter_pes2ts_t p2t[2];
struct ipack_s ipack[2];
u8 *kbuf[2];
@@ -621,11 +621,11 @@ typedef struct av7110_s {
ring_buffer_t ci_wbuffer;
- dvb_adapter_t *dvb_adapter;
- dvb_device_t *video_dev;
- dvb_device_t *audio_dev;
- dvb_device_t *ca_dev;
- dvb_device_t *osd_dev;
+ struct dvb_adapter *dvb_adapter;
+ struct dvb_device *video_dev;
+ struct dvb_device *audio_dev;
+ struct dvb_device *ca_dev;
+ struct dvb_device *osd_dev;
int dsp_dev;
} av7110_t;
diff --git a/drivers/media/dvb/av7110/saa7146.c b/drivers/media/dvb/av7110/saa7146.c
index d0ef805dda34..a636af50c31e 100644
--- a/drivers/media/dvb/av7110/saa7146.c
+++ b/drivers/media/dvb/av7110/saa7146.c
@@ -1399,7 +1399,7 @@ int i2c_reset(struct saa7146* saa)
/* if any error is still present, a fatal error has occured ... */
if ( SAA7146_I2C_BBR != (status = i2c_status_check(saa)) ) {
hprintk("saa7146: i2c_reset: fatal error, status:0x%08x\n",status);
- return -1;
+ return -EIO;
}
return 0;
diff --git a/drivers/media/dvb/av7110/saa7146_core.c b/drivers/media/dvb/av7110/saa7146_core.c
index 0ba82f9d18e8..e18cb6c6ab1b 100644
--- a/drivers/media/dvb/av7110/saa7146_core.c
+++ b/drivers/media/dvb/av7110/saa7146_core.c
@@ -33,8 +33,8 @@
#include "saa7146_core.h"
#include "saa7146_v4l.h"
#include "av7110.h"
-#include "../dvb-core/compat.h"
-#include "../dvb-core/dvb_i2c.h"
+#include "compat.h"
+#include "dvb_i2c.h"
/* insmod parameter: here you can specify the number of video-buffers
to be allocated. for simple capturing 2 buffers (double-buffering)
@@ -197,23 +197,23 @@ static
int do_master_xfer (struct dvb_i2c_bus *i2c, struct i2c_msg msgs[], int num)
{
struct saa7146 *a = i2c->data;
- int result, count;
+ int count;
int i = 0;
dprintk(KERN_ERR "saa7146_core.o: master_xfer called, num:%d\n",num);
/* prepare the message(s), get number of u32s to transfer */
count = prepare(msgs, num, a->i2c);
- if ( 0 > count ) {
- hprintk(KERN_ERR "saa7146_core.o: master_xfer: could not prepare i2c-message\n");
+
+ if (count < 0) {
+ hprintk(KERN_ERR "saa7146_core.o: could not prepare i2c-message\n");
return -EIO;
}
/* reset the i2c-device if necessary */
- result = i2c_reset( a );
- if ( 0 > result ) {
- hprintk(KERN_ERR "saa7146_core.o: master_xfer: could not reset i2c-bus\n");
- return result;
+ if (i2c_reset(a) < 0) {
+ hprintk(KERN_ERR "saa7146_core.o: could not reset i2c-bus\n");
+ return -EIO;
}
for(i = 0; i < count; i++) {
@@ -222,31 +222,17 @@ int do_master_xfer (struct dvb_i2c_bus *i2c, struct i2c_msg msgs[], int num)
* we do not start the whole rps1-engine...
*/
- result = i2c_write_out( a, &a->i2c[i],
- SAA7146_I2C_TIMEOUT );
-
- if ( 0 != result) {
/* if address-error occured, don't retry */
- if ( result == -EREMOTEIO )
- {
- hprintk(KERN_ERR "saa7146_core.o: master_xfer: error in address phase\n");
- return result;
- }
- hprintk(KERN_ERR "saa7146_core.o: master_xfer: error transferring, trying again\n");
- break;
- }
+ if (i2c_write_out(a, &a->i2c[i], SAA7146_I2C_TIMEOUT) < 0) {
+ hprintk (KERN_ERR "saa7146_core.o: "
+ "i2c error in address phase\n");
+ return -EREMOTEIO;
}
-
- /* see if an error occured & the last retry failed */
- if (0 != result) {
- hprintk(KERN_ERR "saa7146_core.o: master_xfer: could not transfer i2c-message\n");
- return -EIO;
}
/* if any things had to be read, get the results */
- result = clean_up(msgs, num, a->i2c);
- if ( 0 > result ) {
- hprintk(KERN_ERR "saa7146_core.o: master_xfer: could not cleanup\n");
+ if (clean_up(msgs, num, a->i2c) < 0) {
+ hprintk(KERN_ERR "saa7146_core.o: i2c cleanup failed!\n");
return -EIO;
}
@@ -259,13 +245,19 @@ int do_master_xfer (struct dvb_i2c_bus *i2c, struct i2c_msg msgs[], int num)
static
int master_xfer (struct dvb_i2c_bus *i2c, struct i2c_msg msgs[], int num)
{
+ struct saa7146 *saa = i2c->data;
int retries = SAA7146_I2C_RETRIES;
int ret;
+ if (down_interruptible (&saa->i2c_sem))
+ return -ERESTARTSYS;
+
do {
ret = do_master_xfer (i2c, msgs, num);
} while (ret != num && retries--);
+ up (&saa->i2c_sem);
+
return ret;
}
@@ -273,6 +265,8 @@ int master_xfer (struct dvb_i2c_bus *i2c, struct i2c_msg msgs[], int num)
/* registering functions to load algorithms at runtime */
int i2c_saa7146_add_bus (struct saa7146 *saa)
{
+ init_MUTEX(&saa->i2c_sem);
+
/* enable i2c-port pins */
saa7146_write (saa->mem, MC1, (MASK_08 | MASK_24));
@@ -389,9 +383,9 @@ static int saa7146_core_command (struct dvb_i2c_bus *i2c, unsigned int cmd, void
struct saa7146_debi_transfer *dt = arg;
- printk("saa7146_core.o: SAA7146_DEBI_TRANSFER\n");
- printk("saa7146_core.o: timeout:%d, swap:%d, slave16:%d, increment:%d, intel:%d, tien:%d\n", dt->timeout, dt->swap, dt->slave16, dt->increment, dt->intel, dt->tien);
- printk("saa7146_core.o: address:0x%04x, num_bytes:%d, direction:%d, mem:0x%08x\n",dt->address,dt->address,dt->direction,dt->mem);
+ dprintk("saa7146_core.o: SAA7146_DEBI_TRANSFER\n");
+ dprintk("saa7146_core.o: timeout:%d, swap:%d, slave16:%d, increment:%d, intel:%d, tien:%d\n", dt->timeout, dt->swap, dt->slave16, dt->increment, dt->intel, dt->tien);
+ dprintk("saa7146_core.o: address:0x%04x, num_bytes:%d, direction:%d, mem:0x%08x\n",dt->address,dt->address,dt->direction,dt->mem);
debi_transfer(saa, dt);
break;
@@ -622,7 +616,7 @@ int configure_saa7146 (struct saa7146 *saa)
}
/* print status message */
- printk(KERN_ERR "saa7146_core.o: %s: bus:%d, rev:%d, mem:0x%08x.\n", saa->name, saa->device->bus->number, saa->revision, (unsigned int) saa->mem);
+ dprintk("saa7146_core.o: %s: bus:%d, rev:%d, mem:0x%08x.\n", saa->name, saa->device->bus->number, saa->revision, (unsigned int) saa->mem);
/* enable bus-mastering */
pci_set_master( saa->device );
@@ -827,7 +821,7 @@ static
int __devinit saa7146_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- struct dvb_adapter_s *adap;
+ struct dvb_adapter *adap;
struct saa7146 *saa;
int card_type;
struct card_info *cinfo= (struct card_info *) ent->driver_data;
diff --git a/drivers/media/dvb/av7110/saa7146_core.h b/drivers/media/dvb/av7110/saa7146_core.h
index ec3bd7598a49..3ef91a883d3a 100644
--- a/drivers/media/dvb/av7110/saa7146_core.h
+++ b/drivers/media/dvb/av7110/saa7146_core.h
@@ -1,17 +1,11 @@
#ifndef __SAA7146_CORE__
#define __SAA7146_CORE__
-#include <asm/io.h> /* definitions of u32 etc. */
-#include "../dvb-core/dvbdev.h"
-
-#if LINUX_VERSION_CODE < 0x020300
-#define DECLARE_MUTEX(foo) struct semaphore foo = MUTEX
-#define DECLARE_MUTEX_LOCKED(foo) struct semaphore foo = MUTEX_LOCKED
-#define WAIT_QUEUE struct wait_queue*
-#define init_waitqueue_head(wq) *(wq) = NULL;
-#else
-#define WAIT_QUEUE wait_queue_head_t
-#endif
+#include <asm/io.h>
+#include <asm/semaphore.h>
+
+#include "dvbdev.h"
+
/* maximum number of capture frames we support */
#define SAA7146_MAX_BUF 5
@@ -37,12 +31,13 @@ struct saa7146 {
char name[32]; /* give it a nice name */
struct list_head list_head;
-
- dvb_adapter_t *dvb_adapter;
- struct dvb_i2c_bus *i2c_bus;
struct pci_dev *device;
int card_type;
+ struct dvb_adapter *dvb_adapter;
+ struct dvb_i2c_bus *i2c_bus;
+ struct semaphore i2c_sem;
+
void* data[SAA7146_MAX_EXTENSIONS]; /* data hooks for extensions */
int (*command) (struct dvb_i2c_bus *i, unsigned int cmd, void *arg);
@@ -70,8 +65,8 @@ struct saa7146 {
int grab_format[SAA7146_MAX_BUF]; /* video format of grabs */
int grab_port[SAA7146_MAX_BUF]; /* video port for grab */
- WAIT_QUEUE rps0_wq; /* rps0 interrupt queue (=> capture) */
- WAIT_QUEUE rps1_wq; /* rps1 interrupt queue (=> i2c, ...) */
+ wait_queue_head_t rps0_wq; /* rps0 interrupt queue (=> capture) */
+ wait_queue_head_t rps1_wq; /* rps1 interrupt queue (=> i2c, ...) */
};
#define SAA7146_IRQ_RPS0
diff --git a/drivers/media/dvb/av7110/saa7146_v4l.c b/drivers/media/dvb/av7110/saa7146_v4l.c
index 387d0fe4b267..9a159f83afda 100644
--- a/drivers/media/dvb/av7110/saa7146_v4l.c
+++ b/drivers/media/dvb/av7110/saa7146_v4l.c
@@ -320,7 +320,6 @@ static int saa7146_v4l_command(struct saa7146* saa, void *p, unsigned int cmd, v
/* set corresponding buffer to ´unused´ */
saa->frame_stat[i] = GBUFFER_UNUSED;
-printk ("saa7146_v4l.o: SAA7146_V4L_CSYNC, frame %i done.\n", i);
break;
}
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index d388a1b6254c..99cfcb2ab698 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -24,6 +24,7 @@
#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/poll.h>
+#include <linux/videodev.h>
#include <asm/uaccess.h>
#include "dmxdev.h"
@@ -40,19 +41,19 @@ static int debug = 0;
#define dprintk if (debug) printk
inline dmxdev_filter_t *
-DmxDevFile2Filter(struct file *file)
+dvb_dmxdev_file_to_filter(struct file *file)
{
return (dmxdev_filter_t *) file->private_data;
}
inline dmxdev_dvr_t *
-DmxDevFile2DVR(dmxdev_t *dmxdev, struct file *file)
+dvb_dmxdev_file_to_dvr(dmxdev_t *dmxdev, struct file *file)
{
return (dmxdev_dvr_t *) file->private_data;
}
static inline void
-DmxDevBufferInit(dmxdev_buffer_t *buffer)
+dvb_dmxdev_buffer_init(dmxdev_buffer_t *buffer)
{
buffer->data=0;
buffer->size=8192;
@@ -63,7 +64,7 @@ DmxDevBufferInit(dmxdev_buffer_t *buffer)
}
static inline int
-DmxDevBufferWrite(dmxdev_buffer_t *buf, uint8_t *src, int len)
+dvb_dmxdev_buffer_write(dmxdev_buffer_t *buf, uint8_t *src, int len)
{
int split;
int free;
@@ -98,7 +99,7 @@ DmxDevBufferWrite(dmxdev_buffer_t *buf, uint8_t *src, int len)
}
static ssize_t
-DmxDevBufferRead(dmxdev_buffer_t *src, int non_blocking,
+dvb_dmxdev_buffer_read(dmxdev_buffer_t *src, int non_blocking,
char *buf, size_t count, loff_t *ppos)
{
unsigned long todo=count;
@@ -108,6 +109,7 @@ DmxDevBufferRead(dmxdev_buffer_t *src, int non_blocking,
return 0;
if ((error=src->error)) {
+ src->pwrite=src->pread;
src->error=0;
return error;
}
@@ -125,6 +127,7 @@ DmxDevBufferRead(dmxdev_buffer_t *src, int non_blocking,
return count-todo;
if ((error=src->error)) {
+ src->pwrite=src->pread;
src->error=0;
return error;
}
@@ -172,7 +175,7 @@ get_fe(dmx_demux_t *demux, int type)
}
static inline void
-DmxDevDVRStateSet(dmxdev_dvr_t *dmxdevdvr, int state)
+dvb_dmxdev_dvr_state_set(dmxdev_dvr_t *dmxdevdvr, int state)
{
spin_lock_irq(&dmxdevdvr->dev->lock);
dmxdevdvr->state=state;
@@ -181,7 +184,7 @@ DmxDevDVRStateSet(dmxdev_dvr_t *dmxdevdvr, int state)
static int dvb_dvr_open(struct inode *inode, struct file *file)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
dmxdev_t *dmxdev=(dmxdev_t *) dvbdev->priv;
dmx_frontend_t *front;
@@ -198,7 +201,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
}
if ((file->f_flags&O_ACCMODE)==O_RDONLY) {
- DmxDevBufferInit(&dmxdev->dvr_buffer);
+ dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer);
dmxdev->dvr_buffer.size=DVR_BUFFER_SIZE;
dmxdev->dvr_buffer.data=vmalloc(DVR_BUFFER_SIZE);
if (!dmxdev->dvr_buffer.data) {
@@ -230,7 +233,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
static int dvb_dvr_release(struct inode *inode, struct file *file)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
dmxdev_t *dmxdev=(dmxdev_t *) dvbdev->priv;
if (down_interruptible (&dmxdev->mutex))
@@ -258,7 +261,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
static ssize_t
dvb_dvr_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
dmxdev_t *dmxdev=(dmxdev_t *) dvbdev->priv;
int ret;
@@ -276,12 +279,12 @@ dvb_dvr_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
static ssize_t
dvb_dvr_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
dmxdev_t *dmxdev=(dmxdev_t *) dvbdev->priv;
int ret;
//down(&dmxdev->mutex);
- ret= DmxDevBufferRead(&dmxdev->dvr_buffer,
+ ret= dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
file->f_flags&O_NONBLOCK,
buf, count, ppos);
//up(&dmxdev->mutex);
@@ -289,7 +292,7 @@ dvb_dvr_read(struct file *file, char *buf, size_t count, loff_t *ppos)
}
static inline void
-DmxDevFilterStateSet(dmxdev_filter_t *dmxdevfilter, int state)
+dvb_dmxdev_filter_state_set(dmxdev_filter_t *dmxdevfilter, int state)
{
spin_lock_irq(&dmxdevfilter->dev->lock);
dmxdevfilter->state=state;
@@ -297,7 +300,7 @@ DmxDevFilterStateSet(dmxdev_filter_t *dmxdevfilter, int state)
}
static int
-DmxDevSetBufferSize(dmxdev_filter_t *dmxdevfilter, unsigned long size)
+dvb_dmxdev_set_buffer_size(dmxdev_filter_t *dmxdevfilter, unsigned long size)
{
dmxdev_buffer_t *buf=&dmxdevfilter->buffer;
void *mem;
@@ -327,7 +330,7 @@ DmxDevSetBufferSize(dmxdev_filter_t *dmxdevfilter, unsigned long size)
}
static void
-DmxDevFilterTimeout(unsigned long data)
+dvb_dmxdev_filter_timeout(unsigned long data)
{
dmxdev_filter_t *dmxdevfilter=(dmxdev_filter_t *)data;
@@ -339,13 +342,13 @@ DmxDevFilterTimeout(unsigned long data)
}
static void
-DmxDevFilterTimer(dmxdev_filter_t *dmxdevfilter)
+dvb_dmxdev_filter_timer(dmxdev_filter_t *dmxdevfilter)
{
struct dmx_sct_filter_params *para=&dmxdevfilter->params.sec;
del_timer(&dmxdevfilter->timer);
if (para->timeout) {
- dmxdevfilter->timer.function=DmxDevFilterTimeout;
+ dmxdevfilter->timer.function=dvb_dmxdev_filter_timeout;
dmxdevfilter->timer.data=(unsigned long) dmxdevfilter;
dmxdevfilter->timer.expires=jiffies+1+(HZ/2+HZ*para->timeout)/1000;
add_timer(&dmxdevfilter->timer);
@@ -353,7 +356,7 @@ DmxDevFilterTimer(dmxdev_filter_t *dmxdevfilter)
}
static int
-DmxDevSectionCallback(u8 *buffer1, size_t buffer1_len,
+dvb_dmxdev_section_callback(u8 *buffer1, size_t buffer1_len,
u8 *buffer2, size_t buffer2_len,
dmx_section_filter_t *filter,
dmx_success_t success)
@@ -375,9 +378,9 @@ DmxDevSectionCallback(u8 *buffer1, size_t buffer1_len,
buffer1[0], buffer1[1],
buffer1[2], buffer1[3],
buffer1[4], buffer1[5]);
- ret=DmxDevBufferWrite(&dmxdevfilter->buffer, buffer1, buffer1_len);
+ ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, buffer1_len);
if (ret==buffer1_len) {
- ret=DmxDevBufferWrite(&dmxdevfilter->buffer, buffer2, buffer2_len);
+ ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2, buffer2_len);
}
if (ret<0) {
dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread;
@@ -391,7 +394,7 @@ DmxDevSectionCallback(u8 *buffer1, size_t buffer1_len,
}
static int
-DmxDevTSCallback(u8 *buffer1, size_t buffer1_len,
+dvb_dmxdev_ts_callback(u8 *buffer1, size_t buffer1_len,
u8 *buffer2, size_t buffer2_len,
dmx_ts_feed_t *feed,
dmx_success_t success)
@@ -415,9 +418,9 @@ DmxDevTSCallback(u8 *buffer1, size_t buffer1_len,
wake_up(&buffer->queue);
return 0;
}
- ret=DmxDevBufferWrite(buffer, buffer1, buffer1_len);
+ ret=dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
if (ret==buffer1_len)
- ret=DmxDevBufferWrite(buffer, buffer2, buffer2_len);
+ ret=dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
if (ret<0) {
buffer->pwrite=buffer->pread;
buffer->error=-EOVERFLOW;
@@ -431,9 +434,9 @@ DmxDevTSCallback(u8 *buffer1, size_t buffer1_len,
/* stop feed but only mark the specified filter as stopped (state set) */
static int
-DmxDevFeedStop(dmxdev_filter_t *dmxdevfilter)
+dvb_dmxdev_feed_stop(dmxdev_filter_t *dmxdevfilter)
{
- DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_SET);
+ dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
switch (dmxdevfilter->type) {
case DMXDEV_TYPE_SEC:
@@ -453,9 +456,9 @@ DmxDevFeedStop(dmxdev_filter_t *dmxdevfilter)
/* start feed associated with the specified filter */
static int
-DmxDevFeedStart(dmxdev_filter_t *dmxdevfilter)
+dvb_dmxdev_feed_start(dmxdev_filter_t *dmxdevfilter)
{
- DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_GO);
+ dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_GO);
switch (dmxdevfilter->type) {
case DMXDEV_TYPE_SEC:
@@ -475,7 +478,7 @@ DmxDevFeedStart(dmxdev_filter_t *dmxdevfilter)
otherwise release the feed */
static int
-DmxDevFeedRestart(dmxdev_filter_t *dmxdevfilter)
+dvb_dmxdev_feed_restart(dmxdev_filter_t *dmxdevfilter)
{
int i;
dmxdev_t *dmxdev=dmxdevfilter->dev;
@@ -485,7 +488,7 @@ DmxDevFeedRestart(dmxdev_filter_t *dmxdevfilter)
if (dmxdev->filter[i].state>=DMXDEV_STATE_GO &&
dmxdev->filter[i].type==DMXDEV_TYPE_SEC &&
dmxdev->filter[i].pid==pid) {
- DmxDevFeedStart(&dmxdev->filter[i]);
+ dvb_dmxdev_feed_start(&dmxdev->filter[i]);
return 0;
}
@@ -497,7 +500,7 @@ DmxDevFeedRestart(dmxdev_filter_t *dmxdevfilter)
}
static int
-DmxDevFilterStop(dmxdev_filter_t *dmxdevfilter)
+dvb_dmxdev_filter_stop(dmxdev_filter_t *dmxdevfilter)
{
if (dmxdevfilter->state<DMXDEV_STATE_GO)
return 0;
@@ -506,18 +509,18 @@ DmxDevFilterStop(dmxdev_filter_t *dmxdevfilter)
case DMXDEV_TYPE_SEC:
if (!dmxdevfilter->feed.sec)
break;
- DmxDevFeedStop(dmxdevfilter);
+ dvb_dmxdev_feed_stop(dmxdevfilter);
if (dmxdevfilter->filter.sec)
dmxdevfilter->feed.sec->
release_filter(dmxdevfilter->feed.sec,
dmxdevfilter->filter.sec);
- DmxDevFeedRestart(dmxdevfilter);
+ dvb_dmxdev_feed_restart(dmxdevfilter);
dmxdevfilter->feed.sec=0;
break;
case DMXDEV_TYPE_PES:
if (!dmxdevfilter->feed.ts)
break;
- DmxDevFeedStop(dmxdevfilter);
+ dvb_dmxdev_feed_stop(dmxdevfilter);
dmxdevfilter->dev->demux->
release_ts_feed(dmxdevfilter->dev->demux,
dmxdevfilter->feed.ts);
@@ -533,19 +536,19 @@ DmxDevFilterStop(dmxdev_filter_t *dmxdevfilter)
}
static inline int
-DmxDevFilterReset(dmxdev_filter_t *dmxdevfilter)
+dvb_dmxdev_filter_reset(dmxdev_filter_t *dmxdevfilter)
{
if (dmxdevfilter->state<DMXDEV_STATE_SET)
return 0;
dmxdevfilter->type=DMXDEV_TYPE_NONE;
dmxdevfilter->pid=0xffff;
- DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
+ dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
return 0;
}
static int
-DmxDevFilterStart(dmxdev_filter_t *dmxdevfilter)
+dvb_dmxdev_filter_start(dmxdev_filter_t *dmxdevfilter)
{
dmxdev_t *dmxdev=dmxdevfilter->dev;
void *mem;
@@ -554,7 +557,7 @@ DmxDevFilterStart(dmxdev_filter_t *dmxdevfilter)
if (dmxdevfilter->state<DMXDEV_STATE_SET)
return -EINVAL;
if (dmxdevfilter->state>=DMXDEV_STATE_GO)
- DmxDevFilterStop(dmxdevfilter);
+ dvb_dmxdev_filter_stop(dmxdevfilter);
mem=dmxdevfilter->buffer.data;
if (!mem) {
@@ -566,6 +569,8 @@ DmxDevFilterStart(dmxdev_filter_t *dmxdevfilter)
return -ENOMEM;
}
+ dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread=0;
+
switch (dmxdevfilter->type) {
case DMXDEV_TYPE_SEC:
{
@@ -588,10 +593,9 @@ DmxDevFilterStart(dmxdev_filter_t *dmxdevfilter)
/* if no feed found, try to allocate new one */
if (!*secfeed) {
- ret=dmxdev->demux->
- allocate_section_feed(dmxdev->demux,
+ ret=dmxdev->demux->allocate_section_feed(dmxdev->demux,
secfeed,
- DmxDevSectionCallback);
+ dvb_dmxdev_section_callback);
if (ret<0) {
printk ("DVB (%s): could not alloc feed\n",
__FUNCTION__);
@@ -604,18 +608,17 @@ DmxDevFilterStart(dmxdev_filter_t *dmxdevfilter)
if (ret<0) {
printk ("DVB (%s): could not set feed\n",
__FUNCTION__);
- DmxDevFeedRestart(dmxdevfilter);
+ dvb_dmxdev_feed_restart(dmxdevfilter);
return ret;
}
}
else
- DmxDevFeedStop(dmxdevfilter);
+ dvb_dmxdev_feed_stop(dmxdevfilter);
ret=(*secfeed)->allocate_filter(*secfeed, secfilter);
if (ret<0) {
- DmxDevFeedRestart(dmxdevfilter);
- dmxdevfilter->feed.sec->
- start_filtering(*secfeed);
+ dvb_dmxdev_feed_restart(dmxdevfilter);
+ dmxdevfilter->feed.sec->start_filtering(*secfeed);
dprintk ("could not get filter\n");
return ret;
}
@@ -636,15 +639,14 @@ DmxDevFilterStart(dmxdev_filter_t *dmxdevfilter)
(*secfilter)->filter_mask[2]=0;
dmxdevfilter->todo=0;
- dmxdevfilter->feed.sec->
- start_filtering(dmxdevfilter->feed.sec);
- DmxDevFilterTimer(dmxdevfilter);
+ dmxdevfilter->feed.sec->start_filtering(dmxdevfilter->feed.sec);
+ dvb_dmxdev_filter_timer(dmxdevfilter);
break;
}
case DMXDEV_TYPE_PES:
{
- struct timespec timeout = {0 };
+ struct timespec timeout = { 0 };
struct dmx_pes_filter_params *para=&dmxdevfilter->params.pes;
dmx_output_t otype;
int ret;
@@ -670,31 +672,29 @@ DmxDevFilterStart(dmxdev_filter_t *dmxdevfilter)
ret=dmxdev->demux->allocate_ts_feed(dmxdev->demux,
tsfeed,
- DmxDevTSCallback);
+ dvb_dmxdev_ts_callback);
if (ret<0)
return ret;
(*tsfeed)->priv=(void *) dmxdevfilter;
ret=(*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes, 188, 32768, 0, timeout);
if (ret<0) {
- dmxdev->demux->
- release_ts_feed(dmxdev->demux, *tsfeed);
+ dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed);
return ret;
}
- dmxdevfilter->feed.ts->
- start_filtering(dmxdevfilter->feed.ts);
+ dmxdevfilter->feed.ts->start_filtering(dmxdevfilter->feed.ts);
break;
}
default:
return -EINVAL;
}
- DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_GO);
+ dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_GO);
return 0;
}
static int dvb_demux_open(struct inode *inode, struct file *file)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
dmxdev_t *dmxdev=(dmxdev_t *) dvbdev->priv;
int i;
dmxdev_filter_t *dmxdevfilter;
@@ -714,9 +714,9 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
dmxdevfilter->dvbdev=dmxdev->dvbdev;
file->private_data=dmxdevfilter;
- DmxDevBufferInit(&dmxdevfilter->buffer);
+ dvb_dmxdev_buffer_init(&dmxdevfilter->buffer);
dmxdevfilter->type=DMXDEV_TYPE_NONE;
- DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
+ dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
dmxdevfilter->feed.ts=0;
init_timer(&dmxdevfilter->timer);
@@ -725,13 +725,13 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
}
int
-DmxDevFilterFree(dmxdev_t *dmxdev, dmxdev_filter_t *dmxdevfilter)
+dvb_dmxdev_filter_free(dmxdev_t *dmxdev, dmxdev_filter_t *dmxdevfilter)
{
if (down_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
- DmxDevFilterStop(dmxdevfilter);
- DmxDevFilterReset(dmxdevfilter);
+ dvb_dmxdev_filter_stop(dmxdevfilter);
+ dvb_dmxdev_filter_reset(dmxdevfilter);
if (dmxdevfilter->buffer.data) {
void *mem=dmxdevfilter->buffer.data;
@@ -741,7 +741,7 @@ DmxDevFilterFree(dmxdev_t *dmxdev, dmxdev_filter_t *dmxdevfilter)
spin_unlock_irq(&dmxdev->lock);
vfree(mem);
}
- DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_FREE);
+ dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE);
wake_up(&dmxdevfilter->buffer.queue);
up(&dmxdev->mutex);
return 0;
@@ -758,33 +758,33 @@ invert_mode(dmx_filter_t *filter)
static int
-DmxDevFilterSet(dmxdev_t *dmxdev,
+dvb_dmxdev_filter_set(dmxdev_t *dmxdev,
dmxdev_filter_t *dmxdevfilter,
struct dmx_sct_filter_params *params)
{
dprintk ("function : %s\n", __FUNCTION__);
- DmxDevFilterStop(dmxdevfilter);
+ dvb_dmxdev_filter_stop(dmxdevfilter);
dmxdevfilter->type=DMXDEV_TYPE_SEC;
dmxdevfilter->pid=params->pid;
memcpy(&dmxdevfilter->params.sec,
params, sizeof(struct dmx_sct_filter_params));
invert_mode(&dmxdevfilter->params.sec.filter);
- DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_SET);
+ dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
if (params->flags&DMX_IMMEDIATE_START)
- return DmxDevFilterStart(dmxdevfilter);
+ return dvb_dmxdev_filter_start(dmxdevfilter);
return 0;
}
static int
-DmxDevPesFilterSet(dmxdev_t *dmxdev,
+dvb_dmxdev_pes_filter_set(dmxdev_t *dmxdev,
dmxdev_filter_t *dmxdevfilter,
struct dmx_pes_filter_params *params)
{
- DmxDevFilterStop(dmxdevfilter);
+ dvb_dmxdev_filter_stop(dmxdevfilter);
if (params->pes_type>DMX_PES_OTHER || params->pes_type<0)
return -EINVAL;
@@ -793,16 +793,16 @@ DmxDevPesFilterSet(dmxdev_t *dmxdev,
dmxdevfilter->pid=params->pid;
memcpy(&dmxdevfilter->params, params, sizeof(struct dmx_pes_filter_params));
- DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_SET);
+ dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
if (params->flags&DMX_IMMEDIATE_START)
- return DmxDevFilterStart(dmxdevfilter);
+ return dvb_dmxdev_filter_start(dmxdevfilter);
return 0;
}
static ssize_t
-DmxDevReadSec(dmxdev_filter_t *dfil, struct file *file,
+dvb_dmxdev_read_sec(dmxdev_filter_t *dfil, struct file *file,
char *buf, size_t count, loff_t *ppos)
{
int result, hcount;
@@ -812,7 +812,7 @@ DmxDevReadSec(dmxdev_filter_t *dfil, struct file *file,
hcount=3+dfil->todo;
if (hcount>count)
hcount=count;
- result=DmxDevBufferRead(&dfil->buffer, file->f_flags&O_NONBLOCK,
+ result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK,
buf, hcount, ppos);
if (result<0) {
dfil->todo=0;
@@ -832,7 +832,7 @@ DmxDevReadSec(dmxdev_filter_t *dfil, struct file *file,
}
if (count>dfil->todo)
count=dfil->todo;
- result=DmxDevBufferRead(&dfil->buffer, file->f_flags&O_NONBLOCK,
+ result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK,
buf, count, ppos);
if (result<0)
return result;
@@ -844,16 +844,16 @@ DmxDevReadSec(dmxdev_filter_t *dfil, struct file *file,
ssize_t
dvb_demux_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
- dmxdev_filter_t *dmxdevfilter=DmxDevFile2Filter(file);
+ dmxdev_filter_t *dmxdevfilter=dvb_dmxdev_file_to_filter(file);
//dmxdev_t *dmxdev=dmxdevfilter->dev;
int ret=0;
// semaphore should not be necessary (I hope ...)
//down(&dmxdev->mutex);
if (dmxdevfilter->type==DMXDEV_TYPE_SEC)
- ret=DmxDevReadSec(dmxdevfilter, file, buf, count, ppos);
+ ret=dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos);
else
- ret=DmxDevBufferRead(&dmxdevfilter->buffer,
+ ret=dvb_dmxdev_buffer_read(&dmxdevfilter->buffer,
file->f_flags&O_NONBLOCK,
buf, count, ppos);
//up(&dmxdev->mutex);
@@ -864,7 +864,7 @@ dvb_demux_read(struct file *file, char *buf, size_t count, loff_t *ppos)
static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
- dmxdev_filter_t *dmxdevfilter=DmxDevFile2Filter(file);
+ dmxdev_filter_t *dmxdevfilter=dvb_dmxdev_file_to_filter(file);
dmxdev_t *dmxdev=dmxdevfilter->dev;
unsigned long arg=(unsigned long) parg;
int ret=0;
@@ -877,25 +877,25 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
if (dmxdevfilter->state<DMXDEV_STATE_SET)
ret=-EINVAL;
else
- ret=DmxDevFilterStart(dmxdevfilter);
+ ret=dvb_dmxdev_filter_start(dmxdevfilter);
break;
case DMX_STOP:
- ret=DmxDevFilterStop(dmxdevfilter);
+ ret=dvb_dmxdev_filter_stop(dmxdevfilter);
break;
case DMX_SET_FILTER:
- ret=DmxDevFilterSet(dmxdev, dmxdevfilter,
+ ret=dvb_dmxdev_filter_set(dmxdev, dmxdevfilter,
(struct dmx_sct_filter_params *)parg);
break;
case DMX_SET_PES_FILTER:
- ret=DmxDevPesFilterSet(dmxdev, dmxdevfilter,
+ ret=dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter,
(struct dmx_pes_filter_params *)parg);
break;
case DMX_SET_BUFFER_SIZE:
- ret=DmxDevSetBufferSize(dmxdevfilter, arg);
+ ret=dvb_dmxdev_set_buffer_size(dmxdevfilter, arg);
break;
case DMX_GET_EVENT:
@@ -919,13 +919,13 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
static int dvb_demux_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- return generic_usercopy(inode, file, cmd, arg, dvb_demux_do_ioctl);
+ return video_usercopy(inode, file, cmd, arg, dvb_demux_do_ioctl);
}
static unsigned int dvb_demux_poll(struct file *file, poll_table *wait)
{
- dmxdev_filter_t *dmxdevfilter=DmxDevFile2Filter(file);
+ dmxdev_filter_t *dmxdevfilter=dvb_dmxdev_file_to_filter(file);
if (!dmxdevfilter)
return -EINVAL;
@@ -958,33 +958,32 @@ static unsigned int dvb_demux_poll(struct file *file, poll_table *wait)
static int dvb_demux_release(struct inode *inode, struct file *file)
{
- dmxdev_filter_t *dmxdevfilter=DmxDevFile2Filter(file);
+ dmxdev_filter_t *dmxdevfilter=dvb_dmxdev_file_to_filter(file);
dmxdev_t *dmxdev=dmxdevfilter->dev;
- return DmxDevFilterFree(dmxdev, dmxdevfilter);
+ return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
}
static struct file_operations dvb_demux_fops = {
- owner: THIS_MODULE,
- read: dvb_demux_read,
- write: 0,
- ioctl: dvb_demux_ioctl,
- open: dvb_demux_open,
- release: dvb_demux_release,
- poll: dvb_demux_poll,
+ .owner = THIS_MODULE,
+ .read = dvb_demux_read,
+ .ioctl = dvb_demux_ioctl,
+ .open = dvb_demux_open,
+ .release = dvb_demux_release,
+ .poll = dvb_demux_poll,
};
-static dvb_device_t dvbdev_demux = {
- priv: 0,
- users: 1,
- writers: 1,
- fops: &dvb_demux_fops
+static struct dvb_device dvbdev_demux = {
+ .priv = 0,
+ .users = 1,
+ .writers = 1,
+ .fops = &dvb_demux_fops
};
static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
dmxdev_t *dmxdev=(dmxdev_t *) dvbdev->priv;
int ret=0;
@@ -1008,13 +1007,13 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
static int dvb_dvr_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- return generic_usercopy(inode, file, cmd, arg, dvb_dvr_do_ioctl);
+ return video_usercopy(inode, file, cmd, arg, dvb_dvr_do_ioctl);
}
static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
dmxdev_t *dmxdev=(dmxdev_t *) dvbdev->priv;
dprintk ("function : %s\n", __FUNCTION__);
@@ -1040,24 +1039,24 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
}
static struct file_operations dvb_dvr_fops = {
- owner: THIS_MODULE,
- read: dvb_dvr_read,
- write: dvb_dvr_write,
- ioctl: dvb_dvr_ioctl,
- open: dvb_dvr_open,
- release: dvb_dvr_release,
- poll: dvb_dvr_poll,
+ .owner = THIS_MODULE,
+ .read = dvb_dvr_read,
+ .write = dvb_dvr_write,
+ .ioctl = dvb_dvr_ioctl,
+ .open = dvb_dvr_open,
+ .release = dvb_dvr_release,
+ .poll =dvb_dvr_poll,
};
-static dvb_device_t dvbdev_dvr = {
- priv: 0,
- users: 1,
- writers: 1,
- fops: &dvb_dvr_fops
+static struct dvb_device dvbdev_dvr = {
+ .priv = 0,
+ .users = 1,
+ .writers = 1,
+ .fops = &dvb_dvr_fops
};
int
-DmxDevInit(dmxdev_t *dmxdev, dvb_adapter_t *dvb_adapter)
+dvb_dmxdev_init(dmxdev_t *dmxdev, struct dvb_adapter *dvb_adapter)
{
int i;
@@ -1079,22 +1078,22 @@ DmxDevInit(dmxdev_t *dmxdev, dvb_adapter_t *dvb_adapter)
for (i=0; i<dmxdev->filternum; i++) {
dmxdev->filter[i].dev=dmxdev;
dmxdev->filter[i].buffer.data=0;
- DmxDevFilterStateSet(&dmxdev->filter[i], DMXDEV_STATE_FREE);
+ dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
dmxdev->dvr[i].dev=dmxdev;
dmxdev->dvr[i].buffer.data=0;
- DmxDevFilterStateSet(&dmxdev->filter[i], DMXDEV_STATE_FREE);
- DmxDevDVRStateSet(&dmxdev->dvr[i], DMXDEV_STATE_FREE);
+ dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
+ dvb_dmxdev_dvr_state_set(&dmxdev->dvr[i], DMXDEV_STATE_FREE);
}
dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, DVB_DEVICE_DEMUX);
dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, dmxdev, DVB_DEVICE_DVR);
- DmxDevBufferInit(&dmxdev->dvr_buffer);
+ dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer);
MOD_INC_USE_COUNT;
return 0;
}
void
-DmxDevRelease(dmxdev_t *dmxdev)
+dvb_dmxdev_release(dmxdev_t *dmxdev)
{
dvb_unregister_device(dmxdev->dvbdev);
dvb_unregister_device(dmxdev->dvr_dvbdev);
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h
index c5fa89d51d86..d37a9f706304 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/drivers/media/dvb/dvb-core/dmxdev.h
@@ -64,7 +64,7 @@ typedef struct dmxdev_buffer_s {
typedef struct dmxdev_filter_s {
- dvb_device_t *dvbdev;
+ struct dvb_device *dvbdev;
union {
dmx_section_filter_t *sec;
@@ -102,8 +102,8 @@ typedef struct dmxdev_dvr_s {
typedef struct dmxdev_s {
- dvb_device_t *dvbdev;
- dvb_device_t *dvr_dvbdev;
+ struct dvb_device *dvbdev;
+ struct dvb_device *dvr_dvbdev;
dmxdev_filter_t *filter;
dmxdev_dvr_t *dvr;
@@ -122,7 +122,7 @@ typedef struct dmxdev_s {
} dmxdev_t;
-int DmxDevInit(dmxdev_t *dmxdev, dvb_adapter_t *);
-void DmxDevRelease(dmxdev_t *dmxdev);
+int dvb_dmxdev_init(dmxdev_t *dmxdev, struct dvb_adapter *);
+void dvb_dmxdev_release(dmxdev_t *dmxdev);
#endif /* _DMXDEV_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 3a3e3834afeb..29289ef75d1b 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -182,7 +182,7 @@ void dvb_set_crc32(u8 *data, int length)
******************************************************************************/
static inline int
-DvbDmxSWFilterPayload(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf)
+dvb_dmx_swfilter_payload(struct dvb_demux_feed *dvbdmxfeed, const u8 *buf)
{
int p, count;
//int ccok;
@@ -208,8 +208,8 @@ DvbDmxSWFilterPayload(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf)
static int
-DvbDmxSWFilterSectionFilter(dvb_demux_feed_t *dvbdmxfeed,
- dvb_demux_filter_t *f)
+dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *dvbdmxfeed,
+ struct dvb_demux_filter *f)
{
dmx_section_filter_t *filter=&f->filter;
int i;
@@ -229,10 +229,10 @@ DvbDmxSWFilterSectionFilter(dvb_demux_feed_t *dvbdmxfeed,
}
static inline int
-DvbDmxSWFilterSectionFeed(dvb_demux_feed_t *dvbdmxfeed)
+dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *dvbdmxfeed)
{
u8 *buf=dvbdmxfeed->secbuf;
- dvb_demux_filter_t *f;
+ struct dvb_demux_filter *f;
if (dvbdmxfeed->secbufp!=dvbdmxfeed->seclen)
return -1;
@@ -241,7 +241,7 @@ DvbDmxSWFilterSectionFeed(dvb_demux_feed_t *dvbdmxfeed)
if (!(f=dvbdmxfeed->filter))
return 0;
do
- if (DvbDmxSWFilterSectionFilter(dvbdmxfeed, f)<0)
+ if (dvb_dmx_swfilter_sectionfilter(dvbdmxfeed, f)<0)
return -1;
while ((f=f->next) && dvbdmxfeed->feed.sec.is_filtering);
@@ -251,7 +251,7 @@ DvbDmxSWFilterSectionFeed(dvb_demux_feed_t *dvbdmxfeed)
}
static inline int
-DvbDmxSWFilterSectionPacket(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf)
+dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *dvbdmxfeed, const u8 *buf)
{
int p, count;
int ccok, rest;
@@ -286,7 +286,7 @@ DvbDmxSWFilterSectionPacket(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf)
memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp,
buf+p+1, buf[p]);
dvbdmxfeed->secbufp+=buf[p];
- DvbDmxSWFilterSectionFeed(dvbdmxfeed);
+ dvb_dmx_swfilter_section_feed(dvbdmxfeed);
}
}
p+=buf[p]+1; // skip rest of last section
@@ -301,7 +301,7 @@ DvbDmxSWFilterSectionPacket(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf)
dvbdmxfeed->secbufp=dvbdmxfeed->seclen;
p+=dvbdmxfeed->seclen;
count=188-p;
- DvbDmxSWFilterSectionFeed(dvbdmxfeed);
+ dvb_dmx_swfilter_section_feed(dvbdmxfeed);
// filling bytes until packet end?
if (count && buf[p]==0xff)
@@ -337,7 +337,7 @@ DvbDmxSWFilterSectionPacket(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf)
if (rest<=count) { // section completed in this TS packet
memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, buf+p, rest);
dvbdmxfeed->secbufp+=rest;
- DvbDmxSWFilterSectionFeed(dvbdmxfeed);
+ dvb_dmx_swfilter_section_feed(dvbdmxfeed);
} else { // section continues in following ts packet
memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, buf+p, count);
dvbdmxfeed->secbufp+=count;
@@ -346,7 +346,7 @@ DvbDmxSWFilterSectionPacket(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf)
}
static inline void
-DvbDmxSWFilterPacketType(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf)
+dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *dvbdmxfeed, const u8 *buf)
{
switch(dvbdmxfeed->type) {
case DMX_TYPE_TS:
@@ -354,7 +354,7 @@ DvbDmxSWFilterPacketType(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf)
break;
if (dvbdmxfeed->ts_type & TS_PACKET) {
if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
- DvbDmxSWFilterPayload(dvbdmxfeed, buf);
+ dvb_dmx_swfilter_payload(dvbdmxfeed, buf);
else
dvbdmxfeed->cb.ts((u8 *)buf, 188, 0, 0,
&dvbdmxfeed->feed.ts, DMX_OK);
@@ -368,7 +368,7 @@ DvbDmxSWFilterPacketType(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf)
case DMX_TYPE_SEC:
if (!dvbdmxfeed->feed.sec.is_filtering)
break;
- if (DvbDmxSWFilterSectionPacket(dvbdmxfeed, buf)<0)
+ if (dvb_dmx_swfilter_section_packet(dvbdmxfeed, buf)<0)
dvbdmxfeed->seclen=dvbdmxfeed->secbufp=0;
break;
@@ -377,27 +377,27 @@ DvbDmxSWFilterPacketType(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf)
}
}
-void inline
-DvbDmxSWFilterPacket(dvb_demux_t *dvbdmx, const u8 *buf)
+void
+dvb_dmx_swfilter_packet(struct dvb_demux *dvbdmx, const u8 *buf)
{
- dvb_demux_feed_t *dvbdmxfeed;
+ struct dvb_demux_feed *dvbdmxfeed;
if (!(dvbdmxfeed=dvbdmx->pid2feed[ts_pid(buf)]))
return;
- DvbDmxSWFilterPacketType(dvbdmxfeed, buf);
+ dvb_dmx_swfilter_packet_type(dvbdmxfeed, buf);
}
void
-DvbDmxSWFilterPackets(dvb_demux_t *dvbdmx, const u8 *buf, int count)
+dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf, int count)
{
- dvb_demux_feed_t *dvbdmxfeed;
+ struct dvb_demux_feed *dvbdmxfeed;
spin_lock(&dvbdmx->lock);
if ((dvbdmxfeed=dvbdmx->pid2feed[0x2000]))
dvbdmxfeed->cb.ts((u8 *)buf, count*188, 0, 0,
&dvbdmxfeed->feed.ts, DMX_OK);
while (count) {
- DvbDmxSWFilterPacket(dvbdmx, buf);
+ dvb_dmx_swfilter_packet(dvbdmx, buf);
count--;
buf+=188;
}
@@ -405,7 +405,7 @@ DvbDmxSWFilterPackets(dvb_demux_t *dvbdmx, const u8 *buf, int count)
}
static inline void
-DvbDmxSWFilter(dvb_demux_t *dvbdmx, const u8 *buf, size_t count)
+dvb_dmx_swfilter(struct dvb_demux *dvbdmx, const u8 *buf, size_t count)
{
int p=0,i, j;
@@ -416,7 +416,7 @@ DvbDmxSWFilter(dvb_demux_t *dvbdmx, const u8 *buf, size_t count)
return;
}
memcpy(&dvbdmx->tsbuf[i], buf, j);
- DvbDmxSWFilterPacket(dvbdmx, dvbdmx->tsbuf);
+ dvb_dmx_swfilter_packet(dvbdmx, dvbdmx->tsbuf);
dvbdmx->tsbufp=0;
p+=j;
}
@@ -424,7 +424,7 @@ DvbDmxSWFilter(dvb_demux_t *dvbdmx, const u8 *buf, size_t count)
while (p<count) {
if (buf[p]==0x47) {
if (count-p>=188) {
- DvbDmxSWFilterPacket(dvbdmx, buf+p);
+ dvb_dmx_swfilter_packet(dvbdmx, buf+p);
p+=188;
} else {
i=count-p;
@@ -444,8 +444,8 @@ DvbDmxSWFilter(dvb_demux_t *dvbdmx, const u8 *buf, size_t count)
******************************************************************************
******************************************************************************/
-static dvb_demux_filter_t *
-DvbDmxFilterAlloc(dvb_demux_t *dvbdmx)
+static struct dvb_demux_filter *
+dvb_dmx_filter_alloc(struct dvb_demux *dvbdmx)
{
int i;
@@ -458,8 +458,8 @@ DvbDmxFilterAlloc(dvb_demux_t *dvbdmx)
return &dvbdmx->filter[i];
}
-static dvb_demux_feed_t *
-DvbDmxFeedAlloc(dvb_demux_t *dvbdmx)
+static struct dvb_demux_feed *
+dvb_dmx_feed_alloc(struct dvb_demux *dvbdmx)
{
int i;
@@ -478,10 +478,10 @@ DvbDmxFeedAlloc(dvb_demux_t *dvbdmx)
******************************************************************************/
static int
-dmx_pid_set(u16 pid, dvb_demux_feed_t *dvbdmxfeed)
+dmx_pid_set(u16 pid, struct dvb_demux_feed *dvbdmxfeed)
{
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
- dvb_demux_feed_t **pid2feed=dvbdmx->pid2feed;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux_feed **pid2feed=dvbdmx->pid2feed;
if (pid>DMX_MAX_PID)
return -EINVAL;
@@ -510,8 +510,8 @@ dmx_ts_feed_set(struct dmx_ts_feed_s* feed,
struct timespec timeout
)
{
- dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
int ret;
if (down_interruptible (&dvbdmx->mutex))
@@ -576,8 +576,8 @@ dmx_ts_feed_set(struct dmx_ts_feed_s* feed,
static int
dmx_ts_feed_start_filtering(struct dmx_ts_feed_s* feed)
{
- dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
int ret;
if (down_interruptible (&dvbdmx->mutex))
@@ -608,8 +608,8 @@ dmx_ts_feed_start_filtering(struct dmx_ts_feed_s* feed)
static int
dmx_ts_feed_stop_filtering(struct dmx_ts_feed_s* feed)
{
- dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
int ret;
if (down_interruptible (&dvbdmx->mutex))
@@ -637,13 +637,13 @@ static int dvbdmx_allocate_ts_feed(dmx_demux_t *demux,
dmx_ts_feed_t **feed,
dmx_ts_cb callback)
{
- dvb_demux_t *dvbdmx=(dvb_demux_t *) demux;
- dvb_demux_feed_t *dvbdmxfeed;
+ struct dvb_demux *dvbdmx=(struct dvb_demux *) demux;
+ struct dvb_demux_feed *dvbdmxfeed;
if (down_interruptible (&dvbdmx->mutex))
return -ERESTARTSYS;
- if (!(dvbdmxfeed=DvbDmxFeedAlloc(dvbdmx))) {
+ if (!(dvbdmxfeed=dvb_dmx_feed_alloc(dvbdmx))) {
up(&dvbdmx->mutex);
return -EBUSY;
}
@@ -663,7 +663,7 @@ static int dvbdmx_allocate_ts_feed(dmx_demux_t *demux,
(*feed)->stop_filtering=dmx_ts_feed_stop_filtering;
- if (!(dvbdmxfeed->filter=DvbDmxFilterAlloc(dvbdmx))) {
+ if (!(dvbdmxfeed->filter=dvb_dmx_filter_alloc(dvbdmx))) {
dvbdmxfeed->state=DMX_STATE_FREE;
up(&dvbdmx->mutex);
return -EBUSY;
@@ -679,8 +679,8 @@ static int dvbdmx_allocate_ts_feed(dmx_demux_t *demux,
static int dvbdmx_release_ts_feed(dmx_demux_t *demux, dmx_ts_feed_t *feed)
{
- dvb_demux_t *dvbdmx=(dvb_demux_t *) demux;
- dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
+ struct dvb_demux *dvbdmx=(struct dvb_demux *) demux;
+ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
if (down_interruptible (&dvbdmx->mutex))
return -ERESTARTSYS;
@@ -715,14 +715,14 @@ static int
dmx_section_feed_allocate_filter(struct dmx_section_feed_s* feed,
dmx_section_filter_t** filter)
{
- dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
- dvb_demux_t *dvbdemux=dvbdmxfeed->demux;
- dvb_demux_filter_t *dvbdmxfilter;
+ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
+ struct dvb_demux *dvbdemux=dvbdmxfeed->demux;
+ struct dvb_demux_filter *dvbdmxfilter;
if (down_interruptible (&dvbdemux->mutex))
return -ERESTARTSYS;
- dvbdmxfilter=DvbDmxFilterAlloc(dvbdemux);
+ dvbdmxfilter=dvb_dmx_filter_alloc(dvbdemux);
if (!dvbdmxfilter) {
up(&dvbdemux->mutex);
return -ENOSPC;
@@ -747,8 +747,8 @@ dmx_section_feed_set(struct dmx_section_feed_s* feed,
u16 pid, size_t circular_buffer_size,
int descramble, int check_crc)
{
- dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
if (pid>0x1fff)
return -EINVAL;
@@ -789,11 +789,11 @@ dmx_section_feed_set(struct dmx_section_feed_s* feed,
return 0;
}
-static void prepare_secfilters(dvb_demux_feed_t *dvbdmxfeed)
+static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
{
int i;
dmx_section_filter_t *sf;
- dvb_demux_filter_t *f;
+ struct dvb_demux_filter *f;
u8 mask, mode, doneq;
if (!(f=dvbdmxfeed->filter))
@@ -815,8 +815,8 @@ static void prepare_secfilters(dvb_demux_feed_t *dvbdmxfeed)
static int
dmx_section_feed_start_filtering(dmx_section_feed_t *feed)
{
- dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
int ret;
if (down_interruptible (&dvbdmx->mutex))
@@ -854,8 +854,8 @@ dmx_section_feed_start_filtering(dmx_section_feed_t *feed)
static int
dmx_section_feed_stop_filtering(struct dmx_section_feed_s* feed)
{
- dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
int ret;
if (down_interruptible (&dvbdmx->mutex))
@@ -878,9 +878,9 @@ static int
dmx_section_feed_release_filter(dmx_section_feed_t *feed,
dmx_section_filter_t* filter)
{
- dvb_demux_filter_t *dvbdmxfilter=(dvb_demux_filter_t *) filter, *f;
- dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
- dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+ struct dvb_demux_filter *dvbdmxfilter=(struct dvb_demux_filter *) filter, *f;
+ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
+ struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
if (down_interruptible (&dvbdmx->mutex))
return -ERESTARTSYS;
@@ -911,13 +911,13 @@ static int dvbdmx_allocate_section_feed(dmx_demux_t *demux,
dmx_section_feed_t **feed,
dmx_section_cb callback)
{
- dvb_demux_t *dvbdmx=(dvb_demux_t *) demux;
- dvb_demux_feed_t *dvbdmxfeed;
+ struct dvb_demux *dvbdmx=(struct dvb_demux *) demux;
+ struct dvb_demux_feed *dvbdmxfeed;
if (down_interruptible (&dvbdmx->mutex))
return -ERESTARTSYS;
- if (!(dvbdmxfeed=DvbDmxFeedAlloc(dvbdmx))) {
+ if (!(dvbdmxfeed=dvb_dmx_feed_alloc(dvbdmx))) {
up(&dvbdmx->mutex);
return -EBUSY;
}
@@ -946,8 +946,8 @@ static int dvbdmx_allocate_section_feed(dmx_demux_t *demux,
static int dvbdmx_release_section_feed(dmx_demux_t *demux,
dmx_section_feed_t *feed)
{
- dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
- dvb_demux_t *dvbdmx=(dvb_demux_t *) demux;
+ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
+ struct dvb_demux *dvbdmx=(struct dvb_demux *) demux;
if (down_interruptible (&dvbdmx->mutex))
return -ERESTARTSYS;
@@ -977,7 +977,7 @@ static int dvbdmx_release_section_feed(dmx_demux_t *demux,
static int dvbdmx_open(dmx_demux_t *demux)
{
- dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+ struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
if (dvbdemux->users>=MAX_DVB_DEMUX_USERS)
return -EUSERS;
@@ -987,7 +987,7 @@ static int dvbdmx_open(dmx_demux_t *demux)
static int dvbdmx_close(struct dmx_demux_s *demux)
{
- dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+ struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
if (dvbdemux->users==0)
return -ENODEV;
@@ -998,7 +998,7 @@ static int dvbdmx_close(struct dmx_demux_s *demux)
static int dvbdmx_write(dmx_demux_t *demux, const char *buf, size_t count)
{
- dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+ struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
if ((!demux->frontend) ||
(demux->frontend->source!=DMX_MEMORY_FE))
@@ -1007,7 +1007,7 @@ static int dvbdmx_write(dmx_demux_t *demux, const char *buf, size_t count)
if (down_interruptible (&dvbdemux->mutex))
return -ERESTARTSYS;
- DvbDmxSWFilter(dvbdemux, buf, count);
+ dvb_dmx_swfilter(dvbdemux, buf, count);
up(&dvbdemux->mutex);
return count;
}
@@ -1016,7 +1016,7 @@ static int dvbdmx_write(dmx_demux_t *demux, const char *buf, size_t count)
static int dvbdmx_add_frontend(dmx_demux_t *demux,
dmx_frontend_t *frontend)
{
- dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+ struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
struct list_head *pos, *head=&dvbdemux->frontend_list;
if (!(frontend->id && frontend->vendor && frontend->model))
@@ -1035,7 +1035,7 @@ static int
dvbdmx_remove_frontend(dmx_demux_t *demux,
dmx_frontend_t *frontend)
{
- dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+ struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
struct list_head *pos, *n, *head=&dvbdemux->frontend_list;
list_for_each_safe (pos, n, head)
@@ -1052,7 +1052,7 @@ dvbdmx_remove_frontend(dmx_demux_t *demux,
static struct list_head *
dvbdmx_get_frontends(dmx_demux_t *demux)
{
- dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+ struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
if (list_empty(&dvbdemux->frontend_list))
return NULL;
@@ -1062,7 +1062,7 @@ dvbdmx_get_frontends(dmx_demux_t *demux)
static int dvbdmx_connect_frontend(dmx_demux_t *demux,
dmx_frontend_t *frontend)
{
- dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+ struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
if (demux->frontend)
return -EINVAL;
@@ -1077,7 +1077,7 @@ static int dvbdmx_connect_frontend(dmx_demux_t *demux,
static int dvbdmx_disconnect_frontend(dmx_demux_t *demux)
{
- dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+ struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
if (down_interruptible (&dvbdemux->mutex))
return -ERESTARTSYS;
@@ -1089,24 +1089,24 @@ static int dvbdmx_disconnect_frontend(dmx_demux_t *demux)
static int dvbdmx_get_pes_pids(dmx_demux_t *demux, u16 *pids)
{
- dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+ struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
memcpy(pids, dvbdemux->pids, 5*sizeof(u16));
return 0;
}
int
-DvbDmxInit(dvb_demux_t *dvbdemux)
+dvb_dmx_init(struct dvb_demux *dvbdemux)
{
int i;
dmx_demux_t *dmx=&dvbdemux->dmx;
dvbdemux->users=0;
- dvbdemux->filter=vmalloc(dvbdemux->filternum*sizeof(dvb_demux_filter_t));
+ dvbdemux->filter=vmalloc(dvbdemux->filternum*sizeof(struct dvb_demux_filter));
if (!dvbdemux->filter)
return -ENOMEM;
- dvbdemux->feed=vmalloc(dvbdemux->feednum*sizeof(dvb_demux_feed_t));
+ dvbdemux->feed=vmalloc(dvbdemux->feednum*sizeof(struct dvb_demux_feed));
if (!dvbdemux->feed) {
vfree(dvbdemux->filter);
return -ENOMEM;
@@ -1125,7 +1125,7 @@ DvbDmxInit(dvb_demux_t *dvbdemux)
dvbdemux->pids[i]=0xffff;
}
dvbdemux->playing=dvbdemux->recording=0;
- memset(dvbdemux->pid2feed, 0, (DMX_MAX_PID+1)*sizeof(dvb_demux_feed_t *));
+ memset(dvbdemux->pid2feed, 0, (DMX_MAX_PID+1)*sizeof(struct dvb_demux_feed *));
dvbdemux->tsbufp=0;
dmx->frontend=0;
@@ -1159,7 +1159,7 @@ DvbDmxInit(dvb_demux_t *dvbdemux)
}
int
-DvbDmxRelease(dvb_demux_t *dvbdemux)
+dvb_dmx_release(struct dvb_demux *dvbdemux)
{
dmx_demux_t *dmx=&dvbdemux->dmx;
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index 7fb008c4b355..cb3aecae4639 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -39,14 +39,14 @@
#define DVB_DEMUX_MASK_MAX 18
-typedef struct dvb_demux_filter_s {
+struct dvb_demux_filter {
dmx_section_filter_t filter;
u8 maskandmode [DMX_MAX_FILTER_SIZE];
u8 maskandnotmode [DMX_MAX_FILTER_SIZE];
int doneq;
- struct dvb_demux_filter_s *next;
- struct dvb_demux_feed_s *feed;
+ struct dvb_demux_filter *next;
+ struct dvb_demux_feed *feed;
int index;
int state;
int type;
@@ -56,11 +56,10 @@ typedef struct dvb_demux_filter_s {
u16 hw_handle;
struct timer_list timer;
int ts_state;
+};
- //u16 pid; //to be removed
-} dvb_demux_filter_t;
-typedef struct dvb_demux_feed_s {
+struct dvb_demux_feed {
union {
dmx_ts_feed_t ts;
dmx_section_feed_t sec;
@@ -71,7 +70,7 @@ typedef struct dvb_demux_feed_s {
dmx_section_cb sec;
} cb;
- struct dvb_demux_s *demux;
+ struct dvb_demux *demux;
int type;
int state;
u16 pid;
@@ -81,7 +80,7 @@ typedef struct dvb_demux_feed_s {
int check_crc;
struct timespec timeout;
- dvb_demux_filter_t *filter;
+ struct dvb_demux_filter *filter;
int cb_length;
int ts_type;
@@ -93,42 +92,43 @@ typedef struct dvb_demux_feed_s {
int cc;
u16 peslen;
-} dvb_demux_feed_t;
+};
-typedef struct dvb_demux_s {
+struct dvb_demux {
dmx_demux_t dmx;
void *priv;
int filternum;
int feednum;
- int (*start_feed)(dvb_demux_feed_t *);
- int (*stop_feed)(dvb_demux_feed_t *);
- int (*write_to_decoder)(dvb_demux_feed_t *, u8 *, size_t);
+ int (*start_feed)(struct dvb_demux_feed *);
+ int (*stop_feed)(struct dvb_demux_feed *);
+ int (*write_to_decoder)(struct dvb_demux_feed *, u8 *, size_t);
int users;
#define MAX_DVB_DEMUX_USERS 10
- dvb_demux_filter_t *filter;
- dvb_demux_feed_t *feed;
+ struct dvb_demux_filter *filter;
+ struct dvb_demux_feed *feed;
struct list_head frontend_list;
- dvb_demux_feed_t *pesfilter[DMX_TS_PES_OTHER];
+ struct dvb_demux_feed *pesfilter[DMX_TS_PES_OTHER];
u16 pids[DMX_TS_PES_OTHER];
int playing;
int recording;
#define DMX_MAX_PID 0x2000
- dvb_demux_feed_t *pid2feed[DMX_MAX_PID+1];
+ struct dvb_demux_feed *pid2feed[DMX_MAX_PID+1];
u8 tsbuf[188];
int tsbufp;
struct semaphore mutex;
spinlock_t lock;
-} dvb_demux_t;
+};
-int DvbDmxInit(dvb_demux_t *dvbdemux);
-int DvbDmxRelease(dvb_demux_t *dvbdemux);
-void DvbDmxSWFilterPackets(dvb_demux_t *dvbdmx, const u8 *buf, int count);
+int dvb_dmx_init(struct dvb_demux *dvbdemux);
+int dvb_dmx_release(struct dvb_demux *dvbdemux);
+void dvb_dmx_swfilter_packet(struct dvb_demux *dvbdmx, const u8 *buf);
+void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf, int count);
#endif /* _DVB_DEMUX_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.c b/drivers/media/dvb/dvb-core/dvb_filter.c
index 4b6ef6d32caa..0df33c45e47e 100644
--- a/drivers/media/dvb/dvb-core/dvb_filter.c
+++ b/drivers/media/dvb/dvb-core/dvb_filter.c
@@ -24,454 +24,23 @@ uint32_t ac3_frames[3][32] =
-void pes2ts_init(pes2ts_t *p2ts, unsigned short pid,
- pes2ts_cb_t *cb, void *priv)
-{
- unsigned char *buf=p2ts->buf;
-
- buf[0]=0x47;
- buf[1]=(pid>>8);
- buf[2]=pid&0xff;
- p2ts->cc=0;
- p2ts->cb=cb;
- p2ts->priv=priv;
-}
-
-int pes2ts(pes2ts_t *p2ts, unsigned char *pes, int len)
-{
- unsigned char *buf=p2ts->buf;
- int ret=0, rest;
-
- //len=6+((pes[4]<<8)|pes[5]);
-
- buf[1]|=0x40;
- while (len>=184) {
- buf[3]=0x10|((p2ts->cc++)&0x0f);
- memcpy(buf+4, pes, 184);
- if ((ret=p2ts->cb(p2ts->priv, buf)))
- return ret;
- len-=184; pes+=184;
- buf[1]&=~0x40;
- }
- if (!len)
- return 0;
- buf[3]=0x30|((p2ts->cc++)&0x0f);
- rest=183-len;
- if (rest) {
- buf[5]=0x00;
- if (rest-1)
- memset(buf+6, 0xff, rest-1);
- }
- buf[4]=rest;
- memcpy(buf+5+rest, pes, len);
- return p2ts->cb(p2ts->priv, buf);
-}
-
-void reset_ipack(ipack *p)
-{
- p->found = 0;
- p->cid = 0;
- p->plength = 0;
- p->flag1 = 0;
- p->flag2 = 0;
- p->hlength = 0;
- p->mpeg = 0;
- p->check = 0;
- p->which = 0;
- p->done = 0;
- p->count = 0;
-}
-
-void init_ipack(ipack *p, int size,
- void (*func)(u8 *buf, int size, void *priv))
-{
- if ( !(p->buf = vmalloc(size*sizeof(u8))) ){
- printk ("Couldn't allocate memory for ipack\n");
- }
- p->size = size;
- p->func = func;
- p->repack_subids = 0;
- reset_ipack(p);
-}
-
-void free_ipack(ipack * p)
-{
- if (p->buf) vfree(p->buf);
-}
-
-void send_ipack(ipack *p)
-{
- int off;
- AudioInfo ai;
- int ac3_off = 0;
- int streamid=0;
- int nframes= 0;
- int f=0;
-
- switch ( p->mpeg ){
- case 2:
- if (p->count < 10) return;
- p->buf[3] = p->cid;
-
- p->buf[4] = (u8)(((p->count-6) & 0xFF00) >> 8);
- p->buf[5] = (u8)((p->count-6) & 0x00FF);
- if (p->repack_subids && p->cid == PRIVATE_STREAM1){
-
- off = 9+p->buf[8];
- streamid = p->buf[off];
- if ((streamid & 0xF8) == 0x80){
- ai.off = 0;
- ac3_off = ((p->buf[off+2] << 8)|
- p->buf[off+3]);
- if (ac3_off < p->count)
- f=get_ac3info(p->buf+off+3+ac3_off,
- p->count-ac3_off, &ai,0);
- if ( !f ){
- nframes = (p->count-off-3-ac3_off)/
- ai.framesize + 1;
- p->buf[off+2] = (ac3_off >> 8)& 0xFF;
- p->buf[off+3] = (ac3_off)& 0xFF;
- p->buf[off+1] = nframes;
-
- ac3_off += nframes * ai.framesize -
- p->count;
- }
- }
- }
- p->func(p->buf, p->count, p->data);
-
- p->buf[6] = 0x80;
- p->buf[7] = 0x00;
- p->buf[8] = 0x00;
- p->count = 9;
- if (p->repack_subids && p->cid == PRIVATE_STREAM1
- && (streamid & 0xF8)==0x80 ){
- p->count += 4;
- p->buf[9] = streamid;
- p->buf[10] = (ac3_off >> 8)& 0xFF;
- p->buf[11] = (ac3_off)& 0xFF;
- p->buf[12] = 0;
- }
-
- break;
- case 1:
- if (p->count < 8) return;
- p->buf[3] = p->cid;
-
- p->buf[4] = (u8)(((p->count-6) & 0xFF00) >> 8);
- p->buf[5] = (u8)((p->count-6) & 0x00FF);
- p->func(p->buf, p->count, p->data);
-
- p->buf[6] = 0x0F;
- p->count = 7;
- break;
- }
-}
-
-void send_ipack_rest(ipack *p)
-{
- if (p->plength != MMAX_PLENGTH-6 || p->found<=6)
- return;
- p->plength = p->found-6;
- p->found = 0;
- send_ipack(p);
- reset_ipack(p);
-}
-
-static void write_ipack(ipack *p, u8 *data, int count)
-{
- u8 headr[3] = { 0x00, 0x00, 0x01} ;
-
- if (p->count < 6){
- memcpy(p->buf, headr, 3);
- p->count = 6;
- }
-
- if (p->count + count < p->size){
- memcpy(p->buf+p->count, data, count);
- p->count += count;
- } else {
- int rest = p->size - p->count;
- memcpy(p->buf+p->count, data, rest);
- p->count += rest;
- send_ipack(p);
- if (count - rest > 0)
- write_ipack(p, data+rest, count-rest);
- }
-}
-
-int instant_repack(u8 *buf, int count, ipack *p)
-{
- int l;
- int c=0;
-
- while (c < count && (p->mpeg == 0 ||
- (p->mpeg == 1 && p->found < 7) ||
- (p->mpeg == 2 && p->found < 9))
- && (p->found < 5 || !p->done)){
- switch ( p->found ){
- case 0:
- case 1:
- if (buf[c] == 0x00) p->found++;
- else p->found = 0;
- c++;
- break;
- case 2:
- if (buf[c] == 0x01) p->found++;
- else if (buf[c] == 0) {
- p->found = 2;
- } else p->found = 0;
- c++;
- break;
- case 3:
- p->cid = 0;
- switch (buf[c]){
- case PROG_STREAM_MAP:
- case PRIVATE_STREAM2:
- case PROG_STREAM_DIR:
- case ECM_STREAM :
- case EMM_STREAM :
- case PADDING_STREAM :
- case DSM_CC_STREAM :
- case ISO13522_STREAM:
- p->done = 1;
- case PRIVATE_STREAM1:
- case VIDEO_STREAM_S ... VIDEO_STREAM_E:
- case AUDIO_STREAM_S ... AUDIO_STREAM_E:
- p->found++;
- p->cid = buf[c];
- c++;
- break;
- default:
- p->found = 0;
- break;
- }
- break;
-
- case 4:
- if (count-c > 1){
- p->plen[0] = buf[c];
- c++;
- p->plen[1] = buf[c];
- c++;
- p->found+=2;
- p->plength=(p->plen[0]<<8)|p->plen[1];
- } else {
- p->plen[0] = buf[c];
- p->found++;
- return count;
- }
- break;
- case 5:
- p->plen[1] = buf[c];
- c++;
- p->found++;
- p->plength=(p->plen[0]<<8)|p->plen[1];
- break;
- case 6:
- if (!p->done){
- p->flag1 = buf[c];
- c++;
- p->found++;
- if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
- else {
- p->hlength = 0;
- p->which = 0;
- p->mpeg = 1;
- p->flag2 = 0;
- }
- }
- break;
-
- case 7:
- if ( !p->done && p->mpeg == 2) {
- p->flag2 = buf[c];
- c++;
- p->found++;
- }
- break;
-
- case 8:
- if ( !p->done && p->mpeg == 2) {
- p->hlength = buf[c];
- c++;
- p->found++;
- }
- break;
-
- default:
-
- break;
- }
- }
-
- if (c == count) return count;
-
- if (!p->plength) p->plength = MMAX_PLENGTH-6;
-
- if ( p->done || ((p->mpeg == 2 && p->found >= 9) ||
- (p->mpeg == 1 && p->found >= 7)) ){
- switch (p->cid){
-
- case AUDIO_STREAM_S ... AUDIO_STREAM_E:
- case VIDEO_STREAM_S ... VIDEO_STREAM_E:
- case PRIVATE_STREAM1:
-
- if (p->mpeg == 2 && p->found == 9) {
- write_ipack(p, &p->flag1, 1);
- write_ipack(p, &p->flag2, 1);
- write_ipack(p, &p->hlength, 1);
- }
-
- if (p->mpeg == 1 && p->found == 7)
- write_ipack(p, &p->flag1, 1);
-
- if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
- p->found < 14) {
- while (c < count && p->found < 14) {
- p->pts[p->found-9] = buf[c];
- write_ipack(p, buf+c, 1);
- c++;
- p->found++;
- }
- if (c == count) return count;
- }
-
- if (p->mpeg == 1 && p->which < 2000) {
-
- if (p->found == 7) {
- p->check = p->flag1;
- p->hlength = 1;
- }
-
- while (!p->which && c < count &&
- p->check == 0xFF){
- p->check = buf[c];
- write_ipack(p, buf+c, 1);
- c++;
- p->found++;
- p->hlength++;
- }
-
- if ( c == count) return count;
-
- if ( (p->check & 0xC0) == 0x40 && !p->which){
- p->check = buf[c];
- write_ipack(p, buf+c, 1);
- c++;
- p->found++;
- p->hlength++;
-
- p->which = 1;
- if ( c == count) return count;
- p->check = buf[c];
- write_ipack(p, buf+c, 1);
- c++;
- p->found++;
- p->hlength++;
- p->which = 2;
- if ( c == count) return count;
- }
-
- if (p->which == 1){
- p->check = buf[c];
- write_ipack(p, buf+c, 1);
- c++;
- p->found++;
- p->hlength++;
- p->which = 2;
- if ( c == count) return count;
- }
-
- if ( (p->check & 0x30) && p->check != 0xFF){
- p->flag2 = (p->check & 0xF0) << 2;
- p->pts[0] = p->check;
- p->which = 3;
- }
-
- if ( c == count) return count;
- if (p->which > 2){
- if ((p->flag2 & PTS_DTS_FLAGS)
- == PTS_ONLY){
- while (c < count &&
- p->which < 7){
- p->pts[p->which-2] =
- buf[c];
- write_ipack(p,buf+c,1);
- c++;
- p->found++;
- p->which++;
- p->hlength++;
- }
- if ( c == count) return count;
- } else if ((p->flag2 & PTS_DTS_FLAGS)
- == PTS_DTS){
- while (c < count &&
- p->which< 12){
- if (p->which< 7)
- p->pts[p->which
- -2] =
- buf[c];
- write_ipack(p,buf+c,1);
- c++;
- p->found++;
- p->which++;
- p->hlength++;
- }
- if ( c == count) return count;
- }
- p->which = 2000;
- }
-
- }
-
- while (c < count && p->found < p->plength+6){
- l = count -c;
- if (l+p->found > p->plength+6)
- l = p->plength+6-p->found;
- write_ipack(p, buf+c, l);
- p->found += l;
- c += l;
- }
-
- break;
- }
-
-
- if ( p->done ){
- if( p->found + count - c < p->plength+6){
- p->found += count-c;
- c = count;
- } else {
- c += p->plength+6 - p->found;
- p->found = p->plength+6;
- }
- }
-
- if (p->plength && p->found == p->plength+6) {
- send_ipack(p);
- reset_ipack(p);
- if (c < count)
- instant_repack(buf+c, count-c, p);
- }
- }
- return count;
-}
-
-
-
+#if 0
+static
void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv,
void (*pes_write)(u8 *buf, int count, void *data),
void *priv)
{
- init_ipack(pa, IPACKS, pes_write);
- init_ipack(pv, IPACKS, pes_write);
+ dvb_filter_ipack_init(pa, IPACKS, pes_write);
+ dvb_filter_ipack_init(pv, IPACKS, pes_write);
pa->pid = pida;
pv->pid = pidv;
pa->data = priv;
pv->data = priv;
}
+#endif
+#if 0
+static
void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188)
{
u8 off = 0;
@@ -483,28 +52,31 @@ void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188)
if (buf[1]&PAY_START) {
if (p->plength == MMAX_PLENGTH-6 && p->found>6){
p->plength = p->found-6;
- p->found = 0;
+ p->found = 0;
send_ipack(p);
- reset_ipack(p);
- }
+ dvb_filter_ipack_reset(p);
+ }
}
if (buf[3] & ADAPT_FIELD) { // adaptation field?
off = buf[4] + 1;
if (off+4 > 187) return;
}
- instant_repack(buf+4+off, TS_SIZE-4-off, p);
+ dvb_filter_instant_repack(buf+4+off, TS_SIZE-4-off, p);
}
+#endif
+#if 0
/* needs 5 byte input, returns picture coding type*/
+static
int read_picture_header(uint8_t *headr, mpg_picture *pic, int field, int pr)
{
uint8_t pct;
-
+
if (pr) printk( "Pic header: ");
pic->temporal_reference[field] = (( headr[0] << 2 ) |
(headr[1] & 0x03) )& 0x03ff;
if (pr) printk( " temp ref: 0x%04x", pic->temporal_reference[field]);
-
+
pct = ( headr[1] >> 2 ) & 0x07;
pic->picture_coding_type[field] = pct;
if (pr) {
@@ -518,29 +90,31 @@ int read_picture_header(uint8_t *headr, mpg_picture *pic, int field, int pr)
case P_FRAME:
printk( " P-FRAME");
break;
- }
- }
-
+ }
+ }
+
pic->vinfo.vbv_delay = (( headr[1] >> 5 ) | ( headr[2] << 3) |
( (headr[3] & 0x1F) << 11) ) & 0xffff;
-
+
if (pr) printk( " vbv delay: 0x%04x", pic->vinfo.vbv_delay);
-
+
pic->picture_header_parameter = ( headr[3] & 0xe0 ) |
((headr[4] & 0x80) >> 3);
if ( pct == B_FRAME ){
pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f;
- }
+ }
if (pr) printk( " pic head param: 0x%x",
pic->picture_header_parameter);
return pct;
-}
-
+}
+#endif
+#if 0
/* needs 4 byte input */
+static
int read_gop_header(uint8_t *headr, mpg_picture *pic, int pr)
{
if (pr) printk("GOP header: ");
@@ -556,20 +130,23 @@ int read_gop_header(uint8_t *headr, mpg_picture *pic, int pr)
pic->closed_gop = 1;
} else {
pic->closed_gop = 0;
- }
+ }
if (pr) printk("closed: %d", pic->closed_gop);
if ( ( headr[3] & 0x20 ) != 0 ){
pic->broken_link = 1;
- } else {
+ } else {
pic->broken_link = 0;
- }
+ }
if (pr) printk(" broken: %d\n", pic->broken_link);
return 0;
}
+#endif
+#if 0
/* needs 8 byte input */
+static
int read_sequence_header(uint8_t *headr, VideoInfo *vi, int pr)
{
int sw;
@@ -583,37 +160,37 @@ int read_sequence_header(uint8_t *headr, VideoInfo *vi, int pr)
sw = (int)((headr[3]&0xF0) >> 4) ;
switch( sw ){
- case 1:
+ case 1:
if (pr)
printk("Videostream: ASPECT: 1:1");
vi->aspect_ratio = 100;
- break;
- case 2:
+ break;
+ case 2:
if (pr)
printk("Videostream: ASPECT: 4:3");
vi->aspect_ratio = 133;
- break;
- case 3:
+ break;
+ case 3:
if (pr)
printk("Videostream: ASPECT: 16:9");
vi->aspect_ratio = 177;
- break;
+ break;
case 4:
if (pr)
printk("Videostream: ASPECT: 2.21:1");
vi->aspect_ratio = 221;
- break;
+ break;
case 5 ... 15:
if (pr)
printk("Videostream: ASPECT: reserved");
vi->aspect_ratio = 0;
- break;
-
+ break;
+
default:
vi->aspect_ratio = 0;
return -1;
- }
+ }
if (pr)
printk(" Size = %dx%d",vi->horizontal_size,vi->vertical_size);
@@ -644,29 +221,29 @@ int read_sequence_header(uint8_t *headr, VideoInfo *vi, int pr)
printk(" FRate: 29.97 fps");
vi->framerate = 29970;
form = VIDEO_MODE_NTSC;
- break;
- case 5:
+ break;
+ case 5:
if (pr)
printk(" FRate: 30 fps");
vi->framerate = 30000;
form = VIDEO_MODE_NTSC;
- break;
- case 6:
+ break;
+ case 6:
if (pr)
printk(" FRate: 50 fps");
vi->framerate = 50000;
form = VIDEO_MODE_PAL;
- break;
- case 7:
+ break;
+ case 7:
if (pr)
printk(" FRate: 60 fps");
vi->framerate = 60000;
form = VIDEO_MODE_NTSC;
- break;
- }
-
+ break;
+ }
+
vi->bit_rate = (headr[4] << 10) | (headr[5] << 2) | (headr[6] & 0x03);
-
+
vi->vbv_buffer_size
= (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5);
@@ -680,13 +257,17 @@ int read_sequence_header(uint8_t *headr, VideoInfo *vi, int pr)
return 0;
}
+#endif
+
+#if 0
+static
int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr)
{
uint8_t *headr;
int found = 0;
int c = 0;
-
+
while (found < 4 && c+4 < count){
uint8_t *b;
@@ -696,7 +277,7 @@ int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr)
else {
c++;
}
- }
+ }
if (! found) return -1;
c += 4;
@@ -706,7 +287,11 @@ int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr)
vi->off = c-4;
return 0;
}
+#endif
+
+#if 0
+static
int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
{
uint8_t *headr;
@@ -721,9 +306,9 @@ int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
found = 2;
else {
- c++;
- }
- }
+ c++;
+ }
+ }
if (!found) return -1;
@@ -745,7 +330,7 @@ int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
printk(" BRate: reserved");
else
printk(" BRate: %d kb/s", ai->bit_rate/1000);
- }
+ }
fr = (headr[2] & 0x0c ) >> 2;
ai->frequency = freq[fr]*100;
@@ -755,11 +340,13 @@ int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
else
printk(" Freq: %d kHz\n",ai->frequency);
- }
+ }
ai->off = c;
return 0;
}
-
+#endif
+
+static
int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
{
uint8_t *headr;
@@ -767,27 +354,27 @@ int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
int c = 0;
uint8_t frame = 0;
int fr = 0;
-
+
while ( !found && c < count){
uint8_t *b = mbuf+c;
-
+
if ( b[0] == 0x0b && b[1] == 0x77 )
found = 1;
else {
- c++;
- }
- }
-
+ c++;
+ }
+ }
+
if (!found) return -1;
if (pr)
printk("Audiostream: AC3");
-
+
ai->off = c;
if (c+5 >= count) return -1;
-
+
ai->layer = 0; // 0 for AC3
headr = mbuf+c+2;
-
+
frame = (headr[2]&0x3f);
ai->bit_rate = ac3_bitrates[frame >> 1]*1000;
@@ -809,6 +396,9 @@ int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
return 0;
}
+
+#if 0
+static
uint8_t *skip_pes_header(uint8_t **bufp)
{
uint8_t *inbuf = *bufp;
@@ -816,10 +406,10 @@ uint8_t *skip_pes_header(uint8_t **bufp)
uint8_t *pts = NULL;
int skip = 0;
-int mpeg1_skip_table[16] = {
- 1, 0xffff, 5, 10, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
-};
+ static const int mpeg1_skip_table[16] = {
+ 1, 0xffff, 5, 10, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
+ };
if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */
@@ -830,8 +420,8 @@ int mpeg1_skip_table[16] = {
} else { /* mpeg1 */
for (buf = inbuf + 6; *buf == 0xff; buf++)
if (buf == inbuf + 6 + 16) {
- break;
- }
+ break;
+ }
if ((*buf & 0xc0) == 0x40)
buf += 2;
skip = mpeg1_skip_table [*buf >> 4];
@@ -843,9 +433,11 @@ int mpeg1_skip_table[16] = {
*bufp = buf;
return pts;
-}
-
+}
+#endif
+#if 0
+static
void initialize_quant_matrix( uint32_t *matrix )
{
int i;
@@ -870,7 +462,10 @@ void initialize_quant_matrix( uint32_t *matrix )
for ( i = 16 ; i < 32 ; i++ )
matrix[i] = 0x10101010;
}
+#endif
+#if 0
+static
void initialize_mpg_picture(mpg_picture *pic)
{
int i;
@@ -895,8 +490,10 @@ void initialize_mpg_picture(mpg_picture *pic)
pic->gop_flag = 0;
pic->sequence_end_flag = 0;
}
+#endif
-
+#if 0
+static
void mpg_set_picture_parameter( int32_t field_type, mpg_picture *pic )
{
int16_t last_h_offset;
@@ -912,7 +509,7 @@ void mpg_set_picture_parameter( int32_t field_type, mpg_picture *pic )
pic->progressive_frame = 1;
pic->picture_coding_parameter = 0x000010;
}
-
+
/* Reset flag */
pic->picture_display_extension_flag[field_type] = 0;
@@ -930,9 +527,12 @@ void mpg_set_picture_parameter( int32_t field_type, mpg_picture *pic )
} else {
pic->frame_centre_horizontal_offset[3] = last_h_offset;
pic->frame_centre_vertical_offset[3] = last_v_offset;
- }
+ }
}
+#endif
+#if 0
+static
void init_mpg_picture( mpg_picture *pic, int chan, int32_t field_type)
{
pic->picture_header = 0;
@@ -960,3 +560,442 @@ void init_mpg_picture( mpg_picture *pic, int chan, int32_t field_type)
pic->last_frame_centre_vertical_offset = 0;
pic->channel = chan;
}
+#endif
+
+void dvb_filter_pes2ts_init(dvb_filter_pes2ts_t *p2ts, unsigned short pid,
+ dvb_filter_pes2ts_cb_t *cb, void *priv)
+{
+ unsigned char *buf=p2ts->buf;
+
+ buf[0]=0x47;
+ buf[1]=(pid>>8);
+ buf[2]=pid&0xff;
+ p2ts->cc=0;
+ p2ts->cb=cb;
+ p2ts->priv=priv;
+}
+
+int dvb_filter_pes2ts(dvb_filter_pes2ts_t *p2ts, unsigned char *pes, int len)
+{
+ unsigned char *buf=p2ts->buf;
+ int ret=0, rest;
+
+ //len=6+((pes[4]<<8)|pes[5]);
+
+ buf[1]|=0x40;
+ while (len>=184) {
+ buf[3]=0x10|((p2ts->cc++)&0x0f);
+ memcpy(buf+4, pes, 184);
+ if ((ret=p2ts->cb(p2ts->priv, buf)))
+ return ret;
+ len-=184; pes+=184;
+ buf[1]&=~0x40;
+ }
+ if (!len)
+ return 0;
+ buf[3]=0x30|((p2ts->cc++)&0x0f);
+ rest=183-len;
+ if (rest) {
+ buf[5]=0x00;
+ if (rest-1)
+ memset(buf+6, 0xff, rest-1);
+ }
+ buf[4]=rest;
+ memcpy(buf+5+rest, pes, len);
+ return p2ts->cb(p2ts->priv, buf);
+}
+
+void dvb_filter_ipack_reset(ipack *p)
+{
+ p->found = 0;
+ p->cid = 0;
+ p->plength = 0;
+ p->flag1 = 0;
+ p->flag2 = 0;
+ p->hlength = 0;
+ p->mpeg = 0;
+ p->check = 0;
+ p->which = 0;
+ p->done = 0;
+ p->count = 0;
+}
+
+void dvb_filter_ipack_init(ipack *p, int size,
+ void (*func)(u8 *buf, int size, void *priv))
+{
+ if ( !(p->buf = vmalloc(size*sizeof(u8))) ){
+ printk ("Couldn't allocate memory for ipack\n");
+ }
+ p->size = size;
+ p->func = func;
+ p->repack_subids = 0;
+ dvb_filter_ipack_reset(p);
+}
+
+void dvb_filter_ipack_free(ipack * p)
+{
+ if (p->buf) vfree(p->buf);
+}
+
+static
+void send_ipack(ipack *p)
+{
+ int off;
+ AudioInfo ai;
+ int ac3_off = 0;
+ int streamid=0;
+ int nframes= 0;
+ int f=0;
+
+ switch ( p->mpeg ){
+ case 2:
+ if (p->count < 10) return;
+ p->buf[3] = p->cid;
+
+ p->buf[4] = (u8)(((p->count-6) & 0xFF00) >> 8);
+ p->buf[5] = (u8)((p->count-6) & 0x00FF);
+ if (p->repack_subids && p->cid == PRIVATE_STREAM1){
+
+ off = 9+p->buf[8];
+ streamid = p->buf[off];
+ if ((streamid & 0xF8) == 0x80){
+ ai.off = 0;
+ ac3_off = ((p->buf[off+2] << 8)|
+ p->buf[off+3]);
+ if (ac3_off < p->count)
+ f=get_ac3info(p->buf+off+3+ac3_off,
+ p->count-ac3_off, &ai,0);
+ if ( !f ){
+ nframes = (p->count-off-3-ac3_off)/
+ ai.framesize + 1;
+ p->buf[off+2] = (ac3_off >> 8)& 0xFF;
+ p->buf[off+3] = (ac3_off)& 0xFF;
+ p->buf[off+1] = nframes;
+
+ ac3_off += nframes * ai.framesize -
+ p->count;
+ }
+ }
+ }
+ p->func(p->buf, p->count, p->data);
+
+ p->buf[6] = 0x80;
+ p->buf[7] = 0x00;
+ p->buf[8] = 0x00;
+ p->count = 9;
+ if (p->repack_subids && p->cid == PRIVATE_STREAM1
+ && (streamid & 0xF8)==0x80 ){
+ p->count += 4;
+ p->buf[9] = streamid;
+ p->buf[10] = (ac3_off >> 8)& 0xFF;
+ p->buf[11] = (ac3_off)& 0xFF;
+ p->buf[12] = 0;
+ }
+
+ break;
+ case 1:
+ if (p->count < 8) return;
+ p->buf[3] = p->cid;
+
+ p->buf[4] = (u8)(((p->count-6) & 0xFF00) >> 8);
+ p->buf[5] = (u8)((p->count-6) & 0x00FF);
+ p->func(p->buf, p->count, p->data);
+
+ p->buf[6] = 0x0F;
+ p->count = 7;
+ break;
+ }
+}
+
+void dvb_filter_ipack_flush(ipack *p)
+{
+ if (p->plength != MMAX_PLENGTH-6 || p->found<=6)
+ return;
+ p->plength = p->found-6;
+ p->found = 0;
+ send_ipack(p);
+ dvb_filter_ipack_reset(p);
+}
+
+static
+void write_ipack(ipack *p, u8 *data, int count)
+{
+ u8 headr[3] = { 0x00, 0x00, 0x01} ;
+
+ if (p->count < 6){
+ memcpy(p->buf, headr, 3);
+ p->count = 6;
+ }
+
+ if (p->count + count < p->size){
+ memcpy(p->buf+p->count, data, count);
+ p->count += count;
+ } else {
+ int rest = p->size - p->count;
+ memcpy(p->buf+p->count, data, rest);
+ p->count += rest;
+ send_ipack(p);
+ if (count - rest > 0)
+ write_ipack(p, data+rest, count-rest);
+ }
+}
+
+
+int dvb_filter_instant_repack(u8 *buf, int count, ipack *p)
+{
+ int l;
+ int c=0;
+
+ while (c < count && (p->mpeg == 0 ||
+ (p->mpeg == 1 && p->found < 7) ||
+ (p->mpeg == 2 && p->found < 9))
+ && (p->found < 5 || !p->done)){
+ switch ( p->found ){
+ case 0:
+ case 1:
+ if (buf[c] == 0x00) p->found++;
+ else p->found = 0;
+ c++;
+ break;
+ case 2:
+ if (buf[c] == 0x01) p->found++;
+ else if (buf[c] == 0) {
+ p->found = 2;
+ } else p->found = 0;
+ c++;
+ break;
+ case 3:
+ p->cid = 0;
+ switch (buf[c]){
+ case PROG_STREAM_MAP:
+ case PRIVATE_STREAM2:
+ case PROG_STREAM_DIR:
+ case ECM_STREAM :
+ case EMM_STREAM :
+ case PADDING_STREAM :
+ case DSM_CC_STREAM :
+ case ISO13522_STREAM:
+ p->done = 1;
+ case PRIVATE_STREAM1:
+ case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+ case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+ p->found++;
+ p->cid = buf[c];
+ c++;
+ break;
+ default:
+ p->found = 0;
+ break;
+ }
+ break;
+
+ case 4:
+ if (count-c > 1){
+ p->plen[0] = buf[c];
+ c++;
+ p->plen[1] = buf[c];
+ c++;
+ p->found+=2;
+ p->plength=(p->plen[0]<<8)|p->plen[1];
+ } else {
+ p->plen[0] = buf[c];
+ p->found++;
+ return count;
+ }
+ break;
+ case 5:
+ p->plen[1] = buf[c];
+ c++;
+ p->found++;
+ p->plength=(p->plen[0]<<8)|p->plen[1];
+ break;
+ case 6:
+ if (!p->done){
+ p->flag1 = buf[c];
+ c++;
+ p->found++;
+ if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
+ else {
+ p->hlength = 0;
+ p->which = 0;
+ p->mpeg = 1;
+ p->flag2 = 0;
+ }
+ }
+ break;
+
+ case 7:
+ if ( !p->done && p->mpeg == 2) {
+ p->flag2 = buf[c];
+ c++;
+ p->found++;
+ }
+ break;
+
+ case 8:
+ if ( !p->done && p->mpeg == 2) {
+ p->hlength = buf[c];
+ c++;
+ p->found++;
+ }
+ break;
+
+ default:
+
+ break;
+ }
+ }
+
+ if (c == count) return count;
+
+ if (!p->plength) p->plength = MMAX_PLENGTH-6;
+
+ if ( p->done || ((p->mpeg == 2 && p->found >= 9) ||
+ (p->mpeg == 1 && p->found >= 7)) ){
+ switch (p->cid){
+
+ case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+ case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+ case PRIVATE_STREAM1:
+
+ if (p->mpeg == 2 && p->found == 9) {
+ write_ipack(p, &p->flag1, 1);
+ write_ipack(p, &p->flag2, 1);
+ write_ipack(p, &p->hlength, 1);
+ }
+
+ if (p->mpeg == 1 && p->found == 7)
+ write_ipack(p, &p->flag1, 1);
+
+ if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
+ p->found < 14) {
+ while (c < count && p->found < 14) {
+ p->pts[p->found-9] = buf[c];
+ write_ipack(p, buf+c, 1);
+ c++;
+ p->found++;
+ }
+ if (c == count) return count;
+ }
+
+ if (p->mpeg == 1 && p->which < 2000) {
+
+ if (p->found == 7) {
+ p->check = p->flag1;
+ p->hlength = 1;
+ }
+
+ while (!p->which && c < count &&
+ p->check == 0xFF){
+ p->check = buf[c];
+ write_ipack(p, buf+c, 1);
+ c++;
+ p->found++;
+ p->hlength++;
+ }
+
+ if ( c == count) return count;
+
+ if ( (p->check & 0xC0) == 0x40 && !p->which){
+ p->check = buf[c];
+ write_ipack(p, buf+c, 1);
+ c++;
+ p->found++;
+ p->hlength++;
+
+ p->which = 1;
+ if ( c == count) return count;
+ p->check = buf[c];
+ write_ipack(p, buf+c, 1);
+ c++;
+ p->found++;
+ p->hlength++;
+ p->which = 2;
+ if ( c == count) return count;
+ }
+
+ if (p->which == 1){
+ p->check = buf[c];
+ write_ipack(p, buf+c, 1);
+ c++;
+ p->found++;
+ p->hlength++;
+ p->which = 2;
+ if ( c == count) return count;
+ }
+
+ if ( (p->check & 0x30) && p->check != 0xFF){
+ p->flag2 = (p->check & 0xF0) << 2;
+ p->pts[0] = p->check;
+ p->which = 3;
+ }
+
+ if ( c == count) return count;
+ if (p->which > 2){
+ if ((p->flag2 & PTS_DTS_FLAGS)
+ == PTS_ONLY){
+ while (c < count &&
+ p->which < 7){
+ p->pts[p->which-2] =
+ buf[c];
+ write_ipack(p,buf+c,1);
+ c++;
+ p->found++;
+ p->which++;
+ p->hlength++;
+ }
+ if ( c == count) return count;
+ } else if ((p->flag2 & PTS_DTS_FLAGS)
+ == PTS_DTS){
+ while (c < count &&
+ p->which< 12){
+ if (p->which< 7)
+ p->pts[p->which
+ -2] =
+ buf[c];
+ write_ipack(p,buf+c,1);
+ c++;
+ p->found++;
+ p->which++;
+ p->hlength++;
+ }
+ if ( c == count) return count;
+ }
+ p->which = 2000;
+ }
+
+ }
+
+ while (c < count && p->found < p->plength+6){
+ l = count -c;
+ if (l+p->found > p->plength+6)
+ l = p->plength+6-p->found;
+ write_ipack(p, buf+c, l);
+ p->found += l;
+ c += l;
+ }
+
+ break;
+ }
+
+
+ if ( p->done ){
+ if( p->found + count - c < p->plength+6){
+ p->found += count-c;
+ c = count;
+ } else {
+ c += p->plength+6 - p->found;
+ p->found = p->plength+6;
+ }
+ }
+
+ if (p->plength && p->found == p->plength+6) {
+ send_ipack(p);
+ dvb_filter_ipack_reset(p);
+ if (c < count)
+ dvb_filter_instant_repack(buf+c, count-c, p);
+ }
+ }
+ return count;
+}
+
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.h b/drivers/media/dvb/dvb-core/dvb_filter.h
index 062fdcae46a8..4f3a0852cd78 100644
--- a/drivers/media/dvb/dvb-core/dvb_filter.h
+++ b/drivers/media/dvb/dvb-core/dvb_filter.h
@@ -6,18 +6,18 @@
#include "demux.h"
-typedef int (pes2ts_cb_t) (void *, unsigned char *);
+typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *);
-typedef struct pes2ts_s {
+typedef struct dvb_filter_pes2ts_s {
unsigned char buf[188];
unsigned char cc;
- pes2ts_cb_t *cb;
+ dvb_filter_pes2ts_cb_t *cb;
void *priv;
-} pes2ts_t;
+} dvb_filter_pes2ts_t;
-void pes2ts_init(pes2ts_t *p2ts, unsigned short pid,
- pes2ts_cb_t *cb, void *priv);
-int pes2ts(pes2ts_t *p2ts, unsigned char *pes, int len);
+void dvb_filter_pes2ts_init(dvb_filter_pes2ts_t *p2ts, unsigned short pid,
+ dvb_filter_pes2ts_cb_t *cb, void *priv);
+int dvb_filter_pes2ts(dvb_filter_pes2ts_t *p2ts, unsigned char *pes, int len);
#define PROG_STREAM_MAP 0xBC
@@ -224,26 +224,11 @@ typedef struct audio_i{
} AudioInfo;
-void reset_ipack(ipack *p);
-int instant_repack(u8 *buf, int count, ipack *p);
-void init_ipack(ipack *p, int size,
+void dvb_filter_ipack_reset(ipack *p);
+int dvb_filter_instant_repack(u8 *buf, int count, ipack *p);
+void dvb_filter_ipack_init(ipack *p, int size,
void (*func)(u8 *buf, int size, void *priv));
-void free_ipack(ipack * p);
-void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv,
- void (*pes_write)(u8 *buf, int count, void *data),
- void *priv);
-void ts_to_pes(ipack *p, u8 *buf);
-void send_ipack(ipack *p);
-void send_ipack_rest(ipack *p);
-int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr);
-int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr);
-int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr);
-uint8_t *skip_pes_header(uint8_t **bufp);
-void initialize_quant_matrix( uint32_t *matrix );
-void initialize_mpg_picture(mpg_picture *pic);
-void init_mpg_picture( mpg_picture *pic, int chan, int32_t field_type);
-void mpg_set_picture_parameter( int32_t field_type, mpg_picture *pic );
-int read_sequence_header(uint8_t *headr, VideoInfo *vi, int pr);
-int read_gop_header(uint8_t *headr, mpg_picture *pic, int pr);
-int read_picture_header(uint8_t *headr, mpg_picture *pic, int field, int pr);
+void dvb_filter_ipack_free(ipack * p);
+void dvb_filter_ipack_flush(ipack *p);
+
#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index f64279a047a4..344621653fea 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -83,7 +83,7 @@ struct dvb_frontend_data {
struct dvb_frontend_ioctl_data {
struct list_head list_head;
- struct dvb_adapter_s *adapter;
+ struct dvb_adapter *adapter;
int (*before_ioctl) (struct dvb_frontend *frontend,
unsigned int cmd, void *arg);
int (*after_ioctl) (struct dvb_frontend *frontend,
@@ -336,9 +336,6 @@ int dvb_frontend_set_parameters (struct dvb_frontend_data *fe,
struct dvb_frontend *frontend = &fe->frontend;
int err;
- dprintk ("%s: f == %i, drift == %i\n",
- __FUNCTION__, param->frequency, fe->lnb_drift);
-
dvb_bend_frequency (fe, 0);
if (first_trial) {
@@ -352,6 +349,9 @@ int dvb_frontend_set_parameters (struct dvb_frontend_data *fe,
sizeof (struct dvb_frontend_parameters));
}
+ dprintk ("%s: f == %i, drift == %i\n",
+ __FUNCTION__, param->frequency, fe->lnb_drift);
+
param->frequency += fe->lnb_drift + fe->bending;
err = dvb_frontend_internal_ioctl (frontend, FE_SET_FRONTEND, param);
param->frequency -= fe->lnb_drift + fe->bending;
@@ -367,9 +367,8 @@ void dvb_frontend_init (struct dvb_frontend_data *fe)
struct dvb_frontend *frontend = &fe->frontend;
struct dvb_frontend_parameters *init_param;
- printk ("%s: initialising frontend %i:%i (%s)...\n", __FUNCTION__,
- frontend->i2c->adapter->num, frontend->i2c->id,
- fe->info->name);
+ printk ("DVB: initialising frontend %i:%i (%s)...\n",
+ frontend->i2c->adapter->num, frontend->i2c->id, fe->info->name);
dvb_frontend_internal_ioctl (frontend, FE_INIT, NULL);
@@ -436,15 +435,20 @@ void dvb_frontend_recover (struct dvb_frontend_data *fe)
*/
{
int j = fe->lost_sync_count;
- int stepsize = fe->info->frequency_stepsize;
-
- if (j % 32 == 0)
- fe->lnb_drift = 0;
+ int stepsize;
- if (j % 2)
- fe->lnb_drift += stepsize * ((j+1)/2);
+ if (fe->info->type == FE_QPSK)
+ stepsize = fe->parameters.u.qpsk.symbol_rate / 16000;
else
+ stepsize = fe->info->frequency_stepsize * 2;
+
+ if (j % 32 == 0) {
+ fe->lnb_drift = 0;
+ } else {
fe->lnb_drift = -fe->lnb_drift;
+ if (j % 2)
+ fe->lnb_drift += stepsize;
+ }
dvb_frontend_set_parameters (fe, &fe->parameters, 0);
}
@@ -511,7 +515,8 @@ int dvb_frontend_thread (void *data)
fe->lost_sync_count = 0;
} else {
fe->lost_sync_count++;
-
+ if (fe->lost_sync_count < 10) /* XXX FIXME CHECKME! */
+ continue;
dvb_frontend_recover (fe);
delay = HZ/5;
if (jiffies - fe->lost_sync_jiffies > TIMEOUT) {
@@ -627,7 +632,7 @@ unsigned int dvb_frontend_poll (struct file *file, struct poll_table_struct *wai
static
int dvb_frontend_open (struct inode *inode, struct file *file)
{
- dvb_device_t *dvbdev = file->private_data;
+ struct dvb_device *dvbdev = file->private_data;
struct dvb_frontend_data *fe = dvbdev->priv;
int ret;
@@ -648,7 +653,7 @@ int dvb_frontend_open (struct inode *inode, struct file *file)
static
int dvb_frontend_release (struct inode *inode, struct file *file)
{
- dvb_device_t *dvbdev = file->private_data;
+ struct dvb_device *dvbdev = file->private_data;
struct dvb_frontend_data *fe = dvbdev->priv;
dprintk ("%s\n", __FUNCTION__);
@@ -661,7 +666,7 @@ int dvb_frontend_release (struct inode *inode, struct file *file)
int
-dvb_add_frontend_ioctls (struct dvb_adapter_s *adapter,
+dvb_add_frontend_ioctls (struct dvb_adapter *adapter,
int (*before_ioctl) (struct dvb_frontend *frontend,
unsigned int cmd, void *arg),
int (*after_ioctl) (struct dvb_frontend *frontend,
@@ -715,7 +720,7 @@ dvb_add_frontend_ioctls (struct dvb_adapter_s *adapter,
void
-dvb_remove_frontend_ioctls (struct dvb_adapter_s *adapter,
+dvb_remove_frontend_ioctls (struct dvb_adapter *adapter,
int (*before_ioctl) (struct dvb_frontend *frontend,
unsigned int cmd, void *arg),
int (*after_ioctl) (struct dvb_frontend *frontend,
@@ -748,7 +753,7 @@ dvb_remove_frontend_ioctls (struct dvb_adapter_s *adapter,
int
-dvb_add_frontend_notifier (struct dvb_adapter_s *adapter,
+dvb_add_frontend_notifier (struct dvb_adapter *adapter,
void (*callback) (fe_status_t s, void *data),
void *data)
{
@@ -791,7 +796,7 @@ dvb_add_frontend_notifier (struct dvb_adapter_s *adapter,
void
-dvb_remove_frontend_notifier (struct dvb_adapter_s *adapter,
+dvb_remove_frontend_notifier (struct dvb_adapter *adapter,
void (*callback) (fe_status_t s, void *data))
{
struct list_head *entry;
@@ -827,11 +832,11 @@ dvb_remove_frontend_notifier (struct dvb_adapter_s *adapter,
static
struct file_operations dvb_frontend_fops = {
- owner: THIS_MODULE,
- ioctl: dvb_generic_ioctl,
- poll: dvb_frontend_poll,
- open: dvb_frontend_open,
- release: dvb_frontend_release
+ .owner = THIS_MODULE,
+ .ioctl = dvb_generic_ioctl,
+ .poll = dvb_frontend_poll,
+ .open = dvb_frontend_open,
+ .release = dvb_frontend_release
};
@@ -845,9 +850,11 @@ dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend,
{
struct list_head *entry;
struct dvb_frontend_data *fe;
- dvb_device_t dvbdev_template = { users: 1, writers: 1,
- fops: &dvb_frontend_fops,
- kernel_ioctl: dvb_frontend_ioctl
+ static const struct dvb_device dvbdev_template = {
+ .users = 1,
+ .writers = 1,
+ .fops = &dvb_frontend_fops,
+ .kernel_ioctl = dvb_frontend_ioctl
};
dprintk ("%s\n", __FUNCTION__);
@@ -878,7 +885,9 @@ dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend,
list_for_each (entry, &frontend_ioctl_list) {
struct dvb_frontend_ioctl_data *ioctl;
- ioctl = list_entry (entry, struct dvb_frontend_ioctl_data, list_head);
+ ioctl = list_entry (entry,
+ struct dvb_frontend_ioctl_data,
+ list_head);
if (ioctl->adapter == i2c->adapter) {
fe->frontend.before_ioctl = ioctl->before_ioctl;
@@ -936,3 +945,4 @@ MODULE_PARM(dvb_frontend_debug,"i");
MODULE_PARM(dvb_shutdown_timeout,"i");
MODULE_PARM_DESC(dvb_frontend_debug, "enable verbose debug messages");
MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware");
+
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 9a65459e69f3..5c1950022383 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -90,7 +90,7 @@ dvb_unregister_frontend (int (*ioctl) (struct dvb_frontend *frontend,
* Return value: number of frontends where the ioctl's were applied.
*/
extern int
-dvb_add_frontend_ioctls (struct dvb_adapter_s *adapter,
+dvb_add_frontend_ioctls (struct dvb_adapter *adapter,
int (*before_ioctl) (struct dvb_frontend *frontend,
unsigned int cmd, void *arg),
int (*after_ioctl) (struct dvb_frontend *frontend,
@@ -99,18 +99,18 @@ dvb_add_frontend_ioctls (struct dvb_adapter_s *adapter,
extern void
-dvb_remove_frontend_ioctls (struct dvb_adapter_s *adapter,
+dvb_remove_frontend_ioctls (struct dvb_adapter *adapter,
int (*before_ioctl) (struct dvb_frontend *frontend,
unsigned int cmd, void *arg),
int (*after_ioctl) (struct dvb_frontend *frontend,
unsigned int cmd, void *arg));
extern int
-dvb_add_frontend_notifier (struct dvb_adapter_s *adapter,
+dvb_add_frontend_notifier (struct dvb_adapter *adapter,
void (*callback) (fe_status_t s, void *data),
void *data);
extern void
-dvb_remove_frontend_notifier (struct dvb_adapter_s *adapter,
+dvb_remove_frontend_notifier (struct dvb_adapter *adapter,
void (*callback) (fe_status_t s, void *data));
#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_i2c.c b/drivers/media/dvb/dvb-core/dvb_i2c.c
index 7aae8c93dc5c..e9a48ba1af9f 100644
--- a/drivers/media/dvb/dvb-core/dvb_i2c.c
+++ b/drivers/media/dvb/dvb-core/dvb_i2c.c
@@ -173,7 +173,7 @@ struct dvb_i2c_bus*
dvb_register_i2c_bus (int (*xfer) (struct dvb_i2c_bus *i2c,
struct i2c_msg msgs[], int num),
void *data,
- struct dvb_adapter_s *adapter,
+ struct dvb_adapter *adapter,
int id)
{
struct dvb_i2c_bus *i2c;
@@ -200,7 +200,7 @@ dvb_register_i2c_bus (int (*xfer) (struct dvb_i2c_bus *i2c,
struct dvb_i2c_bus*
dvb_find_i2c_bus (int (*xfer) (struct dvb_i2c_bus *i2c,
struct i2c_msg msgs[], int num),
- struct dvb_adapter_s *adapter,
+ struct dvb_adapter *adapter,
int id)
{
struct list_head *entry;
@@ -231,7 +231,7 @@ dvb_find_i2c_bus (int (*xfer) (struct dvb_i2c_bus *i2c,
void dvb_unregister_i2c_bus (int (*xfer) (struct dvb_i2c_bus *i2c,
struct i2c_msg msgs[], int num),
- struct dvb_adapter_s *adapter,
+ struct dvb_adapter *adapter,
int id)
{
struct dvb_i2c_bus *i2c = dvb_find_i2c_bus (xfer, adapter, id);
diff --git a/drivers/media/dvb/dvb-core/dvb_i2c.h b/drivers/media/dvb/dvb-core/dvb_i2c.h
index c06e4d1bceaa..137e9b155ed2 100644
--- a/drivers/media/dvb/dvb-core/dvb_i2c.h
+++ b/drivers/media/dvb/dvb-core/dvb_i2c.h
@@ -32,7 +32,7 @@ struct dvb_i2c_bus {
struct list_head list_head;
int (*xfer) (struct dvb_i2c_bus *i2c, struct i2c_msg msgs[], int num);
void *data;
- struct dvb_adapter_s *adapter;
+ struct dvb_adapter *adapter;
int id;
struct list_head client_list;
};
@@ -43,13 +43,13 @@ struct dvb_i2c_bus* dvb_register_i2c_bus (int (*xfer) (struct dvb_i2c_bus *i2c,
struct i2c_msg msgs[],
int num),
void *data,
- struct dvb_adapter_s *adapter,
+ struct dvb_adapter *adapter,
int id);
extern
void dvb_unregister_i2c_bus (int (*xfer) (struct dvb_i2c_bus *i2c,
struct i2c_msg msgs[], int num),
- struct dvb_adapter_s *adapter,
+ struct dvb_adapter *adapter,
int id);
diff --git a/drivers/media/dvb/dvb-core/dvb_ksyms.c b/drivers/media/dvb/dvb-core/dvb_ksyms.c
index 619ec95b66ef..bdfa82b8ba98 100644
--- a/drivers/media/dvb/dvb-core/dvb_ksyms.c
+++ b/drivers/media/dvb/dvb-core/dvb_ksyms.c
@@ -9,11 +9,12 @@
#include "dvb_net.h"
-EXPORT_SYMBOL(DmxDevInit);
-EXPORT_SYMBOL(DmxDevRelease);
-EXPORT_SYMBOL(DvbDmxInit);
-EXPORT_SYMBOL(DvbDmxRelease);
-EXPORT_SYMBOL(DvbDmxSWFilterPackets);
+EXPORT_SYMBOL(dvb_dmxdev_init);
+EXPORT_SYMBOL(dvb_dmxdev_release);
+EXPORT_SYMBOL(dvb_dmx_init);
+EXPORT_SYMBOL(dvb_dmx_release);
+EXPORT_SYMBOL(dvb_dmx_swfilter_packet);
+EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
EXPORT_SYMBOL(dvb_register_frontend);
EXPORT_SYMBOL(dvb_unregister_frontend);
@@ -37,13 +38,12 @@ EXPORT_SYMBOL(dvb_unregister_device);
EXPORT_SYMBOL(dvb_generic_ioctl);
EXPORT_SYMBOL(dvb_generic_open);
EXPORT_SYMBOL(dvb_generic_release);
-EXPORT_SYMBOL(generic_usercopy);
-
-EXPORT_SYMBOL(init_ipack);
-EXPORT_SYMBOL(reset_ipack);
-EXPORT_SYMBOL(free_ipack);
-EXPORT_SYMBOL(send_ipack_rest);
-EXPORT_SYMBOL(instant_repack);
-EXPORT_SYMBOL(pes2ts_init);
-EXPORT_SYMBOL(pes2ts);
+
+EXPORT_SYMBOL(dvb_filter_ipack_init);
+EXPORT_SYMBOL(dvb_filter_ipack_reset);
+EXPORT_SYMBOL(dvb_filter_ipack_free);
+EXPORT_SYMBOL(dvb_filter_ipack_flush);
+EXPORT_SYMBOL(dvb_filter_instant_repack);
+EXPORT_SYMBOL(dvb_filter_pes2ts_init);
+EXPORT_SYMBOL(dvb_filter_pes2ts);
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 6553682a8a37..ec5e95a23647 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -435,7 +435,7 @@ dvb_net_remove_if(dvb_net_t *dvbnet, int num)
int dvb_net_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
- dvb_device_t *dvbdev=(dvb_device_t *) file->private_data;
+ struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
dvb_net_t *dvbnet=(dvb_net_t *) dvbdev->priv;
if (((file->f_flags&O_ACCMODE)==O_RDONLY))
@@ -462,21 +462,18 @@ int dvb_net_ioctl(struct inode *inode, struct file *file,
}
static struct file_operations dvb_net_fops = {
- owner: THIS_MODULE,
- read: 0,
- write: 0,
- ioctl: dvb_generic_ioctl,
- open: dvb_generic_open,
- release: dvb_generic_release,
- poll: 0,
+ .owner = THIS_MODULE,
+ .ioctl = dvb_generic_ioctl,
+ .open = dvb_generic_open,
+ .release = dvb_generic_release,
};
-static dvb_device_t dvbdev_net = {
- priv: 0,
- users: 1,
- writers: 1,
- fops: &dvb_net_fops,
- kernel_ioctl: dvb_net_ioctl,
+static struct dvb_device dvbdev_net = {
+ .priv = 0,
+ .users = 1,
+ .writers = 1,
+ .fops = &dvb_net_fops,
+ .kernel_ioctl = dvb_net_ioctl,
};
void
@@ -493,7 +490,7 @@ dvb_net_release(dvb_net_t *dvbnet)
}
int
-dvb_net_init(dvb_adapter_t *adap, dvb_net_t *dvbnet, dmx_demux_t *demux)
+dvb_net_init(struct dvb_adapter *adap, dvb_net_t *dvbnet, dmx_demux_t *demux)
{
int i;
diff --git a/drivers/media/dvb/dvb-core/dvb_net.h b/drivers/media/dvb/dvb-core/dvb_net.h
index 714c095655f4..16d2703567cb 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.h
+++ b/drivers/media/dvb/dvb-core/dvb_net.h
@@ -47,7 +47,7 @@ typedef struct dvb_net_priv_s {
} dvb_net_priv_t;
typedef struct dvb_net_s {
- dvb_device_t *dvbdev;
+ struct dvb_device *dvbdev;
int card_num;
int dev_num;
@@ -58,6 +58,6 @@ typedef struct dvb_net_s {
void dvb_net_release(dvb_net_t *);
-int dvb_net_init(dvb_adapter_t *, dvb_net_t *, dmx_demux_t *);
+int dvb_net_init(struct dvb_adapter *, dvb_net_t *, dmx_demux_t *);
#endif
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 37ac0fb2ded0..bbec3083ab76 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -37,6 +37,7 @@
#include <asm/system.h>
#include <linux/kmod.h>
#include <linux/slab.h>
+#include <linux/videodev.h>
#include "compat.h"
#include "dvbdev.h"
@@ -69,17 +70,17 @@ static char *dnames[] = {
static
-dvb_device_t* dvbdev_find_device (int minor)
+struct dvb_device* dvbdev_find_device (int minor)
{
struct list_head *entry;
list_for_each (entry, &dvb_adapter_list) {
struct list_head *entry0;
- dvb_adapter_t *adap;
- adap = list_entry (entry, dvb_adapter_t, list_head);
+ struct dvb_adapter *adap;
+ adap = list_entry (entry, struct dvb_adapter, list_head);
list_for_each (entry0, &adap->device_list) {
- dvb_device_t *dev;
- dev = list_entry (entry0, dvb_device_t, list_head);
+ struct dvb_device *dev;
+ dev = list_entry (entry0, struct dvb_device, list_head);
if (nums2minor(adap->num, dev->type, dev->id) == minor)
return dev;
}
@@ -92,7 +93,7 @@ dvb_device_t* dvbdev_find_device (int minor)
static
int dvb_device_open(struct inode *inode, struct file *file)
{
- dvb_device_t *dvbdev;
+ struct dvb_device *dvbdev;
dvbdev = dvbdev_find_device (minor(inode->i_rdev));
@@ -118,13 +119,8 @@ int dvb_device_open(struct inode *inode, struct file *file)
static struct file_operations dvb_device_fops =
{
- owner: THIS_MODULE,
- read: NULL,
- write: NULL,
- ioctl: NULL,
- open: dvb_device_open,
- release: NULL,
- poll: NULL,
+ .owner = THIS_MODULE,
+ .open = dvb_device_open,
};
#endif /* CONFIG_DVB_DEVFS_ONLY */
@@ -132,7 +128,7 @@ static struct file_operations dvb_device_fops =
int dvb_generic_open(struct inode *inode, struct file *file)
{
- dvb_device_t *dvbdev = file->private_data;
+ struct dvb_device *dvbdev = file->private_data;
if (!dvbdev)
return -ENODEV;
@@ -153,7 +149,7 @@ int dvb_generic_open(struct inode *inode, struct file *file)
int dvb_generic_release(struct inode *inode, struct file *file)
{
- dvb_device_t *dvbdev = file->private_data;
+ struct dvb_device *dvbdev = file->private_data;
if (!dvbdev)
return -ENODEV;
@@ -166,73 +162,10 @@ int dvb_generic_release(struct inode *inode, struct file *file)
}
-/*
- * helper function -- handles userspace copying for ioctl arguments
- */
-int
-generic_usercopy(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- int (*func)(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg))
-{
- char sbuf[128];
- void *mbuf = NULL;
- void *parg = NULL;
- int err = -EINVAL;
-
- /* Copy arguments into temp kernel buffer */
- switch (_IOC_DIR(cmd)) {
- case _IOC_NONE:
- parg = (void *)arg;
- break;
- case _IOC_READ: /* some v4l ioctls are marked wrong ... */
- case _IOC_WRITE:
- case (_IOC_WRITE | _IOC_READ):
- if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
- parg = sbuf;
- } else {
- /* too big to allocate from stack */
- mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
- if (NULL == mbuf)
- return -ENOMEM;
- parg = mbuf;
- }
-
- err = -EFAULT;
- if (copy_from_user(parg, (void *)arg, _IOC_SIZE(cmd)))
- goto out;
- break;
- }
-
- /* call driver */
- if ((err = func(inode, file, cmd, parg)) == -ENOIOCTLCMD)
- err = -EINVAL;
-
- if (err < 0)
- goto out;
-
- /* Copy results into user buffer */
- switch (_IOC_DIR(cmd))
- {
- case _IOC_READ:
- case (_IOC_WRITE | _IOC_READ):
- if (copy_to_user((void *)arg, parg, _IOC_SIZE(cmd)))
- err = -EFAULT;
- break;
- }
-
-out:
- if (mbuf)
- kfree(mbuf);
-
- return err;
-}
-
-
int dvb_generic_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- dvb_device_t *dvbdev = file->private_data;
+ struct dvb_device *dvbdev = file->private_data;
if (!dvbdev)
return -ENODEV;
@@ -240,20 +173,20 @@ int dvb_generic_ioctl(struct inode *inode, struct file *file,
if (!dvbdev->kernel_ioctl)
return -EINVAL;
- return generic_usercopy (inode, file, cmd, arg, dvbdev->kernel_ioctl);
+ return video_usercopy (inode, file, cmd, arg, dvbdev->kernel_ioctl);
}
static
-int dvbdev_get_free_id (struct dvb_adapter_s *adap, int type)
+int dvbdev_get_free_id (struct dvb_adapter *adap, int type)
{
u32 id = 0;
while (id < DVB_MAX_IDS) {
struct list_head *entry;
list_for_each (entry, &adap->device_list) {
- dvb_device_t *dev;
- dev = list_entry (entry, dvb_device_t, list_head);
+ struct dvb_device *dev;
+ dev = list_entry (entry, struct dvb_device, list_head);
if (dev->type == type && dev->id == id)
goto skip;
}
@@ -265,12 +198,12 @@ skip:
}
-int dvb_register_device(dvb_adapter_t *adap, dvb_device_t **pdvbdev,
- dvb_device_t *template, void *priv, int type)
+int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ const struct dvb_device *template, void *priv, int type)
{
u32 id;
char name [20];
- dvb_device_t *dvbdev;
+ struct dvb_device *dvbdev;
if (down_interruptible (&dvbdev_register_lock))
return -ERESTARTSYS;
@@ -282,7 +215,7 @@ int dvb_register_device(dvb_adapter_t *adap, dvb_device_t **pdvbdev,
return -ENFILE;
}
- *pdvbdev = dvbdev = kmalloc(sizeof(dvb_device_t), GFP_KERNEL);
+ *pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL);
if (!dvbdev) {
up(&dvbdev_register_lock);
@@ -291,7 +224,7 @@ int dvb_register_device(dvb_adapter_t *adap, dvb_device_t **pdvbdev,
up (&dvbdev_register_lock);
- memcpy(dvbdev, template, sizeof(dvb_device_t));
+ memcpy(dvbdev, template, sizeof(struct dvb_device));
dvbdev->type = type;
dvbdev->id = id;
dvbdev->adapter = adap;
@@ -307,15 +240,15 @@ int dvb_register_device(dvb_adapter_t *adap, dvb_device_t **pdvbdev,
S_IFCHR | S_IRUSR | S_IWUSR,
dvbdev->fops, dvbdev);
- dprintk("%s: register adapter%d/%s @ minor: %i (0x%02x) - dvbdev: %p\n",
- __FUNCTION__, adap->num, name, nums2minor(adap->num, type, id),
- nums2minor(adap->num, type, id), dvbdev);
+ dprintk("DVB: register adapter%d/%s @ minor: %i (0x%02x)\n",
+ adap->num, name, nums2minor(adap->num, type, id),
+ nums2minor(adap->num, type, id));
return 0;
}
-void dvb_unregister_device(dvb_device_t *dvbdev)
+void dvb_unregister_device(struct dvb_device *dvbdev)
{
if (!dvbdev)
return;
@@ -334,8 +267,8 @@ int dvbdev_get_free_adapter_num (void)
while (1) {
struct list_head *entry;
list_for_each (entry, &dvb_adapter_list) {
- dvb_adapter_t *adap;
- adap = list_entry (entry, dvb_adapter_t, list_head);
+ struct dvb_adapter *adap;
+ adap = list_entry (entry, struct dvb_adapter, list_head);
if (adap->num == num)
goto skip;
}
@@ -348,10 +281,10 @@ skip:
}
-int dvb_register_adapter(dvb_adapter_t **padap, char *name)
+int dvb_register_adapter(struct dvb_adapter **padap, char *name)
{
char dirname[16];
- dvb_adapter_t *adap;
+ struct dvb_adapter *adap;
int num;
if (down_interruptible (&dvbdev_register_lock))
@@ -362,17 +295,17 @@ int dvb_register_adapter(dvb_adapter_t **padap, char *name)
return -ENFILE;
}
- if (!(*padap = adap = kmalloc(sizeof(dvb_adapter_t), GFP_KERNEL))) {
+ if (!(*padap = adap = kmalloc(sizeof(struct dvb_adapter), GFP_KERNEL))) {
up(&dvbdev_register_lock);
return -ENOMEM;
}
- memset (adap, 0, sizeof(dvb_adapter_t));
+ memset (adap, 0, sizeof(struct dvb_adapter));
INIT_LIST_HEAD (&adap->device_list);
MOD_INC_USE_COUNT;
- printk ("%s: registering new adapter (%s).\n", __FUNCTION__, name);
+ printk ("DVB: registering new adapter (%s).\n", name);
sprintf(dirname, "dvb/adapter%d", num);
adap->devfs_handle = devfs_mk_dir(NULL, dirname, NULL);
@@ -386,7 +319,7 @@ int dvb_register_adapter(dvb_adapter_t **padap, char *name)
}
-int dvb_unregister_adapter(dvb_adapter_t *adap)
+int dvb_unregister_adapter(struct dvb_adapter *adap)
{
devfs_unregister (adap->devfs_handle);
if (down_interruptible (&dvbdev_register_lock))
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 52b0f0d09b54..e0159f6968a3 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -43,49 +43,48 @@
#define DVB_DEVICE_OSD 8
-typedef struct dvb_adapter_s
-{
+struct dvb_adapter {
int num;
devfs_handle_t devfs_handle;
struct list_head list_head;
struct list_head device_list;
-} dvb_adapter_t;
+};
-typedef struct dvb_device
-{
+struct dvb_device {
struct list_head list_head;
struct file_operations *fops;
devfs_handle_t devfs_handle;
- dvb_adapter_t *adapter;
+ struct dvb_adapter *adapter;
int type;
u32 id;
int users;
int writers;
- /* don't really need those !? */
+ /* don't really need those !? -- FIXME: use video_usercopy */
int (*kernel_ioctl)(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg); // FIXME: use generic_usercopy()
+ unsigned int cmd, void *arg);
void *priv;
-} dvb_device_t;
+};
-int dvb_register_device(dvb_adapter_t *adap, dvb_device_t **pdvbdev,
- dvb_device_t *template, void *priv, int type);
-void dvb_unregister_device(struct dvb_device *dvbdev);
+extern int dvb_register_adapter (struct dvb_adapter **padap, char *name);
+extern int dvb_unregister_adapter (struct dvb_adapter *adap);
-int dvb_register_adapter(dvb_adapter_t **padap, char *name);
-int dvb_unregister_adapter(dvb_adapter_t *adap);
+extern int dvb_register_device (struct dvb_adapter *adap,
+ struct dvb_device **pdvbdev,
+ const struct dvb_device *template,
+ void *priv,
+ int type);
-int dvb_generic_ioctl(struct inode *inode, struct file *file,
+extern void dvb_unregister_device (struct dvb_device *dvbdev);
+
+extern int dvb_generic_open (struct inode *inode, struct file *file);
+extern int dvb_generic_release (struct inode *inode, struct file *file);
+extern int dvb_generic_ioctl (struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
-int dvb_generic_open(struct inode *inode, struct file *file);
-int dvb_generic_release(struct inode *inode, struct file *file);
-int generic_usercopy(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- int (*func)(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg));
-
-#endif /* #ifndef __DVBDEV_H */
+
+#endif /* #ifndef _DVBDEV_H_ */
+
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index a4b18ed842c8..3e7f3583a5a7 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -23,6 +23,30 @@ config DVB_ALPS_BSRV2
DVB adapter simply enable all supported frontends, the
right one will get autodetected.
+config DVB_ALPS_TDLB7
+ tristate "Alps TDLB7 (OFDM)"
+ depends on DVB_CORE
+ help
+ A DVB-T tuner module. Say Y when you want to support this frontend.
+
+ This tuner module needs some microcode located in a file called
+ "Sc_main.mc" in the windows driver. Please pass the module parameter
+ mcfile="/PATH/FILENAME" when loading alps_tdlb7.o.
+
+ If you don't know what tuner module is soldered on your
+ DVB adapter simply enable all supported frontends, the
+ right one will get autodetected.
+
+config DVB_ALPS_TDMB7
+ tristate "Alps BSRV2 (OFDM)"
+ depends on DVB_CORE
+ help
+ A DVB-S tuner module. Say Y when you want to support this frontend.
+
+ If you don't know what tuner module is soldered on your
+ DVB adapter simply enable all supported frontends, the
+ right one will get autodetected.
+
config DVB_GRUNDIG_29504_491
tristate "Grundig 29504-491 (QPSK)"
depends on DVB_CORE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 3ee94a40a3ec..c693af892d57 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -6,6 +6,8 @@ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
obj-$(CONFIG_DVB_ALPS_BSRU6) += alps_bsru6.o
obj-$(CONFIG_DVB_ALPS_BSRV2) += alps_bsrv2.o
+obj-$(CONFIG_DVB_ALPS_TDLB7) += alps_tdlb7.o
+obj-$(CONFIG_DVB_ALPS_TDMB7) += alps_tdmb7.o
obj-$(CONFIG_DVB_GRUNDIG_29504_491) += grundig_29504-491.o
obj-$(CONFIG_DVB_GRUNDIG_29504_401) += grundig_29504-401.o
obj-$(CONFIG_DVB_VES1820) += ves1820.o
diff --git a/drivers/media/dvb/frontends/alps_bsru6.c b/drivers/media/dvb/frontends/alps_bsru6.c
index 1d2c9983c6db..f67ab386a51d 100644
--- a/drivers/media/dvb/frontends/alps_bsru6.c
+++ b/drivers/media/dvb/frontends/alps_bsru6.c
@@ -1,8 +1,9 @@
/*
- Alps BSRU6 DVB QPSK frontend driver
+ Alps BSRU6 and LG TDQB-S00x DVB QPSK frontend driver
Copyright (C) 2001-2002 Convergence Integrated Media GmbH
- <ralph@convergence.de>, <holger@convergence.de>
+ <ralph@convergence.de>, <holger@convergence.de>,
+ <js@convergence.de>
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
@@ -32,12 +33,16 @@ static int debug = 0;
#define M_CLK (88000000UL)
-
/* M=21, K=0, P=0, f_VCO = 4MHz*4*(M+1)/(K+1) = 352 MHz */
+
static
struct dvb_frontend_info bsru6_info = {
+#ifdef CONFIG_ALPS_BSRU6_IS_LG_TDQBS00X
+ name: "LG TDQB-S00x",
+#else
name: "Alps BSRU6",
+#endif
type: FE_QPSK,
frequency_min: 950000,
frequency_max: 2150000,
@@ -63,7 +68,8 @@ u8 init_tab [] = {
0x05, 0x35, // SDAT:0 SCLT:0 I2CT:1
0x06, 0x00, // DAC mode and MSB
0x07, 0x00, // DAC LSB
- 0x08, 0x43, // DiSEqC
+// 0x08, 0x43, // DiSEqC
+ 0x08, 0x03, // DiSEqC
0x09, 0x00,
0x0a, 0x42,
0x0c, 0x51, // QPSK reverse:1 Nyquist:0 OP0 val:1 OP0 con:1 OP1 val:1 OP1 con:1
@@ -79,17 +85,20 @@ u8 init_tab [] = {
0x15, 0xc9, // lock detector threshold
0x16, 0x1d,
- 0x17, 0x0,
+ 0x17, 0x00,
0x18, 0x14,
0x19, 0xf2,
0x1a, 0x11,
0x1b, 0x9c,
- 0x1c, 0x0,
- 0x1d, 0x0,
- 0x1e, 0xb,
+ 0x1c, 0x00,
+ 0x1d, 0x00,
+ 0x1e, 0x0b,
+ 0x1f, 0x50,
+ 0x20, 0x00,
+ 0x21, 0x00,
0x22, 0x00,
0x23, 0x00,
0x24, 0xff,
@@ -110,16 +119,37 @@ u8 init_tab [] = {
0x33, 0xfc, // rs control
0x34, 0x93, // error control
-
0x0b, 0x00,
- 0x27, 0x00, 0x2f, 0x00, 0x30, 0x00,
- 0x35, 0x00, 0x36, 0x00, 0x37, 0x00,
- 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00,
- 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00,
- 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00,
- 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00,
- 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00,
- 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00
+ 0x27, 0x00,
+ 0x2f, 0x00,
+ 0x30, 0x00,
+ 0x35, 0x00,
+ 0x36, 0x00,
+ 0x37, 0x00,
+ 0x38, 0x00,
+ 0x39, 0x00,
+ 0x3a, 0x00,
+ 0x3b, 0x00,
+ 0x3c, 0x00,
+ 0x3d, 0x00,
+ 0x3e, 0x00,
+ 0x3f, 0x00,
+ 0x40, 0x00,
+ 0x41, 0x00,
+ 0x42, 0x00,
+ 0x43, 0x00,
+ 0x44, 0x00,
+ 0x45, 0x00,
+ 0x46, 0x00,
+ 0x47, 0x00,
+ 0x48, 0x00,
+ 0x49, 0x00,
+ 0x4a, 0x00,
+ 0x4b, 0x00,
+ 0x4c, 0x00,
+ 0x4d, 0x00,
+ 0x4e, 0x00,
+ 0x4f, 0x00
};
@@ -231,12 +261,27 @@ int stv0299_init (struct dvb_i2c_bus *i2c)
static
-int stv0299_set_inversion (struct dvb_i2c_bus *i2c, int inversion)
+int stv0299_set_inversion (struct dvb_i2c_bus *i2c,
+ fe_spectral_inversion_t inversion)
{
u8 val;
dprintk ("%s\n", __FUNCTION__);
+#ifdef CONFIG_ALPS_BSRU6_IS_LG_TDQBS00X /* reversed I/Q pins */
+ switch (inversion) {
+ case INVERSION_AUTO:
+ return -EOPNOTSUPP;
+ case INVERSION_OFF:
+ val = stv0299_readreg (i2c, 0x0c);
+ return stv0299_writereg (i2c, 0x0c, val & 0xfe);
+ case INVERSION_ON:
+ val = stv0299_readreg (i2c, 0x0c);
+ return stv0299_writereg (i2c, 0x0c, val | 0x01);
+ default:
+ return -EINVAL;
+ };
+#else
switch (inversion) {
case INVERSION_AUTO:
return -EOPNOTSUPP;
@@ -248,7 +293,8 @@ int stv0299_set_inversion (struct dvb_i2c_bus *i2c, int inversion)
return stv0299_writereg (i2c, 0x0c, val & 0xfe);
default:
return -EINVAL;
- }
+ };
+#endif
}
@@ -277,9 +323,10 @@ int stv0299_set_FEC (struct dvb_i2c_bus *i2c, fe_code_rate_t fec)
static
-fe_code_rate_t stv0299_get_FEC (struct dvb_i2c_bus *i2c)
+fe_code_rate_t stv0299_get_fec (struct dvb_i2c_bus *i2c)
{
- static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_1_2 };
+ static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6,
+ FEC_7_8, FEC_1_2 };
u8 index;
dprintk ("%s\n", __FUNCTION__);
@@ -343,6 +390,9 @@ int stv0299_send_diseqc_msg (struct dvb_i2c_bus *i2c,
dprintk ("%s\n", __FUNCTION__);
+ if (stv0299_wait_diseqc_idle (i2c, 100) < 0)
+ return -ETIMEDOUT;
+
val = stv0299_readreg (i2c, 0x08);
if (stv0299_writereg (i2c, 0x08, (val & ~0x7) | 0x6)) /* DiSEqC mode */
@@ -356,12 +406,7 @@ int stv0299_send_diseqc_msg (struct dvb_i2c_bus *i2c,
return -EREMOTEIO;
}
- /* Shouldn't we wait for idle state (FE=1, FF=0) here to
- make certain all bytes have been sent ?
- Hmm, actually we should do that before all mode changes too ...
- if (stv0299_wait_diseqc_idle (i2c, 100) < 0) */
-
- if (stv0299_wait_diseqc_fifo (i2c, 100) < 0)
+ if (stv0299_wait_diseqc_idle (i2c, 100) < 0)
return -ETIMEDOUT;
return 0;
@@ -375,18 +420,18 @@ int stv0299_send_diseqc_burst (struct dvb_i2c_bus *i2c, fe_sec_mini_cmd_t burst)
dprintk ("%s\n", __FUNCTION__);
- val = stv0299_readreg (i2c, 0x08);
-
- if (stv0299_wait_diseqc_fifo (i2c, 100) < 0)
+ if (stv0299_wait_diseqc_idle (i2c, 100) < 0)
return -ETIMEDOUT;
+ val = stv0299_readreg (i2c, 0x08);
+
if (stv0299_writereg (i2c, 0x08, (val & ~0x7) | 0x2)) /* burst mode */
return -EREMOTEIO;
if (stv0299_writereg (i2c, 0x09, burst == SEC_MINI_A ? 0x00 : 0xff))
return -EREMOTEIO;
- if (stv0299_wait_diseqc_fifo (i2c, 100) < 0)
+ if (stv0299_wait_diseqc_idle (i2c, 100) < 0)
return -ETIMEDOUT;
if (stv0299_writereg (i2c, 0x08, val))
@@ -403,6 +448,9 @@ int stv0299_set_tone (struct dvb_i2c_bus *i2c, fe_sec_tone_mode_t tone)
dprintk ("%s\n", __FUNCTION__);
+ if (stv0299_wait_diseqc_idle (i2c, 100) < 0)
+ return -ETIMEDOUT;
+
val = stv0299_readreg (i2c, 0x08);
switch (tone) {
@@ -445,8 +493,6 @@ int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate)
u32 tmp;
u8 aclk = 0xb4, bclk = 0x51;
- dprintk ("%s\n", __FUNCTION__);
-
if (srate > M_CLK)
srate = M_CLK;
if (srate < 500000)
@@ -479,7 +525,6 @@ int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate)
}
-
static
int stv0299_get_symbolrate (struct dvb_i2c_bus *i2c)
{
@@ -608,7 +653,7 @@ int bsru6_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
p->frequency += derot_freq;
p->inversion = (stv0299_readreg (i2c, 0x0c) & 1) ?
INVERSION_OFF : INVERSION_ON;
- p->u.qpsk.fec_inner = stv0299_get_FEC (i2c);
+ p->u.qpsk.fec_inner = stv0299_get_fec (i2c);
p->u.qpsk.symbol_rate = stv0299_get_symbolrate (i2c);
break;
}
@@ -694,7 +739,7 @@ module_exit (exit_bsru6);
MODULE_PARM(debug,"i");
MODULE_PARM_DESC(debug, "enable verbose debug messages");
-MODULE_DESCRIPTION("BSRU6 DVB Frontend driver");
+MODULE_DESCRIPTION("Alps BSRU6/LG TDQB-S00x DVB Frontend driver");
MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/alps_bsrv2.c b/drivers/media/dvb/frontends/alps_bsrv2.c
index 8da1f5bb5183..e0ecd0e2447b 100644
--- a/drivers/media/dvb/frontends/alps_bsrv2.c
+++ b/drivers/media/dvb/frontends/alps_bsrv2.c
@@ -342,7 +342,7 @@ int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
*ber = ves1893_readreg (i2c, 0x15);
*ber |= (ves1893_readreg (i2c, 0x16) << 8);
- *ber |= (ves1893_readreg (i2c, 0x17) << 16);
+ *ber |= ((ves1893_readreg (i2c, 0x17) & 0x0f) << 16);
*ber *= 10;
break;
}
diff --git a/drivers/media/dvb/frontends/alps_tdlb7.c b/drivers/media/dvb/frontends/alps_tdlb7.c
new file mode 100644
index 000000000000..d5700041eccd
--- /dev/null
+++ b/drivers/media/dvb/frontends/alps_tdlb7.c
@@ -0,0 +1,437 @@
+/*
+ Driver for Alps TDLB7 Frontend
+
+ Copyright (C) 1999 Juergen Peitz <peitz@snafu.de>
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+
+/*
+
+ Wrote this code mainly to get my own card running. It's working for me, but I
+ hope somebody who knows more about linux programming and the DVB driver can
+ improve it.
+
+ Reused a lot from the existing driver and tuner code.
+ Thanks to everybody who worked on it!
+
+ This driver needs a copy of the microcode file 'Sc_main.mc' from the Haupauge
+ windows driver in the 'usr/lib/DVB/driver/frontends' directory.
+ You can also pass the complete file name with the module parameter 'mcfile'.
+
+ The code only needs to be loaded once after a power on. Because loading the
+ microcode to the card takes some time, you can use the 'loadcode=0' module
+ parameter, if you only want to reload the dvb driver.
+
+ Juergen Peitz
+
+*/
+
+
+
+#define __KERNEL_SYSCALLS__
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/unistd.h>
+
+#include "compat.h"
+#include "dvb_frontend.h"
+
+static int debug = 0;
+
+static int loadcode = 1;
+
+static char * mcfile = "/usr/lib/DVB/driver/frontends/Sc_main.mc";
+
+#define dprintk if (debug) printk
+
+/* microcode size for sp8870 */
+#define SP8870_CODE_SIZE 16384
+
+/* starting point for microcode in file 'Sc_main.mc' */
+#define SP8870_CODE_OFFSET 0x0A
+
+
+static int errno;
+
+static
+struct dvb_frontend_info tdlb7_info = {
+ name: "Alps TDLB7",
+ type: FE_OFDM,
+ frequency_min: 470000000,
+ frequency_max: 860000000,
+ frequency_stepsize: 166666,
+#if 0
+ frequency_tolerance: ???,
+ symbol_rate_min: ???,
+ symbol_rate_max: ???,
+ symbol_rate_tolerance: ???,
+ notifier_delay: 0,
+#endif
+ caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64
+};
+
+
+static
+int sp8870_writereg (struct dvb_i2c_bus *i2c, u16 reg, u16 data)
+{
+ u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
+ struct i2c_msg msg = { addr: 0x71, flags: 0, buf: buf, len: 4 };
+ int err;
+
+ if ((err = i2c->xfer (i2c, &msg, 1)) != 1) {
+ dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+
+static
+u16 sp8870_readreg (struct dvb_i2c_bus *i2c, u16 reg)
+{
+ int ret;
+ u8 b0 [] = { reg >> 8 , reg & 0xff };
+ u8 b1 [] = { 0, 0 };
+ struct i2c_msg msg [] = { { addr: 0x71, flags: 0, buf: b0, len: 2 },
+ { addr: 0x71, flags: I2C_M_RD, buf: b1, len: 2 } };
+
+ ret = i2c->xfer (i2c, msg, 2);
+
+ if (ret != 2)
+ dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
+
+ return (b1[0] << 8 | b1[1]);
+}
+
+
+static
+int sp5659_write (struct dvb_i2c_bus *i2c, u8 data [4])
+{
+ int ret;
+ struct i2c_msg msg = { addr: 0x60, flags: 0, buf: data, len: 4 };
+
+ ret = i2c->xfer (i2c, &msg, 1);
+
+ if (ret != 1)
+ printk("%s: i/o error (ret == %i)\n", __FUNCTION__, ret);
+
+ return (ret != 1) ? -1 : 0;
+}
+
+
+static
+int sp5659_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, u8 pwr)
+{
+ u32 div = (freq + 36200000) / 166666;
+ u8 buf [4] = { (div >> 8) & 0x7f, div & 0xff, 0x85, (pwr << 5) | 0x30 };
+
+ return sp5659_write (i2c, buf);
+}
+
+
+static
+int sp8870_read_code(const char *fn, char **fp)
+{
+ int fd;
+ loff_t l;
+ char *dp;
+
+ fd = open(fn, 0, 0);
+ if (fd == -1) {
+ printk(KERN_INFO "%s: Unable to load '%s'.\n", __FUNCTION__, fn);
+ return -1;
+ }
+ l = lseek(fd, 0L, 2);
+ if (l <= 0 || l < SP8870_CODE_OFFSET+SP8870_CODE_SIZE) {
+ printk(KERN_INFO "%s: code file too small '%s'\n", __FUNCTION__, fn);
+ sys_close(fd);
+ return -1;
+ }
+ lseek(fd, SP8870_CODE_OFFSET, 0);
+ *fp= dp = vmalloc(SP8870_CODE_SIZE);
+ if (dp == NULL) {
+ printk(KERN_INFO "%s: Out of memory loading '%s'.\n", __FUNCTION__, fn);
+ sys_close(fd);
+ return -1;
+ }
+ if (read(fd, dp, SP8870_CODE_SIZE) != SP8870_CODE_SIZE) {
+ printk(KERN_INFO "%s: Failed to read '%s'.\n",__FUNCTION__, fn);
+ vfree(dp);
+ sys_close(fd);
+ return -1;
+ }
+ sys_close(fd);
+ *fp = dp;
+ return 0;
+}
+
+
+static
+int sp8870_load_code(struct dvb_i2c_bus *i2c)
+{
+ /* this takes a long time. is there a way to do it faster? */
+ char *lcode;
+ struct i2c_msg msg;
+ unsigned char buf[255];
+ int err;
+ int p=0;
+ int c;
+ mm_segment_t fs = get_fs();
+
+ sp8870_writereg(i2c,0x8F08,0x1FFF);
+ sp8870_writereg(i2c,0x8F0A,0x0000);
+
+ set_fs(get_ds());
+ if (sp8870_read_code(mcfile,(char**) &lcode)<0) return -1;
+ set_fs(fs);
+ while (p<SP8870_CODE_SIZE){
+ c = (p<=SP8870_CODE_SIZE-252) ? 252 : SP8870_CODE_SIZE-p;
+ buf[0]=0xCF;
+ buf[1]=0x0A;
+ memcpy(&buf[2],lcode+p,c);
+ c+=2;
+ msg.addr=0x71;
+ msg.flags=0;
+ msg.buf=buf;
+ msg.len=c;
+ if ((err = i2c->xfer (i2c, &msg, 1)) != 1) {
+ dprintk ("%s: i2c error (err == %i)\n", __FUNCTION__, err);
+ vfree(lcode);
+ return -EREMOTEIO;
+ }
+
+ p+=252;
+ }
+ vfree(lcode);
+ return 0;
+};
+
+
+static
+int sp8870_init (struct dvb_i2c_bus *i2c)
+{
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ sp8870_readreg(i2c,0x200);
+ sp8870_readreg(i2c,0x200);
+ sp8870_readreg(i2c,0x0F00); /* system controller stop */
+ sp8870_readreg(i2c,0x0301); /* ???????? */
+ sp8870_readreg(i2c,0x0309); /* integer carrier offset */
+ sp8870_readreg(i2c,0x030A); /* fractional carrier offset */
+ sp8870_readreg(i2c,0x0311); /* filter for 8 Mhz channel */
+ sp8870_readreg(i2c,0x0319); /* sample rate correction bit [23..17] */
+ sp8870_readreg(i2c,0x031A); /* sample rate correction bit [16..0] */
+ sp8870_readreg(i2c,0x0338); /* ???????? */
+ sp8870_readreg(i2c,0x0F00);
+ sp8870_readreg(i2c,0x0200);
+
+ if (loadcode) {
+ dprintk("%s: loading mcfile '%s' !\n", __FUNCTION__, mcfile);
+ if (sp8870_load_code(i2c)==0)
+ dprintk("%s: microcode loaded!\n", __FUNCTION__);
+ }else{
+ dprintk("%s: without loading mcfile!\n", __FUNCTION__);
+ }
+
+ return 0;
+}
+
+
+static
+int sp8870_reset (struct dvb_i2c_bus *i2c)
+{
+ dprintk("%s\n", __FUNCTION__);
+ sp8870_writereg(i2c,0x0F00,0x0000); /* system controller stop */
+ sp8870_writereg(i2c,0x0301,0x0003); /* ???????? */
+ sp8870_writereg(i2c,0x0309,0x0400); /* integer carrier offset */
+ sp8870_writereg(i2c,0x030A,0x0000); /* fractional carrier offset */
+ sp8870_writereg(i2c,0x0311,0x0000); /* filter for 8 Mhz channel */
+ sp8870_writereg(i2c,0x0319,0x000A); /* sample rate correction bit [23..17] */
+ sp8870_writereg(i2c,0x031A,0x0AAB); /* sample rate correction bit [16..0] */
+ sp8870_writereg(i2c,0x0338,0x0000); /* ???????? */
+ sp8870_writereg(i2c,0x0201,0x0000); /* interrupts for change of lock or tuner adjustment disabled */
+ sp8870_writereg(i2c,0x0F00,0x0001); /* system controller start */
+
+ return 0;
+}
+
+static
+int tdlb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
+{
+ struct dvb_i2c_bus *i2c = fe->i2c;
+
+ switch (cmd) {
+ case FE_GET_INFO:
+ memcpy (arg, &tdlb7_info, sizeof(struct dvb_frontend_info));
+ break;
+
+ case FE_READ_STATUS:
+ {
+ fe_status_t *status = arg;
+ int sync = sp8870_readreg (i2c, 0x0200);
+
+ *status=0;
+
+ if (sync&0x04) // FIXME: find criteria for having signal
+ *status |= FE_HAS_SIGNAL;
+
+ if (sync&0x04) // FIXME: find criteria
+ *status |= FE_HAS_CARRIER;
+
+ if (sync&0x04) // FIXME
+ *status |= FE_HAS_VITERBI;
+
+ if (sync&0x08) // FIXME
+ *status |= FE_HAS_SYNC;
+
+ if (sync&0x04)
+ *status |= FE_HAS_LOCK;
+ break;
+
+ }
+
+ case FE_READ_BER:
+ {
+ u32 *ber=(u32 *) arg;
+ *ber=sp8870_readreg(i2c,0x0C07); // bit error rate before Viterbi
+ break;
+
+ }
+
+ case FE_READ_SIGNAL_STRENGTH: // not supported by hardware?
+ {
+ s32 *signal=(s32 *) arg;
+ *signal=0;
+ break;
+ }
+
+ case FE_READ_SNR: // not supported by hardware?
+ {
+ s32 *snr=(s32 *) arg;
+ *snr=0;
+ break;
+ }
+
+ case FE_READ_UNCORRECTED_BLOCKS: // not supported by hardware?
+ {
+ u32 *ublocks=(u32 *) arg;
+ *ublocks=0;
+ break;
+ }
+
+ case FE_SET_FRONTEND:
+ {
+ struct dvb_frontend_parameters *p = arg;
+ sp5659_set_tv_freq (i2c, p->frequency, 0);
+ // all other parameters are set by the on card
+ // system controller. Don't know how to pass
+ // distinct values to the card.
+ break;
+ }
+
+ case FE_GET_FRONTEND: // how to do this?
+ {
+ break;
+ }
+
+ case FE_SLEEP: // is this supported by hardware?
+ return -EOPNOTSUPP;
+
+ case FE_INIT:
+ return sp8870_init (i2c);
+
+ case FE_RESET:
+ return sp8870_reset (i2c);
+
+ default:
+ return -EOPNOTSUPP;
+ };
+
+ return 0;
+}
+
+
+static
+int tdlb7_attach (struct dvb_i2c_bus *i2c)
+{
+
+ struct i2c_msg msg = { addr: 0x71, flags: 0, buf: NULL, len: 0 };
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ if (i2c->xfer (i2c, &msg, 1) != 1)
+ return -ENODEV;
+
+ dvb_register_frontend (tdlb7_ioctl, i2c, NULL, &tdlb7_info);
+
+ return 0;
+}
+
+
+static
+void tdlb7_detach (struct dvb_i2c_bus *i2c)
+{
+ dprintk ("%s\n", __FUNCTION__);
+
+ dvb_unregister_frontend (tdlb7_ioctl, i2c);
+}
+
+
+static
+int __init init_tdlb7 (void)
+{
+ dprintk ("%s\n", __FUNCTION__);
+
+ return dvb_register_i2c_device (THIS_MODULE, tdlb7_attach, tdlb7_detach);
+}
+
+
+static
+void __exit exit_tdlb7 (void)
+{
+ dprintk ("%s\n", __FUNCTION__);
+
+ dvb_unregister_i2c_device (tdlb7_attach);
+}
+
+
+module_init(init_tdlb7);
+module_exit(exit_tdlb7);
+
+
+MODULE_PARM(debug,"i");
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+
+MODULE_PARM(loadcode,"i");
+MODULE_PARM_DESC(loadcode, "load tuner microcode");
+
+MODULE_PARM(mcfile,"s");
+MODULE_PARM_DESC(mcfile, "where to find the microcode file");
+
+MODULE_DESCRIPTION("TDLB7 DVB-T Frontend");
+MODULE_AUTHOR("Juergen Peitz");
+MODULE_LICENSE("GPL");
+
+
diff --git a/drivers/media/dvb/frontends/alps_tdmb7.c b/drivers/media/dvb/frontends/alps_tdmb7.c
new file mode 100644
index 000000000000..ddc5e818666b
--- /dev/null
+++ b/drivers/media/dvb/frontends/alps_tdmb7.c
@@ -0,0 +1,468 @@
+/*
+ Alps TDMB7 DVB OFDM frontend driver
+
+ Copyright (C) 2001-2002 Convergence Integrated Media GmbH
+ Holger Waechtler <holger@convergence.de>
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include "compat.h"
+#include "dvb_frontend.h"
+
+
+static int debug = 0;
+#define dprintk if (debug) printk
+
+
+static
+struct dvb_frontend_info tdmb7_info = {
+ name: "Alps TDMB7",
+ type: FE_OFDM,
+ frequency_min: 470000000,
+ frequency_max: 860000000,
+ frequency_stepsize: 166667,
+#if 0
+ frequency_tolerance: ???,
+ symbol_rate_min: ???,
+ symbol_rate_max: ???,
+ symbol_rate_tolerance: 500, /* ppm */
+ notifier_delay: 0,
+#endif
+ caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64
+};
+
+
+static
+inline void ddelay (int timeout)
+{
+ current->state=TASK_INTERRUPTIBLE;
+ schedule_timeout(timeout);
+}
+
+
+static
+u8 init_tab [] = {
+ 0x04, 0x10,
+ 0x05, 0x09,
+ 0x06, 0x00,
+ 0x08, 0x04,
+ 0x09, 0x00,
+ 0x0a, 0x01,
+ 0x15, 0x40,
+ 0x16, 0x10,
+ 0x17, 0x87,
+ 0x18, 0x17,
+ 0x1a, 0x10,
+ 0x25, 0x04,
+ 0x2e, 0x00,
+ 0x39, 0x00,
+ 0x3a, 0x04,
+ 0x45, 0x08,
+ 0x46, 0x02,
+ 0x47, 0x05,
+};
+
+
+static
+int cx22700_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data)
+{
+ int ret;
+ u8 buf [] = { reg, data };
+ struct i2c_msg msg = { addr: 0x43, flags: 0, buf: buf, len: 2 };
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ ret = i2c->xfer (i2c, &msg, 1);
+
+ if (ret != 1)
+ printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
+ __FUNCTION__, reg, data, ret);
+
+ return (ret != 1) ? -1 : 0;
+}
+
+
+static
+u8 cx22700_readreg (struct dvb_i2c_bus *i2c, u8 reg)
+{
+ int ret;
+ u8 b0 [] = { reg };
+ u8 b1 [] = { 0 };
+ struct i2c_msg msg [] = { { addr: 0x43, flags: 0, buf: b0, len: 1 },
+ { addr: 0x43, flags: I2C_M_RD, buf: b1, len: 1 } };
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ ret = i2c->xfer (i2c, msg, 2);
+
+ if (ret != 2)
+ printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
+
+ return b1[0];
+}
+
+
+static
+int pll_write (struct dvb_i2c_bus *i2c, u8 data [4])
+{
+ struct i2c_msg msg = { addr: 0x61, flags: 0, buf: data, len: 4 };
+ int ret;
+
+ cx22700_writereg (i2c, 0x0a, 0x00); /* open i2c bus switch */
+ ret = i2c->xfer (i2c, &msg, 1);
+ cx22700_writereg (i2c, 0x0a, 0x01); /* close i2c bus switch */
+
+ if (ret != 1)
+ printk("%s: i/o error (addr == 0x%02x, ret == %i)\n", __FUNCTION__, msg.addr, ret);
+
+ return (ret != 1) ? -1 : 0;
+}
+
+
+/**
+ * set up the downconverter frequency divisor for a
+ * reference clock comparision frequency of 125 kHz.
+ */
+static
+int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq)
+{
+ u32 div = (freq + 36166667) / 166667;
+#if 1 //ALPS_SETTINGS
+ u8 buf [4] = { (div >> 8) & 0x7f, div & 0xff, ((div >> 10) & 0x60) | 0x85,
+ freq < 592000000 ? 0x40 : 0x80 };
+#else
+ u8 buf [4] = { (div >> 8) & 0x7f, div & 0xff, ((div >> 10) & 0x60) | 0x85,
+ freq < 470000000 ? 0x42 : freq < 862000000 ? 0x41 : 0x81 };
+#endif
+
+ dprintk ("%s: freq == %i, div == %i\n", __FUNCTION__, freq, div);
+
+ return pll_write (i2c, buf);
+}
+
+
+static
+int cx22700_init (struct dvb_i2c_bus *i2c)
+{
+ int i;
+
+ dprintk("cx22700_init: init chip\n");
+
+ cx22700_writereg (i2c, 0x00, 0x02); /* soft reset */
+ cx22700_writereg (i2c, 0x00, 0x00);
+
+ ddelay (HZ/100);
+
+ for (i=0; i<sizeof(init_tab); i+=2)
+ cx22700_writereg (i2c, init_tab[i], init_tab[i+1]);
+
+ cx22700_writereg (i2c, 0x00, 0x01);
+
+ return 0;
+}
+
+
+static
+int cx22700_set_inversion (struct dvb_i2c_bus *i2c, int inversion)
+{
+ u8 val;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ switch (inversion) {
+ case INVERSION_AUTO:
+ return -EOPNOTSUPP;
+ case INVERSION_ON:
+ val = cx22700_readreg (i2c, 0x09);
+ return cx22700_writereg (i2c, 0x09, val | 0x01);
+ case INVERSION_OFF:
+ val = cx22700_readreg (i2c, 0x09);
+ return cx22700_writereg (i2c, 0x09, val & 0xfe);
+ default:
+ return -EINVAL;
+ }
+}
+
+
+static
+int cx22700_set_tps (struct dvb_i2c_bus *i2c, struct dvb_ofdm_parameters *p)
+{
+ static const u8 qam_tab [4] = { 0, 1, 0, 2 };
+ static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 };
+ u8 val;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ if (p->code_rate_HP < FEC_1_2 || p->code_rate_HP > FEC_7_8)
+ return -EINVAL;
+
+ if (p->code_rate_LP < FEC_1_2 || p->code_rate_LP > FEC_7_8)
+
+ if (p->code_rate_HP == FEC_4_5 || p->code_rate_LP == FEC_4_5)
+ return -EINVAL;
+
+ if (p->guard_interval < GUARD_INTERVAL_1_32 ||
+ p->guard_interval > GUARD_INTERVAL_1_4)
+ return -EINVAL;
+
+ if (p->transmission_mode != TRANSMISSION_MODE_2K &&
+ p->transmission_mode != TRANSMISSION_MODE_8K)
+ return -EINVAL;
+
+ if (p->constellation != QPSK &&
+ p->constellation != QAM_16 &&
+ p->constellation != QAM_64)
+ return -EINVAL;
+
+ if (p->hierarchy_information < HIERARCHY_NONE ||
+ p->hierarchy_information > HIERARCHY_4)
+ return -EINVAL;
+
+ if (p->bandwidth < BANDWIDTH_8_MHZ && p->bandwidth > BANDWIDTH_6_MHZ)
+ return -EINVAL;
+
+ if (p->bandwidth == BANDWIDTH_7_MHZ)
+ cx22700_writereg (i2c, 0x09, cx22700_readreg (i2c, 0x09 | 0x10));
+ else
+ cx22700_writereg (i2c, 0x09, cx22700_readreg (i2c, 0x09 & ~0x10));
+
+ val = qam_tab[p->constellation - QPSK];
+ val |= p->hierarchy_information - HIERARCHY_NONE;
+
+ cx22700_writereg (i2c, 0x04, val);
+
+ val = fec_tab[p->code_rate_HP - FEC_1_2] << 3;
+ val |= fec_tab[p->code_rate_LP - FEC_1_2];
+
+ cx22700_writereg (i2c, 0x05, val);
+
+ val = (p->guard_interval - GUARD_INTERVAL_1_32) << 2;
+ val |= p->transmission_mode - TRANSMISSION_MODE_2K;
+
+ cx22700_writereg (i2c, 0x06, val);
+
+ cx22700_writereg (i2c, 0x08, 0x04 | 0x02); /* use user tps parameters */
+ cx22700_writereg (i2c, 0x08, 0x04); /* restart aquisition */
+
+ return 0;
+}
+
+
+static
+int cx22700_get_tps (struct dvb_i2c_bus *i2c, struct dvb_ofdm_parameters *p)
+{
+ static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 };
+ static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4,
+ FEC_5_6, FEC_7_8 };
+ u8 val;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ if (!(cx22700_readreg(i2c, 0x07) & 0x20)) /* tps valid? */
+ return -EAGAIN;
+
+ val = cx22700_readreg (i2c, 0x01);
+
+ if ((val & 0x7) > 4)
+ p->hierarchy_information = HIERARCHY_AUTO;
+ else
+ p->hierarchy_information = HIERARCHY_NONE + (val & 0x7);
+
+ if (((val >> 3) & 0x3) > 2)
+ p->constellation = QAM_AUTO;
+ else
+ p->constellation = qam_tab[(val >> 3) & 0x3];
+
+
+ val = cx22700_readreg (i2c, 0x02);
+
+ if ((val >> 3) > 4)
+ p->code_rate_HP = FEC_AUTO;
+ else
+ p->code_rate_HP = fec_tab[val >> 3];
+
+ if ((val & 0x7) > 4)
+ p->code_rate_LP = FEC_AUTO;
+ else
+ p->code_rate_LP = fec_tab[val >> 3];
+
+
+ val = cx22700_readreg (i2c, 0x03);
+
+ p->guard_interval = GUARD_INTERVAL_1_32 + ((val >> 6) & 0x3);
+ p->transmission_mode = TRANSMISSION_MODE_2K + ((val >> 5) & 0x1);
+
+ return 0;
+}
+
+
+static
+int tdmb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
+{
+ struct dvb_i2c_bus *i2c = fe->i2c;
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ switch (cmd) {
+ case FE_GET_INFO:
+ memcpy (arg, &tdmb7_info, sizeof(struct dvb_frontend_info));
+ break;
+
+ case FE_READ_STATUS:
+ {
+ fe_status_t *status = (fe_status_t *) arg;
+ u16 rs_ber = (cx22700_readreg (i2c, 0x0d) << 9)
+ | (cx22700_readreg (i2c, 0x0e) << 1);
+ u8 sync = cx22700_readreg (i2c, 0x07);
+
+ *status = 0;
+
+ if (rs_ber < 0xff00)
+ *status |= FE_HAS_SIGNAL;
+
+ if (sync & 0x20)
+ *status |= FE_HAS_CARRIER;
+
+ if (sync & 0x10)
+ *status |= FE_HAS_VITERBI;
+
+ if (sync & 0x10)
+ *status |= FE_HAS_SYNC;
+
+ if (sync & 0x10)
+ *status |= FE_HAS_LOCK;
+
+ break;
+ }
+
+ case FE_READ_BER:
+ *((uint32_t*) arg) = cx22700_readreg (i2c, 0x0c) & 0x7f;
+ break;
+
+ case FE_READ_SIGNAL_STRENGTH:
+ {
+ u16 rs_ber = (cx22700_readreg (i2c, 0x0d) << 9)
+ | (cx22700_readreg (i2c, 0x0e) << 1);
+ *((uint16_t*) arg) = ~rs_ber;
+ break;
+ }
+ case FE_READ_SNR:
+ {
+ u16 rs_ber = (cx22700_readreg (i2c, 0x0d) << 9)
+ | (cx22700_readreg (i2c, 0x0e) << 1);
+ *((uint16_t*) arg) = ~rs_ber;
+ break;
+ }
+ case FE_READ_UNCORRECTED_BLOCKS:
+ *((uint32_t*) arg) = cx22700_readreg (i2c, 0x0f);
+ break;
+
+ case FE_SET_FRONTEND:
+ {
+ struct dvb_frontend_parameters *p = arg;
+
+ cx22700_writereg (i2c, 0x00, 0x02); /* XXX CHECKME: soft reset*/
+ cx22700_writereg (i2c, 0x00, 0x00);
+
+ pll_set_tv_freq (i2c, p->frequency);
+ cx22700_set_inversion (i2c, p->inversion);
+ cx22700_set_tps (i2c, &p->u.ofdm);
+ cx22700_writereg (i2c, 0x37, 0x01); /* PAL loop filter off */
+ cx22700_writereg (i2c, 0x00, 0x01); /* restart aquire */
+ break;
+ }
+
+ case FE_GET_FRONTEND:
+ {
+ struct dvb_frontend_parameters *p = arg;
+ u8 reg09 = cx22700_readreg (i2c, 0x09);
+
+ p->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF;
+ return cx22700_get_tps (i2c, &p->u.ofdm);
+ }
+
+ case FE_INIT:
+ return cx22700_init (i2c);
+
+ case FE_RESET:
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ };
+
+ return 0;
+}
+
+
+
+static
+int tdmb7_attach (struct dvb_i2c_bus *i2c)
+{
+ struct i2c_msg msg = { addr: 0x43, flags: 0, buf: NULL, len: 0 };
+
+ dprintk ("%s\n", __FUNCTION__);
+
+ if (i2c->xfer (i2c, &msg, 1) != 1)
+ return -ENODEV;
+
+ dvb_register_frontend (tdmb7_ioctl, i2c, NULL, &tdmb7_info);
+
+ return 0;
+}
+
+
+static
+void tdmb7_detach (struct dvb_i2c_bus *i2c)
+{
+ dprintk ("%s\n", __FUNCTION__);
+
+ dvb_unregister_frontend (tdmb7_ioctl, i2c);
+}
+
+
+static
+int __init init_tdmb7 (void)
+{
+ dprintk ("%s\n", __FUNCTION__);
+
+ return dvb_register_i2c_device (THIS_MODULE, tdmb7_attach, tdmb7_detach);
+}
+
+
+static
+void __exit exit_tdmb7 (void)
+{
+ dprintk ("%s\n", __FUNCTION__);
+
+ dvb_unregister_i2c_device (tdmb7_attach);
+}
+
+module_init (init_tdmb7);
+module_exit (exit_tdmb7);
+
+MODULE_PARM(debug,"i");
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+MODULE_DESCRIPTION("TDMB7 DVB Frontend driver");
+MODULE_AUTHOR("Holger Waechtler");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
index fe2c4e20d5dd..30b06900102c 100644
--- a/drivers/media/dvb/frontends/ves1820.c
+++ b/drivers/media/dvb/frontends/ves1820.c
@@ -199,8 +199,8 @@ int ves1820_init (struct dvb_frontend *frontend)
u8 b0 [] = { 0xff };
u8 pwm;
int i;
- struct i2c_msg msg [] = { { addr: 0x28, flags: 0, buf: b0, len: 1 },
- { addr: 0x28, flags: I2C_M_RD, buf: &pwm, len: 1 } };
+ struct i2c_msg msg [] = { { addr: 0x50, flags: 0, buf: b0, len: 1 },
+ { addr: 0x50, flags: I2C_M_RD, buf: &pwm, len: 1 } };
dprintk("VES1820: init chip\n");
@@ -433,12 +433,13 @@ int ves1820_ioctl (struct dvb_frontend *frontend, unsigned int cmd, void *arg)
}
case FE_READ_BER:
- *((u32*) arg) = ves1820_readreg(frontend->i2c, 0x14) |
+ {
+ u32 ber = ves1820_readreg(frontend->i2c, 0x14) |
(ves1820_readreg(frontend->i2c, 0x15) << 8) |
- (ves1820_readreg(frontend->i2c, 0x16) << 16);
- /* XXX FIXME: scale!!*/
+ ((ves1820_readreg(frontend->i2c, 0x16) & 0x0f) << 16);
+ *((u32*) arg) = 10 * ber;
break;
-
+ }
case FE_READ_SIGNAL_STRENGTH:
{
u8 gain = ves1820_readreg(frontend->i2c, 0x17);
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index fbbf3ad7cdc9..77397b9eced0 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -2990,7 +2990,7 @@ void __devinit bttv_check_chipset(void)
/* print which chipset we have */
while ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8,dev)))
- printk(KERN_INFO "bttv: Host bridge is %s\n",dev->name);
+ printk(KERN_INFO "bttv: Host bridge is %s\n",dev->dev.name);
/* print warnings about any quirks found */
if (triton1)
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c
index 86f538f760c6..cd7d547d34fa 100644
--- a/drivers/media/video/saa7111.c
+++ b/drivers/media/video/saa7111.c
@@ -34,7 +34,7 @@
#include <linux/videodev.h>
#include <linux/version.h>
-#include <linux/i2c-old.h>
+#include <linux/i2c.h>
#include <linux/video_decoder.h>
@@ -43,8 +43,9 @@
/* ----------------------------------------------------------------------- */
struct saa7111 {
- struct i2c_bus *bus;
+ struct i2c_client *client;
int addr;
+ struct semaphore lock;
unsigned char reg[32];
int norm;
@@ -60,74 +61,32 @@ struct saa7111 {
#define I2C_DELAY 10
-/* ----------------------------------------------------------------------- */
-
-static int saa7111_write(struct saa7111 *dev, unsigned char subaddr,
- unsigned char data)
-{
- int ack;
-
- LOCK_I2C_BUS(dev->bus);
- i2c_start(dev->bus);
- i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
- i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
- ack = i2c_sendbyte(dev->bus, data, I2C_DELAY);
- dev->reg[subaddr] = data;
- i2c_stop(dev->bus);
- UNLOCK_I2C_BUS(dev->bus);
- return ack;
-}
-
-static int saa7111_write_block(struct saa7111 *dev,
- unsigned const char *data, unsigned int len)
-{
- int ack = -1;
- unsigned subaddr;
-
- while (len > 1) {
- LOCK_I2C_BUS(dev->bus);
- i2c_start(dev->bus);
- i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
- ack = i2c_sendbyte(dev->bus, (subaddr = *data++), I2C_DELAY);
- ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
- len -= 2;
- while (len > 1 && *data == ++subaddr) {
- data++;
- ack =
- i2c_sendbyte(dev->bus,
- (dev->reg[subaddr] =
- *data++), I2C_DELAY);
- len -= 2;
- }
- i2c_stop(dev->bus);
- UNLOCK_I2C_BUS(dev->bus);
- }
- return ack;
-}
-
-static int saa7111_read(struct saa7111 *dev, unsigned char subaddr)
-{
- int data;
-
- LOCK_I2C_BUS(dev->bus);
- i2c_start(dev->bus);
- i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
- i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
- i2c_start(dev->bus);
- i2c_sendbyte(dev->bus, dev->addr | 1, I2C_DELAY);
- data = i2c_readbyte(dev->bus, 1);
- i2c_stop(dev->bus);
- UNLOCK_I2C_BUS(dev->bus);
- return data;
-}
+static unsigned short normal_i2c[] = { 34>>1, I2C_CLIENT_END };
+static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
+static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
+static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
+static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
+static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
+static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
+
+static struct i2c_client_address_data addr_data = {
+ .normal_i2c = normal_i2c,
+ .normal_i2c_range = normal_i2c_range,
+ .probe = probe,
+ .probe_range = probe_range,
+ .ignore = ignore,
+ .ignore_range = ignore_range,
+ .force = force
+};
+static struct i2c_client client_template;
/* ----------------------------------------------------------------------- */
-static int saa7111_attach(struct i2c_device *device)
+static int saa7111_attach(struct i2c_adapter *adap, int addr, unsigned short flags, int kind)
{
int i;
struct saa7111 *decoder;
-
+ struct i2c_client *client;
static const unsigned char init[] = {
0x00, 0x00, /* 00 - ID byte */
0x01, 0x00, /* 01 - reserved */
@@ -158,20 +117,25 @@ static int saa7111_attach(struct i2c_device *device)
0x16, 0x00, /* 16 - VBI */
0x17, 0x00, /* 17 - VBI */
};
+ client = kmalloc(sizeof(*client), GFP_KERNEL);
+ if(client == NULL)
+ return -ENOMEM;
+ client_template.adapter = adap;
+ client_template.addr = addr;
+ memcpy(client, &client_template, sizeof(*client));
- MOD_INC_USE_COUNT;
-
- device->data = decoder = kmalloc(sizeof(struct saa7111), GFP_KERNEL);
+ decoder = kmalloc(sizeof(*decoder), GFP_KERNEL);
if (decoder == NULL)
{
- MOD_DEC_USE_COUNT;
+ kfree(client);
return -ENOMEM;
}
- memset(decoder, 0, sizeof(struct saa7111));
- strcpy(device->name, "saa7111");
- decoder->bus = device->bus;
- decoder->addr = device->addr;
+ memset(decoder, 0, sizeof(*decoder));
+ strcpy(client->name, "saa7111");
+ decoder->client = client;
+ client->data = decoder;
+ decoder->addr = addr;
decoder->norm = VIDEO_MODE_NTSC;
decoder->input = 0;
decoder->enable = 1;
@@ -180,29 +144,38 @@ static int saa7111_attach(struct i2c_device *device)
decoder->hue = 32768;
decoder->sat = 32768;
- i = saa7111_write_block(decoder, init, sizeof(init));
+ i = i2c_master_send(client, init, sizeof(init));
if (i < 0) {
printk(KERN_ERR "%s_attach: init status %d\n",
- device->name, i);
+ client->name, i);
} else {
printk(KERN_INFO "%s_attach: chip version %x\n",
- device->name, saa7111_read(decoder, 0x00) >> 4);
+ client->name, i2c_smbus_read_byte_data(client, 0x00) >> 4);
}
+ init_MUTEX(&decoder->lock);
+ i2c_attach_client(client);
+ MOD_INC_USE_COUNT;
return 0;
}
+static int saa7111_probe(struct i2c_adapter *adap)
+{
+ return i2c_probe(adap, &addr_data, saa7111_attach);
+}
-
-static int saa7111_detach(struct i2c_device *device)
+static int saa7111_detach(struct i2c_client *client)
{
- kfree(device->data);
+ struct saa7111 *decoder = client->data;
+ i2c_detach_client(client);
+ kfree(decoder);
+ kfree(client);
MOD_DEC_USE_COUNT;
return 0;
}
-static int saa7111_command(struct i2c_device *device, unsigned int cmd,
+static int saa7111_command(struct i2c_client *client, unsigned int cmd,
void *arg)
{
- struct saa7111 *decoder = device->data;
+ struct saa7111 *decoder = client->data;
switch (cmd) {
@@ -214,11 +187,11 @@ static int saa7111_command(struct i2c_device *device, unsigned int cmd,
for (i = 0; i < 32; i += 16) {
int j;
- printk("KERN_DEBUG %s: %03x", device->name,
+ printk("KERN_DEBUG %s: %03x", client->name,
i);
for (j = 0; j < 16; ++j) {
printk(" %02x",
- saa7111_read(decoder,
+ i2c_smbus_read_byte_data(client,
i + j));
}
printk("\n");
@@ -246,7 +219,7 @@ static int saa7111_command(struct i2c_device *device, unsigned int cmd,
int status;
int res;
- status = saa7111_read(decoder, 0x1f);
+ status = i2c_smbus_read_byte_data(client, 0x1f);
res = 0;
if ((status & (1 << 6)) == 0) {
res |= DECODER_STATUS_GOOD;
@@ -281,19 +254,19 @@ static int saa7111_command(struct i2c_device *device, unsigned int cmd,
switch (*iarg) {
case VIDEO_MODE_NTSC:
- saa7111_write(decoder, 0x08,
+ i2c_smbus_write_byte_data(client, 0x08,
(decoder->
reg[0x08] & 0x3f) | 0x40);
break;
case VIDEO_MODE_PAL:
- saa7111_write(decoder, 0x08,
+ i2c_smbus_write_byte_data(client, 0x08,
(decoder->
reg[0x08] & 0x3f) | 0x00);
break;
case VIDEO_MODE_AUTO:
- saa7111_write(decoder, 0x08,
+ i2c_smbus_write_byte_data(client, 0x08,
(decoder->
reg[0x08] & 0x3f) | 0x80);
break;
@@ -317,12 +290,12 @@ static int saa7111_command(struct i2c_device *device, unsigned int cmd,
if (decoder->input != *iarg) {
decoder->input = *iarg;
/* select mode */
- saa7111_write(decoder, 0x02,
+ i2c_smbus_write_byte_data(client, 0x02,
(decoder->
reg[0x02] & 0xf8) |
decoder->input);
/* bypass chrominance trap for modes 4..7 */
- saa7111_write(decoder, 0x09,
+ i2c_smbus_write_byte_data(client, 0x09,
(decoder->
reg[0x09] & 0x7f) |
((decoder->input >
@@ -357,26 +330,26 @@ static int saa7111_command(struct i2c_device *device, unsigned int cmd,
// If output should be enabled, we have to reverse the above.
if (decoder->enable) {
- saa7111_write(decoder, 0x02,
+ i2c_smbus_write_byte_data(client, 0x02,
(decoder->
reg[0x02] & 0xf8) |
decoder->input);
- saa7111_write(decoder, 0x08,
+ i2c_smbus_write_byte_data(client, 0x08,
(decoder->
reg[0x08] & 0xfb));
- saa7111_write(decoder, 0x11,
+ i2c_smbus_write_byte_data(client, 0x11,
(decoder->
reg[0x11] & 0xf3) |
0x0c);
} else {
- saa7111_write(decoder, 0x02,
+ i2c_smbus_write_byte_data(client, 0x02,
(decoder->
reg[0x02] & 0xf8));
- saa7111_write(decoder, 0x08,
+ i2c_smbus_write_byte_data(client, 0x08,
(decoder->
reg[0x08] & 0xfb) |
0x04);
- saa7111_write(decoder, 0x11,
+ i2c_smbus_write_byte_data(client, 0x11,
(decoder->
reg[0x11] & 0xf3));
}
@@ -391,25 +364,25 @@ static int saa7111_command(struct i2c_device *device, unsigned int cmd,
if (decoder->bright != pic->brightness) {
/* We want 0 to 255 we get 0-65535 */
decoder->bright = pic->brightness;
- saa7111_write(decoder, 0x0a,
+ i2c_smbus_write_byte_data(client, 0x0a,
decoder->bright >> 8);
}
if (decoder->contrast != pic->contrast) {
/* We want 0 to 127 we get 0-65535 */
decoder->contrast = pic->contrast;
- saa7111_write(decoder, 0x0b,
+ i2c_smbus_write_byte_data(client, 0x0b,
decoder->contrast >> 9);
}
if (decoder->sat != pic->colour) {
/* We want 0 to 127 we get 0-65535 */
decoder->sat = pic->colour;
- saa7111_write(decoder, 0x0c,
+ i2c_smbus_write_byte_data(client, 0x0c,
decoder->sat >> 9);
}
if (decoder->hue != pic->hue) {
/* We want -128 to 127 we get 0-65535 */
decoder->hue = pic->hue;
- saa7111_write(decoder, 0x0d,
+ i2c_smbus_write_byte_data(client, 0x0d,
(decoder->hue - 32768) >> 8);
}
}
@@ -425,23 +398,28 @@ static int saa7111_command(struct i2c_device *device, unsigned int cmd,
/* ----------------------------------------------------------------------- */
static struct i2c_driver i2c_driver_saa7111 = {
- "saa7111", /* name */
- I2C_DRIVERID_VIDEODECODER, /* ID */
- I2C_SAA7111, I2C_SAA7111 + 1,
+ .name = "saa7111", /* name */
+ .id = I2C_DRIVERID_SAA7111A, /* ID */
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = saa7111_probe,
+ .detach_client = saa7111_detach,
+ .command = saa7111_command
+};
- saa7111_attach,
- saa7111_detach,
- saa7111_command
+static struct i2c_client client_template = {
+ .name = "saa7111_client",
+ .id = -1,
+ .driver = &i2c_driver_saa7111
};
static int saa7111_init(void)
{
- return i2c_register_driver(&i2c_driver_saa7111);
+ return i2c_add_driver(&i2c_driver_saa7111);
}
static void saa7111_exit(void)
{
- i2c_unregister_driver(&i2c_driver_saa7111);
+ i2c_del_driver(&i2c_driver_saa7111);
}
module_init(saa7111_init);
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
index 609ca91fd083..9db597c23dae 100644
--- a/drivers/media/video/saa7185.c
+++ b/drivers/media/video/saa7185.c
@@ -43,7 +43,7 @@
#include <linux/version.h>
#include <asm/uaccess.h>
-#include <linux/i2c-old.h>
+#include <linux/i2c.h>
#include <linux/video_encoder.h>
@@ -52,9 +52,10 @@
/* ----------------------------------------------------------------------- */
struct saa7185 {
- struct i2c_bus *bus;
+ struct i2c_client *client;
int addr;
unsigned char reg[128];
+ struct semaphore lock;
int norm;
int enable;
@@ -69,66 +70,25 @@ struct saa7185 {
#define I2C_DELAY 10
/* ----------------------------------------------------------------------- */
+static unsigned short normal_i2c[] = { 34>>1, I2C_CLIENT_END };
+static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
+static unsigned short probe[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
+static unsigned short probe_range[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
+static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
+static unsigned short ignore_range[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
+static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
+
+static struct i2c_client_address_data addr_data = {
+ .normal_i2c = normal_i2c,
+ .normal_i2c_range = normal_i2c_range,
+ .probe = probe,
+ .probe_range = probe_range,
+ .ignore = ignore,
+ .ignore_range = ignore_range,
+ .force = force
+};
-static int saa7185_read(struct saa7185 *dev)
-{
- int ack;
-
- LOCK_I2C_BUS(dev->bus);
-
- i2c_start(dev->bus);
- i2c_sendbyte(dev->bus, dev->addr | 1, I2C_DELAY);
- ack = i2c_readbyte(dev->bus, 1);
- i2c_stop(dev->bus);
- UNLOCK_I2C_BUS(dev->bus);
- return ack;
-}
-
-static int saa7185_write(struct saa7185 *dev, unsigned char subaddr,
- unsigned char data)
-{
- int ack;
-
- DEBUG(printk
- (KERN_DEBUG "SAA7185: %02x set to %02x\n", subaddr, data);
- )
- LOCK_I2C_BUS(dev->bus);
-
- i2c_start(dev->bus);
- i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
- i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
- ack = i2c_sendbyte(dev->bus, data, I2C_DELAY);
- dev->reg[subaddr] = data;
- i2c_stop(dev->bus);
- UNLOCK_I2C_BUS(dev->bus);
- return ack;
-}
-
-static int saa7185_write_block(struct saa7185 *dev,
- unsigned const char *data, unsigned int len)
-{
- int ack = -1;
- unsigned subaddr;
-
- while (len > 1) {
- LOCK_I2C_BUS(dev->bus);
- i2c_start(dev->bus);
- i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
- ack = i2c_sendbyte(dev->bus, (subaddr = *data++), I2C_DELAY);
- ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
- len -= 2;
- while (len > 1 && *data == ++subaddr) {
- data++;
- ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
- len -= 2;
- }
- i2c_stop(dev->bus);
- UNLOCK_I2C_BUS(dev->bus);
- }
- return ack;
-}
-
-/* ----------------------------------------------------------------------- */
+static struct i2c_client client_template;
static const unsigned char init_common[] = {
0x3a, 0x0f, /* CBENB=0, V656=0, VY2C=1, YUV2C=1, MY2C=1, MUV2C=1 */
@@ -222,58 +182,71 @@ static const unsigned char init_ntsc[] = {
0x66, 0x21, /* FSC3 */
};
-static int saa7185_attach(struct i2c_device *device)
+static int saa7185_attach(struct i2c_adapter *adap, int addr, unsigned short flags, int kind)
{
int i;
struct saa7185 *encoder;
+ struct i2c_client client;
- MOD_INC_USE_COUNT;
-
- device->data = encoder = kmalloc(sizeof(struct saa7185), GFP_KERNEL);
+ client = kmalloc(sizeof(*client), GFP_KERNEL);
+ if (client == NULL)
+ return -ENOMEM;
+ client_template.adapter = adap;
+ client_template.addr = addr;
+ memcpy(client, &client_template, sizeof(*client));
+ encoder = kmalloc(sizeof(*decoder), GFP_KERNEL);
if (encoder == NULL) {
- MOD_DEC_USE_COUNT;
+ kfree(client);
return -ENOMEM;
}
- memset(encoder, 0, sizeof(struct saa7185));
- strcpy(device->name, "saa7185");
- encoder->bus = device->bus;
- encoder->addr = device->addr;
+ memset(encoder, 0, sizeof(*decoder));
+ strcpy(client->name, "saa7185");
+ encoder->client = client;
+ client->data = encoder;
+ encoder->addr = addr;
encoder->norm = VIDEO_MODE_NTSC;
encoder->enable = 1;
- i = saa7185_write_block(encoder, init_common, sizeof(init_common));
+ i = i2c_master_send(client, init_common, sizeof(init_common));
if (i >= 0) {
- i = saa7185_write_block(encoder, init_ntsc,
+ i = i2c_master_send(client, init_ntsc,
sizeof(init_ntsc));
}
if (i < 0) {
- printk(KERN_ERR "%s_attach: init error %d\n", device->name,
+ printk(KERN_ERR "%s_attach: init error %d\n", client->name,
i);
} else {
printk(KERN_INFO "%s_attach: chip version %d\n",
- device->name, saa7185_read(encoder) >> 5);
+ client->name, i2c_smbus_read_byte(client) >> 5);
}
-
+ init_MUTEX(&decoder->lock);
+ i2c_attach_client(client);
+ MOD_INC_USE_COUNT;
return 0;
}
+static int saa7185_probe(struct i2c_adapter *adap)
+{
+ return i2c_probe(adap, &addr_data, saa7185_attach);
+}
-
-static int saa7185_detach(struct i2c_device *device)
+static int saa7185_detach(struct i2c_client *client)
{
- struct saa7185 *encoder = device->data;
- saa7185_write(encoder, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */
- //saa7185_write(encoder, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */
+ struct saa7185 *encoder = client->data;
+ i2c_detach_client(client);
+ i2c_smbus_write_byte_data(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */
+ //i2c_smbus_write_byte_data(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */
kfree(encoder);
+ kfree(client);
MOD_DEC_USE_COUNT;
return 0;
}
-static int saa7185_command(struct i2c_device *device, unsigned int cmd,
+static int saa7185_command(struct i2c_client *client, unsigned int cmd,
void *arg)
{
- struct saa7185 *encoder = device->data;
+ struct saa7185 *encoder = client->data;
switch (cmd) {
@@ -297,12 +270,12 @@ static int saa7185_command(struct i2c_device *device, unsigned int cmd,
switch (*iarg) {
case VIDEO_MODE_NTSC:
- saa7185_write_block(encoder, init_ntsc,
+ i2c_master_send(client, init_ntsc,
sizeof(init_ntsc));
break;
case VIDEO_MODE_PAL:
- saa7185_write_block(encoder, init_pal,
+ i2c_master_send(client, init_pal,
sizeof(init_pal));
break;
@@ -326,19 +299,19 @@ static int saa7185_command(struct i2c_device *device, unsigned int cmd,
case 0:
/* Switch RTCE to 1 */
- saa7185_write(encoder, 0x61,
+ i2c_smbus_write_byte_data(client, 0x61,
(encoder->
reg[0x61] & 0xf7) | 0x08);
- saa7185_write(encoder, 0x6e, 0x01);
+ i2c_smbus_write_byte_data(client, 0x6e, 0x01);
break;
case 1:
/* Switch RTCE to 0 */
- saa7185_write(encoder, 0x61,
+ i2c_smbus_write_byte_data(client, 0x61,
(encoder->
reg[0x61] & 0xf7) | 0x00);
/* SW: a slight sync problem... */
- saa7185_write(encoder, 0x6e, 0x00);
+ i2c_smbus_write_byte_data(client, 0x6e, 0x00);
break;
default:
@@ -364,7 +337,7 @@ static int saa7185_command(struct i2c_device *device, unsigned int cmd,
int *iarg = arg;
encoder->enable = !!*iarg;
- saa7185_write(encoder, 0x61,
+ i2c_smbus_write_byte_data(client, 0x61,
(encoder->
reg[0x61] & 0xbf) | (encoder->
enable ? 0x00 :
@@ -382,23 +355,28 @@ static int saa7185_command(struct i2c_device *device, unsigned int cmd,
/* ----------------------------------------------------------------------- */
static struct i2c_driver i2c_driver_saa7185 = {
- "saa7185", /* name */
- I2C_DRIVERID_VIDEOENCODER, /* ID */
- I2C_SAA7185, I2C_SAA7185 + 1,
+ .name = "saa7185", /* name */
+ .id = I2C_DRIVERID_SAA7185B, /* ID */
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = saa7185_probe,
+ .detach_client = saa7185_detach,
+ .command = saa7185_command
+};
- saa7185_attach,
- saa7185_detach,
- saa7185_command
+static struct i2c_client client_template = {
+ .name = "saa7185_client",
+ .id = -1,
+ .driver = &i2c_driver_saa7185
};
static int saa7185_init(void)
{
- return i2c_register_driver(&i2c_driver_saa7185);
+ return i2c_add_driver(&i2c_driver_saa7185);
}
static void saa7185_exit(void)
{
- i2c_unregister_driver(&i2c_driver_saa7185);
+ i2c_del_driver(&i2c_driver_saa7185);
}
module_init(saa7185_init);
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index b26ee233e9aa..cb7d91bc07a6 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -49,7 +49,7 @@
* (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
*
- * $Id: mptbase.c,v 1.122 2002/10/03 13:10:11 pdelaney Exp $
+ * $Id: mptbase.c,v 1.123 2002/10/17 20:15:56 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
@@ -1156,7 +1156,7 @@ mpt_pci_scan(void)
dprintk((KERN_INFO MYNAM ": Checking for MPT adapters...\n"));
/*
- * NOTE: The 929, 929X and 1030 will appear as 2 separate PCI devices,
+ * NOTE: The 929, 929X, 1030 and 1035 will appear as 2 separate PCI devices,
* one for each channel.
*/
pci_for_each_dev(pdev) {
@@ -1170,18 +1170,14 @@ mpt_pci_scan(void)
(pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929X) &&
(pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919X) &&
(pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030) &&
-#if 0
- /* FIXME! C103x family */
- (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030_ZC) &&
- (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1035) &&
-#endif
+ (pdev->device != MPI_MANUFACTPAGE_DEVID_1030_53C1035) &&
1) {
dprintk((KERN_INFO MYNAM ": Skipping LSI device=%04xh\n", pdev->device));
continue;
}
/* GRRRRR
- * dual function devices (929, 929X, 1030) may be presented in Func 1,0 order,
+ * dual function devices (929, 929X, 1030, 1035) may be presented in Func 1,0 order,
* but we'd really really rather have them in Func 0,1 order.
* Do some kind of look ahead here...
*/
@@ -1445,15 +1441,24 @@ mpt_adapter_install(struct pci_dev *pdev)
ioc->chip_type = C1030;
ioc->prod_name = "LSI53C1030";
{
+ u8 revision;
+
/* 1030 Chip Fix. Disable Split transactions
- * for PCIX. Set bits 4 - 6 to zero.
+ * for PCIX. Set bits 4 - 6 to zero if Rev < C0( = 8)
*/
- u16 pcixcmd = 0;
- pci_read_config_word(pdev, 0x6a, &pcixcmd);
- pcixcmd &= 0xFF8F;
- pci_write_config_word(pdev, 0x6a, pcixcmd);
+ pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
+ if (revision < 0x08) {
+ u16 pcixcmd = 0;
+ pci_read_config_word(pdev, 0x6a, &pcixcmd);
+ pcixcmd &= 0xFF8F;
+ pci_write_config_word(pdev, 0x6a, pcixcmd);
+ }
}
}
+ else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
+ ioc->chip_type = C1035;
+ ioc->prod_name = "LSI53C1035";
+ }
sprintf(ioc->name, "ioc%d", ioc->id);
@@ -1500,9 +1505,10 @@ mpt_adapter_install(struct pci_dev *pdev)
mpt_adapters[ioc->id] = ioc;
/* NEW! 20010220 -sralston
- * Check for "bound ports" (929, 929X, 1030) to reduce redundant resets.
+ * Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
*/
- if ((ioc->chip_type == FC929) || (ioc->chip_type == C1030) || (ioc->chip_type == FC929X))
+ if ((ioc->chip_type == FC929) || (ioc->chip_type == C1030)
+ || (ioc->chip_type == C1035) || (ioc->chip_type == FC929X))
mpt_detect_bound_ports(ioc, pdev);
if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
@@ -1746,7 +1752,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
/*
* mpt_detect_bound_ports - Search for PCI bus/dev_function
* which matches PCI bus/dev_function (+/-1) for newly discovered 929,
- * 929X or 1030.
+ * 929X, 1030 or 1035.
* @ioc: Pointer to MPT adapter structure
* @pdev: Pointer to (struct pci_dev) structure
*
@@ -1806,8 +1812,7 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
/* Disable the FW */
state = mpt_GetIocState(this, 1);
if (state == MPI_IOC_STATE_OPERATIONAL) {
- if (SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, NO_SLEEP) != 0)
- (void) KickStart(this, 1, NO_SLEEP);
+ SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, NO_SLEEP);
}
if (this->cached_fw != NULL) {
@@ -1819,7 +1824,6 @@ mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
}
}
-
/* Disable adapter interrupts! */
CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
this->active = 0;
@@ -2291,9 +2295,6 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
ioc->reply_sz = ioc->req_sz;
ioc->reply_depth = MIN(MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
- /* 1030 - should we use a smaller DEFAULT_REPLY_DEPTH?
- * FIX
- */
dprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
ioc->name, ioc->reply_sz, ioc->reply_depth));
dprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
@@ -2891,6 +2892,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
*/
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
while ((diag0val & MPI_DIAG_DRWE) == 0) {
+ CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
@@ -3126,6 +3128,18 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
int cnt = 0;
dprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
+ if ((int)ioc->chip_type > (int)FC929) {
+ /* Always issue a Msg Unit Reset first. This will clear some
+ * SCSI bus hang conditions.
+ */
+ SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
+
+ if (sleepFlag == CAN_SLEEP) {
+ schedule_timeout(HZ);
+ } else {
+ mdelay (1000);
+ }
+ }
hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
if (hard_reset_done < 0)
@@ -5841,6 +5855,15 @@ fusion_exit(void)
while (! Q_IS_EMPTY(&MptAdapters)) {
this = MptAdapters.head;
+
+ /* Disable interrupts! */
+ CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
+
+ this->active = 0;
+
+ /* Clear any lingering interrupt */
+ CHIPREG_WRITE32(&this->chip->IntStatus, 0);
+
Q_DEL_ITEM(this);
mpt_adapter_dispose(this);
}
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 18cc08030861..c992a7f70379 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -13,7 +13,7 @@
* (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
*
- * $Id: mptbase.h,v 1.134 2002/10/03 13:10:12 pdelaney Exp $
+ * $Id: mptbase.h,v 1.136 2002/10/21 13:51:54 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
@@ -80,8 +80,8 @@
#define COPYRIGHT "Copyright (c) 1999-2002 " MODULEAUTHOR
#endif
-#define MPT_LINUX_VERSION_COMMON "2.02.01.07"
-#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.02.01.07"
+#define MPT_LINUX_VERSION_COMMON "2.03.00.02"
+#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.03.00.02"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
@@ -301,6 +301,7 @@ typedef enum {
FC919 = 0x0919,
FC929 = 0x0929,
C1030 = 0x1030,
+ C1035 = 0x1035,
FCUNK = 0xFBAD
} CHIP_TYPE;
@@ -368,6 +369,7 @@ typedef struct _ScsiCmndTracker {
typedef struct _VirtDevice {
struct _VirtDevice *forw;
struct _VirtDevice *back;
+ struct scsi_device *device;
rwlock_t VdevLock;
int ref_cnt;
u8 tflags;
@@ -912,6 +914,10 @@ typedef struct _MPT_SCSI_HOST {
MPT_FRAME_HDR *cmdPtr; /* Ptr to nonOS request */
struct scsi_cmnd *abortSCpnt;
MPT_LOCAL_REPLY localReply; /* internal cmd reply struct */
+ unsigned long hard_resets; /* driver forced bus resets count */
+ unsigned long soft_resets; /* fw/external bus resets count */
+ unsigned long timeouts; /* cmd timeouts */
+ ushort sel_timeout[MPT_MAX_FC_DEVICES];
} MPT_SCSI_HOST;
/*
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 8b6281b666ca..445afed79fd9 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -34,7 +34,7 @@
* (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
*
- * $Id: mptctl.c,v 1.60 2002/10/03 13:10:13 pdelaney Exp $
+ * $Id: mptctl.c,v 1.61 2002/10/17 20:15:57 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
@@ -136,14 +136,8 @@ static int mptctl_eventreport (unsigned long arg);
static int mptctl_replace_fw (unsigned long arg);
static int mptctl_do_reset(unsigned long arg);
-
-static int mptctl_compaq_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-static int mptctl_cpq_getpciinfo(unsigned long arg);
-static int mptctl_cpq_getdriver(unsigned long arg);
-static int mptctl_cpq_ctlr_status(unsigned long arg);
-static int mptctl_cpq_target_address(unsigned long arg);
-static int mptctl_cpq_passthru(unsigned long arg);
-static int mptctl_compaq_scsiio(VENDOR_IOCTL_REQ *pVenReq, cpqfc_passthru_t *pPass);
+static int mptctl_hp_hostinfo(unsigned long arg);
+static int mptctl_hp_targetinfo(unsigned long arg);
/*
* Private function calls.
@@ -415,7 +409,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
/* Send request
*/
if ((mf = mpt_get_msg_frame(mptctl_id, ioctl->ioc->id)) == NULL) {
- dtmprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
+ dctlprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
ioctl->ioc->name));
mptctl_free_tm_flags(ioctl->ioc);
@@ -623,21 +617,13 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
}
ret = -ENXIO; /* (-6) No such device or address */
-
- /* Test for Compaq-specific IOCTL's.
- */
- if ((cmd == CPQFCTS_GETPCIINFO) || (cmd == CPQFCTS_CTLR_STATUS) ||
- (cmd == CPQFCTS_GETDRIVVER) || (cmd == CPQFCTS_SCSI_PASSTHRU) ||
- (cmd == CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS))
- return mptctl_compaq_ioctl(file, cmd, arg);
-
/* Verify intended MPT adapter - set iocnum and the adapter
* pointer (iocp)
*/
iocnumX = khdr.iocnum & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
+ dctlprintk((KERN_ERR "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnumX));
return -ENODEV;
}
@@ -683,6 +669,12 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
case MPTHARDRESET:
ret = mptctl_do_reset(arg);
break;
+ case HP_GETHOSTINFO:
+ ret = mptctl_hp_hostinfo(arg);
+ break;
+ case HP_GETTARGETINFO:
+ ret = mptctl_hp_targetinfo(arg);
+ break;
default:
ret = -EINVAL;
}
@@ -708,7 +700,7 @@ static int mptctl_do_reset(unsigned long arg)
}
if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) {
- dtmprintk((KERN_ERR "%s@%d::mptctl_do_reset - ioc%d not found!\n",
+ dctlprintk((KERN_ERR "%s@%d::mptctl_do_reset - ioc%d not found!\n",
__FILE__, __LINE__, krinfo.hdr.iocnum));
return -ENODEV; /* (-6) No such device or address */
}
@@ -816,7 +808,7 @@ mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
dctlprintk((KERN_INFO "DbG: kfwdl.ioc = %04xh\n", ioc));
if ((ioc = mpt_verify_adapter(ioc, &iocp)) < 0) {
- dtmprintk(("%s@%d::_ioctl_fwdl - ioc%d not found!\n",
+ dctlprintk(("%s@%d::_ioctl_fwdl - ioc%d not found!\n",
__FILE__, __LINE__, ioc));
return -ENODEV; /* (-6) No such device or address */
}
@@ -1252,7 +1244,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
+ dctlprintk((KERN_ERR "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
@@ -1379,7 +1371,7 @@ mptctl_gettargetinfo (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
+ dctlprintk((KERN_ERR "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
@@ -1510,7 +1502,7 @@ mptctl_readtest (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_readtest() @%d - ioc%d not found!\n",
+ dctlprintk((KERN_ERR "%s::mptctl_readtest() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
@@ -1568,7 +1560,7 @@ mptctl_eventquery (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
+ dctlprintk((KERN_ERR "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
@@ -1606,7 +1598,7 @@ mptctl_eventenable (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
+ dctlprintk((KERN_ERR "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
@@ -1654,7 +1646,7 @@ mptctl_eventreport (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
+ dctlprintk((KERN_ERR "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
@@ -1708,7 +1700,7 @@ mptctl_replace_fw (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
+ dctlprintk((KERN_ERR "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
@@ -1794,7 +1786,7 @@ mptctl_mpt_command (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
+ dctlprintk((KERN_ERR "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
@@ -1842,7 +1834,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
+ dctlprintk((KERN_ERR "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
@@ -1926,6 +1918,14 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
int target = (int) pScsiReq->TargetID;
int dataSize;
+ if ((target < 0) || (target >= ioc->sh->max_id)) {
+ printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+ "Target ID out of bounds. \n",
+ __FILE__, __LINE__);
+ rc = -ENODEV;
+ goto done_free_mem;
+ }
+
pScsiReq->MsgFlags = mpt_msg_flags();
/* verify that app has not requested
@@ -2049,9 +2049,37 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
}
break;
+ case MPI_FUNCTION_IOC_INIT:
+ {
+ IOCInit_t *pInit = (IOCInit_t *) mf;
+ u32 high_addr, sense_high;
+
+ /* Verify that all entries in the IOC INIT match
+ * existing setup (and in LE format).
+ */
+ if (sizeof(dma_addr_t) == sizeof(u64)) {
+ high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
+ sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
+ } else {
+ high_addr = 0;
+ sense_high= 0;
+ }
+
+ if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) ||
+ (pInit->MaxBuses != ioc->facts.MaxBuses) ||
+ (pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||
+ (pInit->HostMfaHighAddr != high_addr) ||
+ (pInit->SenseBufferHighAddr != sense_high)) {
+ printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+ "IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",
+ __FILE__, __LINE__);
+ rc = -EFAULT;
+ goto done_free_mem;
+ }
+ }
+ break;
default:
/*
- * MPI_FUNCTION_IOC_INIT
* MPI_FUNCTION_PORT_ENABLE
* MPI_FUNCTION_TARGET_CMD_BUFFER_POST
* MPI_FUNCTION_TARGET_ASSIST
@@ -2357,131 +2385,85 @@ done_free_mem:
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* Routine for the Compaq IOCTL commands.
+/* Prototype Routine for the HP HOST INFO command.
*
* Outputs: None.
* Return: 0 if successful
- * -EBUSY if previous command timout and IOC reset is not complete.
* -EFAULT if data unavailable
- * -ENODEV if no such device/adapter
- * -ETIME if timer expires
- * -ENOMEM if memory allocation error
- */
-static int
-mptctl_compaq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int iocnum = 0;
- unsigned iocnumX = 0;
- int ret;
- int nonblock = (file->f_flags & O_NONBLOCK);
- MPT_ADAPTER *iocp = NULL;
-
- if (cmd == CPQFCTS_SCSI_PASSTHRU) {
- /* Update the iocnum */
- if (copy_from_user(&iocnumX, (int *)arg, sizeof(int))) {
- printk(KERN_ERR "%s::mptctl_compaq_ioctl() @%d - "
- "Unable to read controller number @ %p\n",
- __FILE__, __LINE__, (void*)arg);
- return -EFAULT;
- }
- iocnumX &= 0xFF;
- }
-
- if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
- (iocp == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_compaq_ioctl() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnumX));
- return -ENODEV;
- }
-
- /* All of these commands require an interrupt or
- * are unknown/illegal.
- */
- if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
- return ret;
-
- dctlprintk((MYIOC_s_INFO_FMT ": mptctl_compaq_ioctl()\n", iocp->name));
-
- switch(cmd) {
- case CPQFCTS_GETPCIINFO:
- ret = mptctl_cpq_getpciinfo(arg);
- break;
- case CPQFCTS_GETDRIVVER:
- ret = mptctl_cpq_getdriver(arg);
- break;
- case CPQFCTS_CTLR_STATUS:
- ret = mptctl_cpq_ctlr_status(arg);
- break;
- case CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS:
- ret = mptctl_cpq_target_address(arg);
- break;
- case CPQFCTS_SCSI_PASSTHRU:
- ret = mptctl_cpq_passthru(arg);
- break;
- default:
- ret = -EINVAL;
- }
-
- up(&mptctl_syscall_sem_ioc[iocp->id]);
-
- return ret;
-
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* mptctl_cpq_getpciinfo - Get PCI Information in format desired by Compaq
- *
- * Outputs: None.
- * Return: 0 if successful
* -EBUSY if previous command timout and IOC reset is not complete.
- * -EFAULT if data unavailable
* -ENODEV if no such device/adapter
* -ETIME if timer expires
+ * -ENOMEM if memory allocation error
*/
static int
-mptctl_cpq_getpciinfo(unsigned long arg)
+mptctl_hp_hostinfo(unsigned long arg)
{
- cpqfc_pci_info_struct *uarg = (cpqfc_pci_info_struct *) arg;
- cpqfc_pci_info_struct karg;
+ hp_host_info_t *uarg = (hp_host_info_t *) arg;
MPT_ADAPTER *ioc;
struct pci_dev *pdev;
+ char *pbuf;
+ dma_addr_t buf_dma;
+ hp_host_info_t karg;
CONFIGPARMS cfg;
ConfigPageHeader_t hdr;
- int iocnum = 0, iocnumX = 0;
- dma_addr_t buf_dma;
- u8 *pbuf = NULL;
- int failed;
+ int iocnum;
+ int rc;
- dctlprintk((": mptctl_cpq_pciinfo called.\n"));
- if (copy_from_user(&karg, uarg, sizeof(cpqfc_pci_info_struct))) {
- printk(KERN_ERR "%s@%d::mptctl_cpq_pciinfo - "
- "Unable to read in cpqfc_pci_info_struct @ %p\n",
+ dctlprintk((": mptctl_hp_hostinfo called.\n"));
+ if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
+ printk(KERN_ERR "%s@%d::mptctl_hp_host_info - "
+ "Unable to read in hp_host_info struct @ %p\n",
__FILE__, __LINE__, (void*)uarg);
- return -EINVAL;
+ return -EFAULT;
}
- if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
+ if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_pciinfo() @%d - ioc%d not found!\n",
+ dctlprintk((KERN_ERR "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
+ /* Fill in the data and return the structure to the calling
+ * program
+ */
pdev = (struct pci_dev *) ioc->pcidev;
- /* Populate the structure. */
- karg.bus = pdev->bus->number;
- karg.bus_type = 1; /* 1 = PCI; 4 = unknown */
- karg.device_fn = PCI_FUNC(pdev->devfn);
- karg.slot_number = PCI_SLOT(pdev->devfn);
- karg.vendor_id = pdev->vendor;
- karg.device_id = pdev->device;
- karg.board_id = (karg.device_id | (karg.vendor_id << 16));
- karg.class_code = pdev->class;
+ karg.vendor = pdev->vendor;
+ karg.device = pdev->device;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
- karg.sub_vendor_id = pdev->subsystem_vendor;
- karg.sub_device_id = pdev->subsystem_device;
+ karg.subsystem_id = pdev->subsystem_device;
+ karg.subsystem_vendor = pdev->subsystem_vendor;
#endif
+ karg.devfn = pdev->devfn;
+ karg.bus = pdev->bus->number;
+
+ /* Save the SCSI host no. if
+ * SCSI driver loaded
+ */
+ if (ioc->sh != NULL)
+ karg.host_no = ioc->sh->host_no;
+ else
+ karg.host_no = -1;
+
+ /* Reformat the fw_version into a string
+ */
+ karg.fw_version[0] = ioc->facts.FWVersion.Struct.Major >= 10 ?
+ ((ioc->facts.FWVersion.Struct.Major / 10) + '0') : '0';
+ karg.fw_version[1] = (ioc->facts.FWVersion.Struct.Major % 10 ) + '0';
+ karg.fw_version[2] = '.';
+ karg.fw_version[3] = ioc->facts.FWVersion.Struct.Minor >= 10 ?
+ ((ioc->facts.FWVersion.Struct.Minor / 10) + '0') : '0';
+ karg.fw_version[4] = (ioc->facts.FWVersion.Struct.Minor % 10 ) + '0';
+ karg.fw_version[5] = '.';
+ karg.fw_version[6] = ioc->facts.FWVersion.Struct.Unit >= 10 ?
+ ((ioc->facts.FWVersion.Struct.Unit / 10) + '0') : '0';
+ karg.fw_version[7] = (ioc->facts.FWVersion.Struct.Unit % 10 ) + '0';
+ karg.fw_version[8] = '.';
+ karg.fw_version[9] = ioc->facts.FWVersion.Struct.Dev >= 10 ?
+ ((ioc->facts.FWVersion.Struct.Dev / 10) + '0') : '0';
+ karg.fw_version[10] = (ioc->facts.FWVersion.Struct.Dev % 10 ) + '0';
+ karg.fw_version[11] = '\0';
/* Issue a config request to get the device serial number
*/
@@ -2496,8 +2478,7 @@ mptctl_cpq_getpciinfo(unsigned long arg)
cfg.dir = 0; /* read */
cfg.timeout = 10;
- failed = 1;
-
+ strncpy(karg.serial_number, " ", 24);
if (mpt_config(ioc, &cfg) == 0) {
if (cfg.hdr->PageLength > 0) {
/* Issue the second config page request */
@@ -2508,242 +2489,207 @@ mptctl_cpq_getpciinfo(unsigned long arg)
cfg.physAddr = buf_dma;
if (mpt_config(ioc, &cfg) == 0) {
ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
- strncpy(karg.serial_number, pdata->BoardTracerNumber, 17);
- failed = 0;
+ if (strlen(pdata->BoardTracerNumber) > 1)
+ strncpy(karg.serial_number, pdata->BoardTracerNumber, 24);
}
pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
pbuf = NULL;
}
}
}
- if (failed)
- strncpy(karg.serial_number, " ", 17);
-
- /* Copy the data from kernel memory to user memory
- */
- if (copy_to_user((char *)arg, &karg,
- sizeof(cpqfc_pci_info_struct))) {
- printk(KERN_ERR "%s@%d::mptctl_cpq_pciinfo - "
- "Unable to write out cpqfc_pci_info_struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
- return -EFAULT;
- }
+ rc = mpt_GetIocState(ioc, 1);
+ switch (rc) {
+ case MPI_IOC_STATE_OPERATIONAL:
+ karg.ioc_status = HP_STATUS_OK;
+ break;
- return 0;
-}
+ case MPI_IOC_STATE_FAULT:
+ karg.ioc_status = HP_STATUS_FAILED;
+ break;
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* mptctl_cpq_getdriver - Get Driver Version in format desired by Compaq
- *
- * Outputs: None.
- * Return: 0 if successful
- * -EFAULT if data unavailable
- * -ENODEV if no such device/adapter
- */
-static int
-mptctl_cpq_getdriver(unsigned long arg)
-{
- int *uarg = (int *)arg;
- int karg;
- MPT_ADAPTER *ioc = NULL;
- int iocnum = 0, iocnumX = 0;
- int ii, jj;
- char version[10];
- char val;
- char *vptr = NULL;
- char *pptr = NULL;
-
- dctlprintk((": mptctl_cpq_getdriver called.\n"));
- if (copy_from_user(&karg, uarg, sizeof(int))) {
- printk(KERN_ERR "%s@%d::mptctl_cpq_getdriver - "
- "Unable to read in struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
- return -EFAULT;
+ case MPI_IOC_STATE_RESET:
+ case MPI_IOC_STATE_READY:
+ default:
+ karg.ioc_status = HP_STATUS_OTHER;
+ break;
}
- if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
- (ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_cpq_getdriver() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum));
- return -ENODEV;
- }
+ karg.base_io_addr = pdev->PCI_BASEADDR_START(0);
- strncpy(version, MPT_LINUX_VERSION_COMMON, 8);
-
- karg = 0;
- vptr = version;
- ii = 3;
- while (ii > 0) {
- pptr = strchr(vptr, '.');
- if (pptr) {
- *pptr = '\0';
- val = 0;
- for (jj=0; vptr[jj]>='0' && vptr[jj]<='9'; jj++)
- val = 10 * val + (vptr[jj] - '0');
- karg |= (val << (8*ii));
- pptr++;
- vptr = pptr;
- } else
- break;
- ii--;
+ if ((int)ioc->chip_type <= (int) FC929)
+ karg.bus_phys_width = HP_BUS_WIDTH_UNK;
+ else
+ karg.bus_phys_width = HP_BUS_WIDTH_16;
+
+ karg.hard_resets = 0;
+ karg.soft_resets = 0;
+ karg.timeouts = 0;
+ if (ioc->sh != NULL) {
+ MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
+
+ if (hd) {
+ karg.hard_resets = hd->hard_resets;
+ karg.soft_resets = hd->soft_resets;
+ karg.timeouts = hd->timeouts;
+ }
}
/* Copy the data from kernel memory to user memory
*/
if (copy_to_user((char *)arg, &karg,
- sizeof(int))) {
- printk(KERN_ERR "%s@%d::mptctl_cpq_getdriver - "
- "Unable to write out stuct @ %p\n",
+ sizeof(hp_host_info_t))) {
+ printk(KERN_ERR "%s@%d::mptctl_hpgethostinfo - "
+ "Unable to write out hp_host_info @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EFAULT;
}
return 0;
+
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* mptctl_cpq_ctlr_status - Get controller status in format desired by Compaq
+/* Prototype Routine for the HP TARGET INFO command.
*
* Outputs: None.
* Return: 0 if successful
* -EFAULT if data unavailable
+ * -EBUSY if previous command timout and IOC reset is not complete.
* -ENODEV if no such device/adapter
+ * -ETIME if timer expires
+ * -ENOMEM if memory allocation error
*/
static int
-mptctl_cpq_ctlr_status(unsigned long arg)
+mptctl_hp_targetinfo(unsigned long arg)
{
- cpqfc_ctlr_status *uarg = (cpqfc_ctlr_status *) arg;
- cpqfc_ctlr_status karg;
+ hp_target_info_t *uarg = (hp_target_info_t *) arg;
+ SCSIDevicePage0_t *pg0_alloc;
+ SCSIDevicePage3_t *pg3_alloc;
MPT_ADAPTER *ioc;
- int iocnum = 0, iocnumX = 0;
+ MPT_SCSI_HOST *hd = NULL;
+ hp_target_info_t karg;
+ int iocnum;
+ int data_sz;
+ dma_addr_t page_dma;
+ CONFIGPARMS cfg;
+ ConfigPageHeader_t hdr;
+ int tmp, np, rc = 0;
- dctlprintk((": mptctl_cpq_pciinfo called.\n"));
- if (copy_from_user(&karg, uarg, sizeof(cpqfc_ctlr_status))) {
- printk(KERN_ERR "%s@%d::mptctl_cpq_ctlr_status - "
- "Unable to read in cpqfc_ctlr_status @ %p\n",
+ dctlprintk((": mptctl_hp_targetinfo called.\n"));
+ if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
+ printk(KERN_ERR "%s@%d::mptctl_hp_targetinfo - "
+ "Unable to read in hp_host_targetinfo struct @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EFAULT;
}
-
- if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
- (ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_cpq_ctlr_status() @%d - ioc%d not found!\n",
+
+ if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
+ (ioc == NULL)) {
+ dctlprintk((KERN_ERR "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum));
return -ENODEV;
}
- karg.status = ioc->last_state;
- karg.offline_reason = 0;
-
- /* Copy the data from kernel memory to user memory
+ /* There is nothing to do for FCP parts.
*/
- if (copy_to_user((char *)arg, &karg,
- sizeof(cpqfc_ctlr_status))) {
- printk(KERN_ERR "%s@%d::mptctl_cpq_ctlr_status - "
- "Unable to write out cpqfc_ctlr_status @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
- return -EFAULT;
- }
-
- return 0;
-}
+ if ((int) ioc->chip_type <= (int) FC929)
+ return 0;
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* mptctl_cpq_target_address - Get WWN Information in format desired by Compaq
- *
- * Outputs: None.
- * Return: 0 if successful
- * -EBUSY if previous command timout and IOC reset is not complete.
- * -EFAULT if data unavailable
- * -ENODEV if no such device/adapter
- * -ETIME if timer expires
- */
-static int
-mptctl_cpq_target_address(unsigned long arg)
-{
- Scsi_FCTargAddress *uarg = (Scsi_FCTargAddress *) arg;
- Scsi_FCTargAddress karg;
- MPT_ADAPTER *ioc;
- int iocnum = 0, iocnumX = 0;
- CONFIGPARMS cfg;
- ConfigPageHeader_t hdr;
- dma_addr_t buf_dma;
- u8 *pbuf = NULL;
- FCPortPage0_t *ppp0;
- int ii, failed;
- u32 low, high;
-
- dctlprintk((": mptctl_cpq_target_address called.\n"));
- if (copy_from_user(&karg, uarg, sizeof(Scsi_FCTargAddress))) {
- printk(KERN_ERR "%s@%d::mptctl_cpq_target_address - "
- "Unable to read in Scsi_FCTargAddress @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
- return -EFAULT;
- }
+ if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
+ return 0;
- if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
- (ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_cpq_target_address() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum));
+ if (ioc->sh->host_no != karg.hdr.host)
return -ENODEV;
+
+ /* Get the data transfer speeds
+ */
+ data_sz = ioc->spi_data.sdp0length * 4;
+ pg0_alloc = (SCSIDevicePage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
+ if (pg0_alloc) {
+ hdr.PageVersion = ioc->spi_data.sdp0version;
+ hdr.PageLength = data_sz;
+ hdr.PageNumber = 0;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
+
+ cfg.hdr = &hdr;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+ cfg.dir = 0;
+ cfg.timeout = 0;
+ cfg.physAddr = page_dma;
+
+ cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
+
+ if ((rc = mpt_config(ioc, &cfg)) == 0) {
+ np = le32_to_cpu(pg0_alloc->NegotiatedParameters);
+ karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ?
+ HP_BUS_WIDTH_16 : HP_BUS_WIDTH_8;
+
+ if (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) {
+ tmp = (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
+ if (tmp < 0x09)
+ karg.negotiated_speed = HP_DEV_SPEED_ULTRA320;
+ else if (tmp <= 0x09)
+ karg.negotiated_speed = HP_DEV_SPEED_ULTRA160;
+ else if (tmp <= 0x0A)
+ karg.negotiated_speed = HP_DEV_SPEED_ULTRA2;
+ else if (tmp <= 0x0C)
+ karg.negotiated_speed = HP_DEV_SPEED_ULTRA;
+ else if (tmp <= 0x25)
+ karg.negotiated_speed = HP_DEV_SPEED_FAST;
+ else
+ karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
+ } else
+ karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
+ }
+
+ pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg0_alloc, page_dma);
}
- karg.host_port_id = 0;
+ /* Set defaults
+ */
+ karg.message_rejects = -1;
+ karg.phase_errors = -1;
+ karg.parity_errors = -1;
+ karg.select_timeouts = -1;
- /* Issue a config request to get the device wwn
+ /* Get the target error parameters
*/
hdr.PageVersion = 0;
hdr.PageLength = 0;
- hdr.PageNumber = 0;
- hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
+ hdr.PageNumber = 3;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
+
cfg.hdr = &hdr;
- cfg.physAddr = -1;
- cfg.pageAddr = 0;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
- cfg.dir = 0; /* read */
- cfg.timeout = 10;
-
- failed = 1;
-
- if (mpt_config(ioc, &cfg) == 0) {
- if (cfg.hdr->PageLength > 0) {
- /* Issue the second config page request */
- cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
-
- pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
- if (pbuf) {
- cfg.physAddr = buf_dma;
- if (mpt_config(ioc, &cfg) == 0) {
- ppp0 = (FCPortPage0_t *) pbuf;
-
- low = le32_to_cpu(ppp0->WWNN.Low);
- high = le32_to_cpu(ppp0->WWNN.High);
-
- for (ii = 0; ii < 4; ii++) {
- karg.host_wwn[7-ii] = low & 0xFF;
- karg.host_wwn[3-ii] = high & 0xFF;
- low = (low >> 8);
- high = (high >> 8);
- }
- failed = 0;
- }
- pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
- pbuf = NULL;
+ cfg.dir = 0;
+ cfg.timeout = 0;
+ cfg.physAddr = -1;
+ if ((mpt_config(ioc, &cfg) == 0) && (cfg.hdr->PageLength > 0)) {
+ /* Issue the second config page request */
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+ data_sz = (int) cfg.hdr->PageLength * 4;
+ pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
+ ioc->pcidev, data_sz, &page_dma);
+ if (pg3_alloc) {
+ cfg.physAddr = page_dma;
+ cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
+ if ((rc = mpt_config(ioc, &cfg)) == 0) {
+ karg.message_rejects = (u32) le16_to_cpu(pg3_alloc->MsgRejectCount);
+ karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
+ karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
}
+ pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
}
}
-
- if (failed) {
- for (ii = 7; ii >= 0; ii--)
- karg.host_wwn[ii] = 0;
- }
+ hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
+ if (hd != NULL)
+ karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
/* Copy the data from kernel memory to user memory
*/
- if (copy_to_user((char *)arg, &karg,
- sizeof(Scsi_FCTargAddress))) {
- printk(KERN_ERR "%s@%d::mptctl_cpq_target_address - "
- "Unable to write out Scsi_FCTargAddress @ %p\n",
+ if (copy_to_user((char *)arg, &karg, sizeof(hp_target_info_t))) {
+ printk(KERN_ERR "%s@%d::mptctl_hp_target_info - "
+ "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
__FILE__, __LINE__, (void*)uarg);
return -EFAULT;
}
@@ -2752,161 +2698,6 @@ mptctl_cpq_target_address(unsigned long arg)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* mptctl_cpq_passthru - Construct and issue a SCSI IO Passthru
- *
- * Requires the SCSI host driver to be loaded.
- * I386 version.
- *
- * Outputs: None.
- * Return: 0 if successful
- * -EBUSY if previous command timout and IOC reset is not complete.
- * -EFAULT if data unavailable
- * -ENODEV if no such device/adapter
- * -ETIME if timer expires
- */
-static int
-mptctl_cpq_passthru(unsigned long arg)
-{
- VENDOR_IOCTL_REQ *uarg = (VENDOR_IOCTL_REQ *) arg;
- VENDOR_IOCTL_REQ karg;
- cpqfc_passthru_t kpass;
- MPT_ADAPTER *ioc;
- int iocnum = 0, iocnumX = 0;
- int rc;
-
- dctlprintk((": mptctl_cpq_passthru called.\n"));
- if (copy_from_user(&karg, uarg, sizeof(VENDOR_IOCTL_REQ))) {
- printk(KERN_ERR "%s@%d::mptctl_cpq_passthru - "
- "Unable to read in VENDOR_IOCTL_REQ @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
- return -EFAULT;
- }
-
- /* Set the IOC number */
- iocnumX = karg.lc & 0xFF;
- if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
- (ioc == NULL)) {
- dtmprintk((KERN_ERR "%s::mptctl_cpq_passthru() @%d - ioc%d not found!\n",
- __FILE__, __LINE__, iocnum));
- return -ENODEV;
- }
-
- if (ioc->sh == NULL) {
- printk(KERN_ERR "%s::mptctl_cpq_passthru() @%d - SCSI Host driver not loaded!\n",
- __FILE__, __LINE__);
- return -EFAULT;
- }
-
- /* Read in the second buffer */
- if (copy_from_user(&kpass, uarg->argp, sizeof(cpqfc_passthru_t))) {
- printk(KERN_ERR "%s@%d::mptctl_cpq_passthru - "
- "Unable to read in cpqfc_passthru_t @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
- return -EFAULT;
- }
-
-
- /* Generate the SCSI IO command and issue */
- rc = mptctl_compaq_scsiio(&karg, &kpass);
- return rc;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* mptctl_compaq_scsiio - Reformat Compaq structures into driver structures
- * Call the generic _do_mpt_command function.
- *
- * Requires the SCSI host driver to be loaded.
- * I386 version.
- *
- * Outputs: None.
- * Return: 0 if successful
- * -EBUSY if previous command timout and IOC reset is not complete.
- * -EFAULT if data unavailable
- * -ENODEV if no such device/adapter
- * -ETIME if timer expires
- */
-static int
-mptctl_compaq_scsiio(VENDOR_IOCTL_REQ *pVenReq, cpqfc_passthru_t *pPass)
-{
- struct mpt_ioctl_command karg;
- SCSIIORequest_t request ;
- SCSIIORequest_t *pMf;
- int ii, rc;
- u8 opcode;
-
- /* Fill in parameters to karg */
- karg.hdr.iocnum = pVenReq->lc;
- karg.hdr.port = 0;
- karg.hdr.maxDataSize = 0; /* not used */
- karg.timeout = 0; /* use default */
-
- karg.replyFrameBufPtr = NULL; /* no reply data */
- karg.maxReplyBytes = 0;
-
- karg.senseDataPtr = pPass->sense_data;
- karg.maxSenseBytes = pPass->sense_len; /* max is 40 */
-
- if (pPass->rw_flag == MPT_COMPAQ_WRITE) {
- karg.dataOutBufPtr = pPass->bufp;
- karg.dataOutSize = pPass->len;
- karg.dataInBufPtr = NULL;
- karg.dataInSize = 0;
- } else {
- karg.dataInBufPtr = pPass->bufp;
- karg.dataInSize = pPass->len;
- karg.dataOutBufPtr = NULL;
- karg.dataOutSize = 0;
- }
-
- karg.dataSgeOffset = (sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION))/4;
-
- /* Construct the Message frame */
- pMf = &request;
-
- pMf->TargetID = (u8) pVenReq->ld; /* ???? FIXME */
- pMf->Bus = (u8) pPass->bus;
- pMf->ChainOffset = 0;
- pMf->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
-
- /* May need some tweaking here */
- opcode = (u8) pPass->cdb[0];
- if (opcode < 0x20)
- pMf->CDBLength = 6;
- else if (opcode < 0x60)
- pMf->CDBLength = 10;
- else if ((opcode < 0xC0) && (opcode >= 0xA0))
- pMf->CDBLength = 12;
- else
- pMf->CDBLength = 16;
-
- pMf->SenseBufferLength = karg.maxSenseBytes; /* max is 40 */
- pMf->Reserved = 0;
- pMf->MsgFlags = 0; /* set later */
- pMf->MsgContext = 0; /* set later */
-
- for (ii = 0; ii < 8; ii++)
- pMf->LUN[ii] = 0;
- pMf->LUN[1] = 0; /* ???? FIXME */
-
- /* Tag values set by _do_mpt_command */
- if (pPass->rw_flag == MPT_COMPAQ_WRITE)
- pMf->Control = MPI_SCSIIO_CONTROL_WRITE;
- else
- pMf->Control = MPI_SCSIIO_CONTROL_READ;
-
- for (ii = 0; ii < 16; ii++)
- pMf->CDB[ii] = pPass->cdb[ii];
-
- pMf->DataLength = pPass->len;
-
- /* All remaining fields are set by the next function
- */
- rc = mptctl_do_mpt_command (karg, (char *)pMf, 1);
- return rc;
-}
-
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)
#define owner_THIS_MODULE owner: THIS_MODULE,
@@ -2971,7 +2762,7 @@ sparc32_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
iocnumX = kfw32.iocnum & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) {
- dtmprintk((KERN_ERR MYNAM "::sparc32_mptfwxfer_ioctl @%d - ioc%d not found!\n",
+ dctlprintk((KERN_ERR MYNAM "::sparc32_mptfwxfer_ioctl @%d - ioc%d not found!\n",
__LINE__, iocnumX));
return -ENODEV;
}
@@ -3011,7 +2802,7 @@ sparc32_mpt_command(unsigned int fd, unsigned int cmd,
iocnumX = karg32.hdr.iocnum & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) {
- dtmprintk((KERN_ERR MYNAM "::sparc32_mpt_command @%d - ioc%d not found!\n",
+ dctlprintk((KERN_ERR MYNAM "::sparc32_mpt_command @%d - ioc%d not found!\n",
__LINE__, iocnumX));
return -ENODEV;
}
@@ -3044,70 +2835,6 @@ sparc32_mpt_command(unsigned int fd, unsigned int cmd,
return ret;
}
-static int
-sparc32_mptctl_cpq_passthru(unsigned int fd, unsigned int cmd,
- unsigned long arg, struct file *filp)
-{
- VENDOR_IOCTL_REQ32 *uarg = (VENDOR_IOCTL_REQ32 *) arg;
- VENDOR_IOCTL_REQ32 karg32;
- VENDOR_IOCTL_REQ karg;
- cpqfc_passthru32_t kpass32;
- cpqfc_passthru_t kpass;
- MPT_ADAPTER *ioc;
- int nonblock = (filp->f_flags & O_NONBLOCK);
- int iocnum = 0, iocnumX = 0;
- int rc;
- int ii;
-
- dctlprintk((KERN_INFO MYNAM "::sparc32_mptctl_cpq_passthru() called\n"));
-
- if (copy_from_user(&karg32, (char *)arg, sizeof(karg32)))
- return -EFAULT;
-
- /* Verify intended MPT adapter */
- iocnumX = karg32.lc & 0xFF;
- if (((iocnum = mpt_verify_adapter(iocnumX, &ioc)) < 0) ||
- (ioc == NULL)) {
- dtmprintk((KERN_ERR MYNAM "::sparc32_mpt_command @%d - ioc%d not found!\n",
- __LINE__, iocnumX));
- return -ENODEV;
- }
-
- if ((rc = mptctl_syscall_down(ioc, nonblock)) != 0)
- return rc;
-
- /* Copy data to karg */
- karg.ld = karg32.ld;
- karg.node = karg32.node;
- karg.lc = karg32.lc;
- karg.nexus = karg32.nexus;
- karg.argp = (void *)(unsigned long)karg32.argp;
-
- /* Read in the second buffer */
- if (copy_from_user(&kpass32, karg.argp, sizeof(cpqfc_passthru32_t))) {
- printk(KERN_ERR "%s@%d::sparc32_mptctl_cpq_passthru - "
- "Unable to read in cpqfc_passthru_t @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
- return -EFAULT;
- }
-
- /* Copy the 32bit buffer to kpass */
- for (ii = 0; ii < 16; ii++)
- kpass.cdb[ii] = kpass32.cdb[ii];
- kpass.bus = kpass32.bus;
- kpass.pdrive = kpass32.pdrive;
- kpass.len = kpass32.len;
- kpass.sense_len = kpass32.sense_len;
- kpass.bufp = (void *)(unsigned long)kpass32.bufp;
- kpass.rw_flag = kpass32.rw_flag;
-
- /* Generate the SCSI IO command and issue */
- rc = mptctl_compaq_scsiio(&karg, &kpass);
-
- up(&mptctl_syscall_sem_ioc[ioc->id]);
- return rc;
-}
-
#endif /*} linux >= 2.3.x */
#endif /*} sparc */
@@ -3176,15 +2903,9 @@ int __init mptctl_init(void)
err = register_ioctl32_conversion(MPTFWDOWNLOAD32,
sparc32_mptfwxfer_ioctl);
if (++where && err) goto out_fail;
- err = register_ioctl32_conversion(CPQFCTS_GETPCIINFO, NULL);
- if (++where && err) goto out_fail;
- err = register_ioctl32_conversion(CPQFCTS_CTLR_STATUS, NULL);
- if (++where && err) goto out_fail;
- err = register_ioctl32_conversion(CPQFCTS_GETDRIVVER, NULL);
- if (++where && err) goto out_fail;
- err = register_ioctl32_conversion(CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS, NULL);
+ err = register_ioctl32_conversion(HP_GETHOSTINFO, NULL);
if (++where && err) goto out_fail;
- err = register_ioctl32_conversion(CPQFCTS_SCSI_PASSTHRU32, sparc32_mptctl_cpq_passthru);
+ err = register_ioctl32_conversion(HP_GETTARGETINFO, NULL);
if (++where && err) goto out_fail;
#endif /*} linux >= 2.3.x */
#endif /*} sparc */
@@ -3233,11 +2954,8 @@ out_fail:
unregister_ioctl32_conversion(MPTHARDRESET);
unregister_ioctl32_conversion(MPTCOMMAND32);
unregister_ioctl32_conversion(MPTFWDOWNLOAD32);
- unregister_ioctl32_conversion(CPQFCTS_GETPCIINFO);
- unregister_ioctl32_conversion(CPQFCTS_GETDRIVVER);
- unregister_ioctl32_conversion(CPQFCTS_CTLR_STATUS);
- unregister_ioctl32_conversion(CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS);
- unregister_ioctl32_conversion(CPQFCTS_SCSI_PASSTHRU32);
+ unregister_ioctl32_conversion(HP_GETHOSTINFO);
+ unregister_ioctl32_conversion(HP_GETTARGETINFO);
#endif /*} linux >= 2.3.x */
#endif /*} sparc */
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h
index 69b3d0a1efb6..444a5009c9ba 100644
--- a/drivers/message/fusion/mptctl.h
+++ b/drivers/message/fusion/mptctl.h
@@ -20,7 +20,7 @@
* (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
*
- * $Id: mptctl.h,v 1.11 2002/10/03 13:10:13 pdelaney Exp $
+ * $Id: mptctl.h,v 1.12 2002/10/17 20:15:58 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
@@ -310,95 +310,91 @@ struct mpt_ioctl_command32 {
#endif /*}*/
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
- /*
- * COMPAQ Specific IOCTL Defines and Structures
- */
+/*
+ * HP Specific IOCTL Defines and Structures
+ */
#define CPQFCTS_IOC_MAGIC 'Z'
+#define HP_IOC_MAGIC 'Z'
+#define HP_GETHOSTINFO _IOR(HP_IOC_MAGIC, 20, hp_host_info_t)
+#define HP_GETTARGETINFO _IOR(HP_IOC_MAGIC, 21, hp_target_info_t)
-#define CPQFCTS_GETPCIINFO _IOR(CPQFCTS_IOC_MAGIC, 1, cpqfc_pci_info_struct)
-#define CPQFCTS_GETDRIVVER _IOR(CPQFCTS_IOC_MAGIC, 9, int)
-#define CPQFCTS_CTLR_STATUS _IOR(CPQFCTS_IOC_MAGIC, 3, struct _cpqfc_ctlr_status)
-#define CPQFCTS_SCSI_IOCTL_FC_TARGET_ADDRESS _IOR(CPQFCTS_IOC_MAGIC, 13, struct scsi_fctargaddress)
-#define CPQFCTS_SCSI_PASSTHRU _IOWR(CPQFCTS_IOC_MAGIC, 11, VENDOR_IOCTL_REQ)
-#if defined(__sparc__) && defined(__sparc_v9__)
-#define CPQFCTS_SCSI_PASSTHRU32 _IOWR(CPQFCTS_IOC_MAGIC, 11, VENDOR_IOCTL_REQ32)
-#endif
-
-typedef struct {
- unsigned short bus;
- unsigned short bus_type;
- unsigned short device_fn;
- u32 board_id;
- u32 slot_number;
- unsigned short vendor_id;
- unsigned short device_id;
- unsigned short class_code;
- unsigned short sub_vendor_id;
- unsigned short sub_device_id;
- u8 serial_number[81];
-} cpqfc_pci_info_struct;
-
-
-typedef struct scsi_fctargaddress {
- unsigned int host_port_id;
- u8 host_wwn[8]; /* WW Network Name */
-} Scsi_FCTargAddress;
-
-typedef struct _cpqfc_ctlr_status {
- u32 status;
- u32 offline_reason;
-} cpqfc_ctlr_status;
-
-
-/* Compaq SCSI I/O Passthru structures.
+/* All HP IOCTLs must include this header
*/
-#define MPT_COMPAQ_READ 0x26
-#define MPT_COMPAQ_WRITE 0x27
-
-typedef struct {
- int lc; /* controller number */
- int node; /* node number */
- int ld; /* target logical id */
- u32 nexus;
- void *argp;
-} VENDOR_IOCTL_REQ;
-
-#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__) /*{*/
-typedef struct {
- int lc; /* controller number */
- int node; /* node number */
- int ld; /* target logical id */
- u32 nexus;
- u32 argp;
-} VENDOR_IOCTL_REQ32;
-#endif
-
-typedef struct {
- char cdb[16]; /* cdb */
- unsigned short bus; /* bus number */
- unsigned short pdrive; /* physical drive */
- int len; /* data area size */
- int sense_len; /* sense size */
- char sense_data[40]; /* sense buffer */
- void *bufp; /* data buffer pointer */
- char rw_flag;
-} cpqfc_passthru_t;
-
-#if defined(__KERNEL__) && defined(__sparc__) && defined(__sparc_v9__) /*{*/
-typedef struct {
- char cdb[16]; /* cdb */
- unsigned short bus; /* bus number */
- unsigned short pdrive; /* physical drive */
- int len; /* data area size */
- int sense_len; /* sense size */
- char sense_data[40]; /* sense buffer */
- u32 bufp; /* data buffer pointer */
- char rw_flag;
-} cpqfc_passthru32_t;
-#endif
+typedef struct _hp_header {
+ unsigned int iocnum;
+ unsigned int host;
+ unsigned int channel;
+ unsigned int id;
+ unsigned int lun;
+} hp_header_t;
+
+/*
+ * Header:
+ * iocnum required (input)
+ * host ignored
+ * channe ignored
+ * id ignored
+ * lun ignored
+ */
+typedef struct _hp_host_info {
+ hp_header_t hdr;
+ u16 vendor;
+ u16 device;
+ u16 subsystem_vendor;
+ u16 subsystem_id;
+ u8 devfn;
+ u8 bus;
+ ushort host_no; /* SCSI Host number, if scsi driver not loaded*/
+ u8 fw_version[16]; /* string */
+ u8 serial_number[24]; /* string */
+ u32 ioc_status;
+ u32 bus_phys_width;
+ u32 base_io_addr;
+ u32 rsvd;
+ unsigned long hard_resets; /* driver initiated resets */
+ unsigned long soft_resets; /* ioc, external resets */
+ unsigned long timeouts; /* num timeouts */
+} hp_host_info_t;
+
+/*
+ * Header:
+ * iocnum required (input)
+ * host required
+ * channel required (bus number)
+ * id required
+ * lun ignored
+ *
+ * All error values between 0 and 0xFFFF in size.
+ */
+typedef struct _hp_target_info {
+ hp_header_t hdr;
+ u32 parity_errors;
+ u32 phase_errors;
+ u32 select_timeouts;
+ u32 message_rejects;
+ u32 negotiated_speed;
+ u8 negotiated_width;
+ u8 rsvd[7]; /* 8 byte alignment */
+} hp_target_info_t;
+
+#define HP_STATUS_OTHER 1
+#define HP_STATUS_OK 2
+#define HP_STATUS_FAILED 3
+
+#define HP_BUS_WIDTH_UNK 1
+#define HP_BUS_WIDTH_8 2
+#define HP_BUS_WIDTH_16 3
+#define HP_BUS_WIDTH_32 4
+
+#define HP_DEV_SPEED_ASYNC 2
+#define HP_DEV_SPEED_FAST 3
+#define HP_DEV_SPEED_ULTRA 4
+#define HP_DEV_SPEED_ULTRA2 5
+#define HP_DEV_SPEED_ULTRA160 6
+#define HP_DEV_SPEED_SCSI1 7
+#define HP_DEV_SPEED_ULTRA320 8
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 179a2101e6f2..f02944755814 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -26,7 +26,7 @@
* Copyright (c) 2000-2002 LSI Logic Corporation
* Originally By: Noah Romer
*
- * $Id: mptlan.c,v 1.52 2002/05/06 13:45:07 sshirron Exp $
+ * $Id: mptlan.c,v 1.53 2002/10/17 20:15:58 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h
index 4add8de21bf2..1c20d33385d8 100644
--- a/drivers/message/fusion/mptlan.h
+++ b/drivers/message/fusion/mptlan.h
@@ -8,7 +8,6 @@
#include <linux/module.h>
#endif
-#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/errno.h>
// #include <linux/etherdevice.h>
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index e55a97bc1840..57faa74cba29 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -26,7 +26,7 @@
* (mailto:sjralston1@netscape.net)
* (mailto:Pam.Delaney@lsil.com)
*
- * $Id: mptscsih.c,v 1.102 2002/10/03 13:10:14 pdelaney Exp $
+ * $Id: mptscsih.c,v 1.103 2002/10/17 20:15:59 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
@@ -78,6 +78,9 @@
#include <linux/reboot.h> /* notifier code */
#include "../../scsi/scsi.h"
#include "../../scsi/hosts.h"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)
+#include "../../scsi/sd.h"
+#endif
#include "mptbase.h"
#include "mptscsih.h"
@@ -198,7 +201,7 @@ static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
static void mptscsih_domainValidation(void *hd);
static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
-static void mptscsih_qas_check(MPT_SCSI_HOST *hd);
+static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
static int mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int target);
static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
@@ -399,6 +402,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
/* Spoof to SCSI Selection Timeout! */
sc->result = DID_NO_CONNECT << 16;
+
+ if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
+ hd->sel_timeout[pScsiReq->TargetID]++;
break;
case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
@@ -1289,11 +1295,17 @@ mptscsih_detect(Scsi_Host_Template *tpnt)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
sh->max_sectors = MPT_SCSI_MAX_SECTORS;
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) || defined CONFIG_HIGHIO
sh->highmem_io = 1;
#endif
sh->this_id = this->pfacts[portnum].PortSCSIID;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,44)
+ /* OS entry to allow host drivers to force
+ * a queue depth on a per device basis.
+ */
+ sh->select_queue_depths = mptscsih_select_queue_depths;
+#endif
/* Required entry.
*/
sh->unique_id = this->id;
@@ -2546,14 +2558,13 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort,
/* Isse the Task Mgmt request.
*/
+ if (hd->hard_resets < -1)
+ hd->hard_resets++;
rc = mptscsih_IssueTaskMgmt(hd, type, target, lun, ctx2abort, sleepFlag);
if (rc) {
-#ifdef MPT_SCSI_USE_NEW_EH
- hd->tmState = TM_STATE_ERROR;
-#endif
printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
} else {
- printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name);
+ dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
}
}
#ifdef DROP_TEST
@@ -2681,7 +2692,6 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
MPT_FRAME_HDR *mf;
- unsigned long flags;
u32 ctx2abort;
int scpnt_idx;
@@ -2696,10 +2706,11 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
return FAILED;
}
- printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
- hd->ioc->name, SCpnt);
- printk(KERN_WARNING MYNAM ": %s: IOs outstanding = %d\n",
- hd->ioc->name, atomic_read(&queue_depth));
+ printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p, numIOs=%d)\n",
+ hd->ioc->name, SCpnt, atomic_read(&queue_depth));
+
+ if (hd->timeouts < -1)
+ hd->timeouts++;
/* Find this command
*/
@@ -2753,11 +2764,9 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
hd->abortSCpnt = SCpnt;
-
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
- SCpnt->target, SCpnt->lun, ctx2abort, CAN_SLEEP)
- < 0
- || hd->tmState == TM_STATE_ERROR) {
+ SCpnt->target, SCpnt->lun, ctx2abort, NO_SLEEP)
+ < 0) {
/* The TM request failed and the subsequent FW-reload failed!
* Fatal error case.
@@ -2765,14 +2774,6 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
hd->ioc->name, SCpnt);
- /* If command not found, do not do callback,
- * just return failed. CHECKME
- */
- if (hd->ScsiLookup[scpnt_idx] != NULL) {
- SCpnt->result = STS_BUSY;
- SCpnt->scsi_done(SCpnt);
- }
-
/* We must clear our pending flag before clearing our state.
*/
hd->tmPending = 0;
@@ -2780,34 +2781,8 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
return FAILED;
}
+ return FAILED;
- /* Our task management request will either complete or time out. So we
- * spin until tmPending is != 1. If tmState is set to TM_STATE_ERROR,
- * we encountered an error executing the task management request.
- */
- while (hd->tmPending == 1){
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ/4);
- }
- spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
- if (hd->tmState == TM_STATE_ERROR){
- hd->tmState = TM_STATE_NONE;
- spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
- nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
- "TM timeout error! (sc=%p)\n",
- hd->ioc->name,
- SCpnt));
- return FAILED;
- }
- hd->tmState = TM_STATE_NONE;
- spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
-
- nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
- "Abort was successful! (sc=%p)\n",
- hd->ioc->name,
- SCpnt));
-
- return SUCCESS;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2823,7 +2798,6 @@ int
mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
- unsigned long flags;
/* If we can't locate our host adapter structure, return FAILED status.
*/
@@ -2834,10 +2808,13 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
return FAILED;
}
- printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
- hd->ioc->name, SCpnt);
- printk(KERN_WARNING MYNAM ": %s: IOs outstanding = %d\n",
- hd->ioc->name, atomic_read(&queue_depth));
+ printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p, numIOs=%d)\n",
+ hd->ioc->name, SCpnt, atomic_read(&queue_depth));
+
+ /* Unsupported for SCSI. Suppored for FCP
+ */
+ if (hd->is_spi)
+ return FAILED;
/* Wait a fixed amount of time for the TM pending flag to be cleared.
* If we time out, then we return a FAILED status to the caller. This
@@ -2853,7 +2830,7 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
}
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
- SCpnt->target, 0, 0, CAN_SLEEP)
+ SCpnt->target, 0, 0, NO_SLEEP)
< 0){
/* The TM request failed and the subsequent FW-reload failed!
* Fatal error case.
@@ -2864,34 +2841,8 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
hd->tmState = TM_STATE_NONE;
return FAILED;
}
-
- /* Our task management request will either complete or time out. So we
- * spin until tmPending is != 1. If tmState is set to TM_STATE_ERROR,
- * we encountered an error executing the task management request.
- */
- while (hd->tmPending == 1){
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ/4);
- }
- spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
- if (hd->tmState == TM_STATE_ERROR){
- hd->tmState = TM_STATE_NONE;
- spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
- nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_dev_reset: "
- "TM timeout error! (sc=%p)\n",
- hd->ioc->name,
- SCpnt));
- return FAILED;
- }
- hd->tmState = TM_STATE_NONE;
- spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
-
- nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_dev_reset: "
- "Device reset was successful! (sc=%p)\n",
- hd->ioc->name,
- SCpnt));
-
return SUCCESS;
+
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2907,7 +2858,6 @@ int
mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
- unsigned long flags;
/* If we can't locate our host adapter structure, return FAILED status.
*/
@@ -2918,10 +2868,11 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
return FAILED;
}
- printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
- hd->ioc->name, SCpnt);
- printk(KERN_WARNING MYNAM ": %s: IOs outstanding = %d\n",
- hd->ioc->name, atomic_read(&queue_depth));
+ printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p, numIOs=%d)\n",
+ hd->ioc->name, SCpnt, atomic_read(&queue_depth));
+
+ if (hd->timeouts < -1)
+ hd->timeouts++;
/* Wait a fixed amount of time for the TM pending flag to be cleared.
* If we time out, then we return a FAILED status to the caller. This
@@ -2932,13 +2883,13 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_bus_reset: "
"Timed out waiting for previous TM to complete! "
"(sc = %p)\n",
- hd->ioc->name, SCpnt ) );
+ hd->ioc->name, SCpnt));
return FAILED;
}
/* We are now ready to execute the task management request. */
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
- 0, 0, 0, CAN_SLEEP)
+ 0, 0, 0, NO_SLEEP)
< 0){
/* The TM request failed and the subsequent FW-reload failed!
@@ -2952,32 +2903,6 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
return FAILED;
}
- /* Our task management request will either complete or time out. So we
- * spin until tmPending is != 1. If tmState is set to TM_STATE_ERROR,
- * we encountered an error executing the task management request.
- */
- while (hd->tmPending == 1){
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ/4);
- }
- spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
- if (hd->tmState == TM_STATE_ERROR){
- hd->tmState = TM_STATE_NONE;
- spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
- nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_bus_reset: "
- "TM timeout error! (sc=%p)\n",
- hd->ioc->name,
- SCpnt));
- return FAILED;
- }
- hd->tmState = TM_STATE_NONE;
- spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
-
- nehprintk((KERN_WARNING MYNAM ": %s: mptscsih_bus_reset: "
- "Bus reset was successful! (sc=%p)\n",
- hd->ioc->name,
- SCpnt));
-
return SUCCESS;
}
@@ -3013,7 +2938,7 @@ mptscsih_host_reset(Scsi_Cmnd *SCpnt)
/* If our attempts to reset the host failed, then return a failed
* status. The host will be taken off line by the SCSI mid-layer.
*/
- if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
+ if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0){
status = FAILED;
} else {
/* Make sure TM pending is cleared and TM state is set to
@@ -3056,9 +2981,7 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
break;
}
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ/4);
-
+ mdelay(250);
} while (--loop_count);
return status;
@@ -3093,6 +3016,9 @@ mptscsih_old_abort(Scsi_Cmnd *SCpnt)
return SCSI_ABORT_NOT_RUNNING;
}
+ if (hd->timeouts < -1)
+ hd->timeouts++;
+
if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
/* Cmd not found in ScsiLookup.
* If found in doneQ, delete from Q.
@@ -3166,7 +3092,7 @@ mptscsih_old_abort(Scsi_Cmnd *SCpnt)
SCpnt->host_scribble = (u8 *) MPT_INDEX_2_MFPTR (hd->ioc, scpnt_idx);
/* For the time being, force bus reset on any abort
- * requests for the 1030 FW.
+ * requests for the 1030/1035 FW.
*/
if (hd->is_spi)
mf->u.frame.linkage.arg1 = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
@@ -3226,6 +3152,9 @@ mptscsih_old_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
return SCSI_RESET_SUCCESS;
}
+ if (hd->timeouts < -1)
+ hd->timeouts++;
+
if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
/* Cmd not found in ScsiLookup.
* If found in doneQ, delete from Q.
@@ -3583,9 +3512,6 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
}
}
}
-#ifdef MPT_SCSI_USE_NEW_EH
- hd->tmState = TM_STATE_ERROR;
-#endif
} else {
dtmprintk((KERN_INFO " SCSI TaskMgmt SUCCESS!\n"));
@@ -3629,6 +3555,9 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
spin_lock_irqsave(&ioc->FreeQlock, flags);
hd->tmPending = 0;
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+#ifdef MPT_SCSI_USE_NEW_EH
+ hd->tmState = TM_STATE_NONE;
+#endif
return 1;
}
@@ -3638,14 +3567,18 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
* This is anyones guess quite frankly.
*/
int
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)
mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
sector_t capacity, int *ip)
{
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28)
+mptscsih_bios_param(Disk * disk, struct block_device *bdev, int *ip)
+{
+ sector_t capacity = disk->capacity;
#else
mptscsih_bios_param(Disk * disk, kdev_t dev, int *ip)
{
- sector_t capacity = disk->capacity;
+ unsigned capacity = disk->capacity;
#endif
int size;
@@ -3666,20 +3599,63 @@ mptscsih_bios_param(Disk * disk, kdev_t dev, int *ip)
* Called once per device the bus scan. Use it to force the queue_depth
* member to 1 if a device does not support Q tags.
*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44)
int
mptscsih_slave_configure(Scsi_Device *device)
{
+ struct Scsi_Host *host = device->host;
VirtDevice *pTarget;
- pTarget = device->hostdata;
- if (!device->tagged_supported ||
- !(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) {
- scsi_adjust_queue_depth(device, 0, 1);
- } else {
- scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
- device->host->can_queue >> 1);
+ MPT_SCSI_HOST *hd;
+
+ hd = (MPT_SCSI_HOST *)host->hostdata;
+ if (hd && (hd->Targets != NULL)) {
+ pTarget = hd->Targets[device->id];
+ if (pTarget) {
+ if (!device->tagged_supported ||
+ !(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) {
+ scsi_adjust_queue_depth(device, 0, 1);
+ } else {
+ scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
+ device->host->can_queue >> 1);
+ }
+ }
}
return 0;
}
+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44) */
+void
+mptscsih_select_queue_depths(struct Scsi_Host *sh, Scsi_Device *sdList)
+{
+ struct scsi_device *device;
+ VirtDevice *pTarget;
+ MPT_SCSI_HOST *hd;
+ int ii, max;
+
+ for (device = sdList; device != NULL; device = device->next) {
+
+ if (device->host != sh)
+ continue;
+
+ hd = (MPT_SCSI_HOST *) sh->hostdata;
+ if (hd == NULL)
+ continue;
+
+ if (hd->Targets != NULL) {
+ if (hd->is_spi)
+ max = MPT_MAX_SCSI_DEVICES;
+ else
+ max = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
+
+ for (ii=0; ii < max; ii++) {
+ pTarget = hd->Targets[ii];
+ if (pTarget && !(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) {
+ device->queue_depth = 1;
+ }
+ }
+ }
+ }
+}
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44) */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
@@ -4126,6 +4102,9 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
hd->resetPending = 0;
hd->numTMrequests = 0;
+#ifdef MPT_SCSI_USE_NEW_EH
+ hd->tmState = TM_STATE_NONE;
+#endif
/* 6. If there was an internal command,
* wake this process up.
@@ -4167,10 +4146,13 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
/* FIXME! */
break;
case MPI_EVENT_IOC_BUS_RESET: /* 04 */
- /* FIXME! */
- break;
case MPI_EVENT_EXT_BUS_RESET: /* 05 */
- /* FIXME! */
+ hd = NULL;
+ if (ioc->sh) {
+ hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
+ if (hd && (hd->is_spi) && (hd->soft_resets < -1))
+ hd->soft_resets++;
+ }
break;
case MPI_EVENT_LOGOUT: /* 09 */
/* FIXME! */
@@ -4804,9 +4786,10 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
}
if (vdev) {
- if (hd->ioc->spi_data.isRaid & (1 << target_id))
+ if (hd->ioc->spi_data.isRaid & (1 << target_id)) {
vdev->raidVolume = 1;
- else
+ ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", target_id));
+ } else
vdev->raidVolume = 0;
}
@@ -4868,6 +4851,8 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
u8 version, nfactor;
u8 noQas = 1;
+ ddvtprintk((KERN_INFO "set Target: (id %d) byte56 0x%x\n", id, byte56));
+
/* Set flags based on Inquiry data
*/
if (target->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
@@ -4886,12 +4871,18 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
*/
if ((byte56 & 0x04) == 0)
factor = MPT_ULTRA2;
+ else if ((byte56 & 0x03) == 0)
+ factor = MPT_ULTRA160;
else
factor = MPT_ULTRA320;
- /* bit 1 QAS support, non-raid only
+ /* If RAID, never disable QAS
+ * else if non RAID, do not disable
+ * QAS if bit 1 is set
+ * bit 1 QAS support, non-raid only
+ * bit 0 IU support
*/
- if ((target->raidVolume == 0) && (byte56 & 0x02) != 0)
+ if ((target->raidVolume == 1) || ((byte56 & 0x02) != 0))
noQas = 0;
offset = pspi_data->maxSyncOffset;
@@ -4976,6 +4967,7 @@ void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byt
VirtDevice *vdev;
int ii;
+ ddvtprintk((KERN_INFO "Disabling QAS!\n"));
pspi_data->noQas = MPT_TARGET_NO_NEGO_QAS;
for (ii = 0; ii < id; ii++) {
vdev = hd->Targets[id];
@@ -5204,6 +5196,17 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
//negoFlags = MPT_TARGET_NO_NEGO_SYNC;
}
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+ /* Force to async and narrow if DV has not been executed
+ * for this ID
+ */
+ if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
+ width = 0;
+ factor = MPT_ASYNC;
+ offset = 0;
+ }
+#endif
+
/* If id is not a raid volume, get the updated
* transmission settings from the target structure.
*/
@@ -5313,13 +5316,6 @@ static void mptscsih_taskmgmt_timeout(unsigned long data)
*/
del_timer(&hd->TMtimer);
-#ifdef MPT_SCSI_USE_NEW_EH
- /* Set the error flag to 1 so that the function that started the
- * task management request knows it timed out.
- */
- hd->tmState = TM_STATE_ERROR;
-#endif
-
/* Call the reset handler. Already had a TM request
* timeout - so issue a diagnostic reset
*/
@@ -5853,6 +5849,12 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
else
pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
+ if (cmd == CMD_RequestSense) {
+ pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
+ ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
+ hd->ioc->name, cmd));
+ }
+
for (ii=0; ii < 16; ii++)
pScsiReq->CDB[ii] = CDB[ii];
@@ -6184,7 +6186,7 @@ mptscsih_domainValidation(void *arg)
post_pendingQ_commands(hd);
if (hd->ioc->spi_data.noQas)
- mptscsih_qas_check(hd);
+ mptscsih_qas_check(hd, id);
}
}
}
@@ -6218,7 +6220,7 @@ static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
/* Write SDP1 if no QAS has been enabled
*/
-static void mptscsih_qas_check(MPT_SCSI_HOST *hd)
+static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
{
VirtDevice *pTarget = NULL;
int ii;
@@ -6227,6 +6229,9 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd)
return;
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
+ if (ii == id)
+ continue;
+
if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
continue;
@@ -6510,6 +6515,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int portnum, int id)
rc = hd->pLocal->completion;
if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
dv.max.width = 0;
+ doFallback = 0;
} else
goto target_done;
}
@@ -7059,6 +7065,10 @@ target_done:
dv.cmd = MPT_SAVE;
mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
+#if 0
+ /* Double writes to SDP1 can cause problems,
+ * skip here since unnecessary
+ */
/* Save the final negotiated settings to
* SCSI device page 1.
*/
@@ -7067,13 +7077,14 @@ target_done:
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
cfg.dir = 1;
mpt_config(hd->ioc, &cfg);
+#endif
}
/* If this is a RAID Passthrough, enable internal IOs
*/
if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
- ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
+ ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
}
/* Done with the DV scan of the current target
@@ -7227,8 +7238,7 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
pPage1->Configuration = le32_to_cpu(configuration);
}
ddvprintk(("width %d, factor %x, offset %x request %x config %x\n",
- dv->now.width, dv->now.factor,
- dv->now.offset, val, configuration));
+ width, factor, offset, val, configuration));
break;
case MPT_FALLBACK:
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index bf6bf05a5943..885a1a55c0f1 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -20,7 +20,7 @@
* (mailto:netscape.net)
* (mailto:Pam.Delaney@lsil.com)
*
- * $Id: mptscsih.h,v 1.19 2002/10/03 13:10:15 pdelaney Exp $
+ * $Id: mptscsih.h,v 1.20 2002/10/17 20:16:00 pdelaney Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
@@ -230,7 +230,10 @@ extern int x_scsi_old_abort(Scsi_Cmnd *);
extern int x_scsi_old_reset(Scsi_Cmnd *, unsigned int);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)
-extern int x_scsi_bios_param(Scsi_Device *, struct block_device *, sector_t, int[]);
+extern int x_scsi_bios_param(struct scsi_device * sdev, struct block_device *bdev,
+ sector_t capacity, int *ip);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28)
+extern int x_scsi_bios_param(Disk *, struct block_device *, int *);
#else
extern int x_scsi_bios_param(Disk *, kdev_t, int *);
#endif
@@ -245,7 +248,7 @@ extern void x_scsi_taskmgmt_bh(void *);
#ifdef MPT_SCSI_USE_NEW_EH
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,44)
#define MPT_SCSIHOST { \
PROC_SCSI_DECL \
@@ -253,8 +256,6 @@ extern void x_scsi_taskmgmt_bh(void *);
.detect = x_scsi_detect, \
.release = x_scsi_release, \
.info = x_scsi_info, \
- .queuecommand = x_scsi_queuecommand, \
- .slave_configure = x_scsi_slave_configure,\
.eh_abort_handler = x_scsi_abort, \
.eh_device_reset_handler = x_scsi_dev_reset, \
.eh_bus_reset_handler = x_scsi_bus_reset, \
@@ -265,26 +266,32 @@ extern void x_scsi_taskmgmt_bh(void *);
.sg_tablesize = MPT_SCSI_SG_DEPTH, \
.max_sectors = MPT_SCSI_MAX_SECTORS, \
.cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \
+ .unchecked_isa_dma = 0, \
.use_clustering = ENABLE_CLUSTERING, \
}
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) */
#define MPT_SCSIHOST { \
+ .next = NULL, \
PROC_SCSI_DECL \
.name = "MPT SCSI Host", \
.detect = x_scsi_detect, \
.release = x_scsi_release, \
.info = x_scsi_info, \
+ .command = NULL, \
.queuecommand = x_scsi_queuecommand, \
+ .eh_strategy_handler = NULL, \
.eh_abort_handler = x_scsi_abort, \
.eh_device_reset_handler = x_scsi_dev_reset, \
.eh_bus_reset_handler = x_scsi_bus_reset, \
+ .eh_host_reset_handler = NULL, \
.bios_param = x_scsi_bios_param, \
.can_queue = MPT_SCSI_CAN_QUEUE, \
.this_id = -1, \
.sg_tablesize = MPT_SCSI_SG_DEPTH, \
.cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \
+ .unchecked_isa_dma = 0, \
.use_clustering = ENABLE_CLUSTERING, \
.use_new_eh_code = 1 \
}
@@ -294,11 +301,13 @@ extern void x_scsi_taskmgmt_bh(void *);
#else /* MPT_SCSI_USE_NEW_EH */
#define MPT_SCSIHOST { \
+ .next = NULL, \
PROC_SCSI_DECL \
.name = "MPT SCSI Host", \
.detect = x_scsi_detect, \
.release = x_scsi_release, \
.info = x_scsi_info, \
+ .command = NULL, \
.queuecommand = x_scsi_queuecommand, \
.abort = x_scsi_old_abort, \
.reset = x_scsi_old_reset, \
@@ -307,6 +316,7 @@ extern void x_scsi_taskmgmt_bh(void *);
.this_id = -1, \
.sg_tablesize = MPT_SCSI_SG_DEPTH, \
.cmd_per_lun = MPT_SCSI_CMD_PER_LUN, \
+ .unchecked_isa_dma = 0, \
.use_clustering = ENABLE_CLUSTERING \
}
#endif /* MPT_SCSI_USE_NEW_EH */
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 718cd1a7caab..05406290dde8 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -1669,7 +1669,6 @@ static int i2o_block_init(void)
if(i2o_install_handler(&i2o_block_handler)<0)
{
unregister_blkdev(MAJOR_NR, "i2o_block");
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
printk(KERN_ERR "i2o_block: unable to register OSM.\n");
return -EINVAL;
}
@@ -1682,8 +1681,7 @@ static int i2o_block_init(void)
evt_pid = kernel_thread(i2ob_evt, NULL, CLONE_SIGHAND);
if(evt_pid < 0)
{
- printk(KERN_ERR
- "i2o_block: Could not initialize event thread. Aborting\n");
+ printk(KERN_ERR "i2o_block: Could not initialize event thread. Aborting\n");
i2o_remove_handler(&i2o_block_handler);
return 0;
}
diff --git a/drivers/message/i2o/i2o_core.c b/drivers/message/i2o/i2o_core.c
index 4c3703eaf7ac..418b2dcd930c 100644
--- a/drivers/message/i2o/i2o_core.c
+++ b/drivers/message/i2o/i2o_core.c
@@ -3344,6 +3344,9 @@ void i2o_report_status(const char *severity, const char *str, u32 *msg)
u16 detailed_status = msg[4]&0xFFFF;
struct i2o_handler *h = i2o_handlers[msg[2] & (MAX_I2O_MODULES-1)];
+ if (cmd == I2O_CMD_UTIL_EVT_REGISTER)
+ return; // No status in this reply
+
printk("%s%s: ", severity, str);
if (cmd < 0x1F) // Utility cmd
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
index 7d47996701b3..a76576c42d91 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/message/i2o/i2o_scsi.c
@@ -57,7 +57,6 @@
#include <linux/i2o.h>
#include "../../scsi/scsi.h"
#include "../../scsi/hosts.h"
-#include "../../scsi/sd.h"
#if BITS_PER_LONG == 64
#error FIXME: driver does not support 64-bit platforms
@@ -918,6 +917,7 @@ int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
unsigned long msg;
u32 m;
int tid;
+ unsigned long timeout;
printk(KERN_WARNING "i2o_scsi: Aborting command block.\n");
@@ -930,21 +930,21 @@ int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
return FAILED;
}
c = hostdata->controller;
-
- /*
- * Obtain an I2O message. Right now we _have_ to obtain one
- * until the scsi layer stuff is cleaned up.
- *
- * FIXME: we are in error context so we could sleep retry
- * a bit and then bail in the improved scsi layer.
- */
-
+
+ spin_unlock_irq(host->host_lock);
+
+ timeout = jiffies+2*HZ;
do
{
- mb();
m = le32_to_cpu(I2O_POST_READ32(c));
+ if(m != 0xFFFFFFFF)
+ break;
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1);
+ mb();
}
- while(m==0xFFFFFFFF);
+ while(time_before(jiffies, timeout));
+
msg = c->mem_offset + m;
i2o_raw_writel(FIVE_WORD_MSG_SIZE, msg);
@@ -955,6 +955,8 @@ int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
wmb();
i2o_post_message(c,m);
wmb();
+
+ spin_lock_irq(host->host_lock);
return SUCCESS;
}
@@ -977,14 +979,20 @@ static int i2o_scsi_bus_reset(Scsi_Cmnd * SCpnt)
struct i2o_scsi_host *hostdata;
u32 m;
unsigned long msg;
+ unsigned long timeout;
+
/*
* Find the TID for the bus
*/
- printk(KERN_WARNING "i2o_scsi: Attempting to reset the bus.\n");
host = SCpnt->host;
+
+ spin_unlock_irq(host->host_lock);
+
+ printk(KERN_WARNING "i2o_scsi: Attempting to reset the bus.\n");
+
hostdata = (struct i2o_scsi_host *)host->hostdata;
tid = hostdata->bus_task;
c = hostdata->controller;
@@ -994,15 +1002,19 @@ static int i2o_scsi_bus_reset(Scsi_Cmnd * SCpnt)
* will be aborted by the IOP. We need to catch the reply
* possibly ?
*/
-
- m = le32_to_cpu(I2O_POST_READ32(c));
+
+ timeout = jiffies+2*HZ;
+ do
+ {
+ m = le32_to_cpu(I2O_POST_READ32(c));
+ if(m != 0xFFFFFFFF)
+ break;
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1);
+ mb();
+ }
+ while(time_before(jiffies, timeout));
- /*
- * No free messages, try again next time - no big deal
- */
-
- if(m == 0xFFFFFFFF)
- return SCSI_RESET_PUNT;
msg = c->mem_offset + m;
i2o_raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, msg);
@@ -1012,7 +1024,12 @@ static int i2o_scsi_bus_reset(Scsi_Cmnd * SCpnt)
/* Now store unit,tid so we can tie the completion back to a specific device */
__raw_writel(c->unit << 16 | tid, msg+12);
wmb();
+
+ /* We want the command to complete after we return */
+ spin_lock_irq(host->host_lock);
i2o_post_message(c,m);
+
+ /* Should we wait for the reset to complete ? */
return SUCCESS;
}
@@ -1044,8 +1061,9 @@ static int i2o_scsi_device_reset(Scsi_Cmnd * SCpnt)
/**
* i2o_scsi_bios_param - Invent disk geometry
- * @disk: device
+ * @sdev: scsi device
* @dev: block layer device
+ * @capacity: size in sectors
* @ip: geometry array
*
* This is anyones guess quite frankly. We use the same rules everyone
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index 789006ac1510..a31ceb3bdb3e 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -90,7 +90,7 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
dev->base_addr = ioaddr;
dev->irq = pdev->irq;
dev->dev_addr[0] = node;
- lp->card_name = pdev->name;
+ lp->card_name = pdev->dev.name;
lp->card_flags = id->driver_data;
lp->backplane = backplane;
lp->clockp = clockp & 7;
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 9ea30cca00b7..0f11ddb16ff6 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -463,8 +463,6 @@ static int load_packet(struct net_device *dev, struct sk_buff *skb);
static void depca_dbg_open(struct net_device *dev);
#ifdef MODULE
-int init_module(void);
-void cleanup_module(void);
static int autoprobed = 1, loading_module = 1;
# else
static u_char de1xx_irq[] __initdata = { 2, 3, 4, 5, 7, 9, 0 };
diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
index dc51c05ee036..3498d35bbeb2 100644
--- a/drivers/net/ewrk3.c
+++ b/drivers/net/ewrk3.c
@@ -332,8 +332,6 @@ static struct net_device *insert_device(struct net_device *dev, u_long iobase, i
#ifdef MODULE
-int init_module(void);
-void cleanup_module(void);
static int autoprobed = 1, loading_module = 1;
#else
@@ -2083,7 +2081,25 @@ MODULE_PARM(irq, "0-21i");
MODULE_PARM_DESC(io, "EtherWORKS 3 I/O base address(es)");
MODULE_PARM_DESC(irq, "EtherWORKS 3 IRQ number(s)");
-int init_module(void)
+static void ewrk3_exit_module(void)
+{
+ int i;
+
+ for( i=0; i<ndevs; i++ ) {
+ unregister_netdev(ewrk3_devs[i]);
+ if (ewrk3_devs[i]->priv) {
+ kfree(ewrk3_devs[i]->priv);
+ ewrk3_devs[i]->priv = NULL;
+ }
+ ewrk3_devs[i]->irq = 0;
+
+ release_region(ewrk3_devs[i]->base_addr, EWRK3_TOTAL_SIZE);
+ kfree(ewrk3_devs[i]);
+ ewrk3_devs[i] = NULL;
+ }
+}
+
+static int ewrk3_init_module(void)
{
int i=0;
@@ -2107,27 +2123,14 @@ int init_module(void)
return ndevs ? 0 : -EIO;
error:
- cleanup_module();
+ ewrk3_exit_module();
return -ENOMEM;
}
-void cleanup_module(void)
-{
- int i;
-
- for( i=0; i<ndevs; i++ ) {
- unregister_netdev(ewrk3_devs[i]);
- if (ewrk3_devs[i]->priv) {
- kfree(ewrk3_devs[i]->priv);
- ewrk3_devs[i]->priv = NULL;
- }
- ewrk3_devs[i]->irq = 0;
- release_region(ewrk3_devs[i]->base_addr, EWRK3_TOTAL_SIZE);
- kfree(ewrk3_devs[i]);
- ewrk3_devs[i] = NULL;
- }
-}
+/* Hack for breakage in new module stuff */
+module_exit(ewrk3_exit_module);
+module_init(ewrk3_init_module);
#endif /* MODULE */
MODULE_LICENSE("GPL");
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index 7ed43e75d0a7..8684da87f9ca 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -185,120 +185,6 @@ config BAYCOM_EPP
say M here and read <file:Documentation/modules.txt>. This is
recommended. The module will be called baycom_par.o.
-config SOUNDMODEM
- tristate "Soundcard modem driver"
- depends on PARPORT && AX25
- ---help---
- This experimental driver allows a standard Sound Blaster or
- WindowsSoundSystem compatible sound card to be used as a packet
- radio modem (NOT as a telephone modem!), to send digital traffic
- over amateur radio.
-
- To configure the driver, use the sethdlc, smdiag and smmixer
- utilities available in the standard ax25 utilities package. For
- information on how to key the transmitter, see
- <http://www.ife.ee.ethz.ch/~sailer/pcf/ptt_circ/ptt.html> and
- <file:Documentation/networking/soundmodem.txt>.
-
- If you want to compile this driver as a module ( = code which can be
- inserted in and removed from the running kernel whenever you want),
- say M here and read <file:Documentation/modules.txt>. This is
- recommended. The module will be called soundmodem.o.
-
-config SOUNDMODEM_SBC
- bool "soundmodem support for Soundblaster and compatible cards"
- depends on SOUNDMODEM
- help
- This option enables the soundmodem driver to use Sound Blaster and
- compatible cards. If you have a dual mode card (i.e. a WSS cards
- with a Sound Blaster emulation) you should say N here and Y to
- "Sound card modem support for WSS and Crystal cards", below, because
- this usually results in better performance. This option also
- supports SB16/32/64 in full-duplex mode.
-
-config SOUNDMODEM_WSS
- bool "soundmodem support for WSS and Crystal cards"
- depends on SOUNDMODEM
- help
- This option enables the soundmodem driver to use WindowsSoundSystem
- compatible cards. These cards feature a codec chip from either
- Analog Devices (such as AD1848, AD1845, AD1812) or Crystal
- Semiconductors (such as CS4248, CS423x). This option also supports
- the WSS full-duplex operation which currently works with Crystal
- CS423x chips. If you don't need full-duplex operation, do not enable
- it to save performance.
-
-config SOUNDMODEM_AFSK1200
- bool "soundmodem support for 1200 baud AFSK modulation"
- depends on SOUNDMODEM
- help
- This option enables the soundmodem driver 1200 baud AFSK modem,
- compatible to popular modems using TCM3105 or AM7911. The
- demodulator requires about 12% of the CPU power of a Pentium 75 CPU
- per channel.
-
-config SOUNDMODEM_AFSK2400_7
- bool "soundmodem support for 2400 baud AFSK modulation (7.3728MHz crystal)"
- depends on SOUNDMODEM
- help
- This option enables the soundmodem driver 2400 baud AFSK modem,
- compatible to TCM3105 modems (over-)clocked with a 7.3728MHz
- crystal. Note that the availability of this driver does _not_ imply
- that I recommend building such links. It is only here since users
- especially in eastern Europe have asked me to do so. In fact this
- modulation scheme has many disadvantages, mainly its incompatibility
- with many transceiver designs and the fact that the TCM3105 (if
- used) is operated widely outside its specifications.
-
-config SOUNDMODEM_AFSK2400_8
- bool "soundmodem support for 2400 baud AFSK modulation (8MHz crystal)"
- depends on SOUNDMODEM
- help
- This option enables the soundmodem driver 2400 baud AFSK modem,
- compatible to TCM3105 modems (over-)clocked with an 8MHz crystal.
- Note that the availability of this driver does _not_ imply that I
- recommend building such links. It is only here since users
- especially in eastern Europe have asked me to do so. In fact this
- modulation scheme has many disadvantages, mainly its incompatibility
- with many transceiver designs and the fact that the TCM3105 (if
- used) is operated widely outside its specifications.
-
-config SOUNDMODEM_AFSK2666
- bool "soundmodem support for 2666 baud AFSK modulation"
- depends on SOUNDMODEM
- help
- This option enables the soundmodem driver 2666 baud AFSK modem.
- This modem is experimental, and not compatible to anything
- else I know of.
-
-config SOUNDMODEM_HAPN4800
- bool "soundmodem support for 4800 baud HAPN-1 modulation"
- depends on SOUNDMODEM
- help
- This option enables the soundmodem driver 4800 baud HAPN-1
- compatible modem. This modulation seems to be widely used 'down
- under' and in the Netherlands. Here, nobody uses it, so I could not
- test if it works. It is compatible to itself, however :-)
-
-config SOUNDMODEM_PSK4800
- bool "soundmodem support for 4800 baud PSK modulation"
- depends on SOUNDMODEM
- help
- This option enables the soundmodem driver 4800 baud 8PSK modem.
- This modem is experimental, and not compatible to anything
- else I know of.
-
-config SOUNDMODEM_FSK9600
- bool "soundmodem support for 9600 baud FSK G3RUH modulation"
- depends on SOUNDMODEM
- help
- This option enables the soundmodem driver 9600 baud FSK modem,
- compatible to the G3RUH standard. The demodulator requires about 4%
- of the CPU power of a Pentium 75 CPU per channel. You can say Y to
- both 1200 baud AFSK and 9600 baud FSK if you want (but obviously you
- can only use one protocol at a time, depending on what the other end
- can understand).
-
config YAM
tristate "YAM driver for AX.25"
depends on AX25
diff --git a/drivers/net/hamradio/Makefile b/drivers/net/hamradio/Makefile
index 60a189f9fde0..ccb63d339190 100644
--- a/drivers/net/hamradio/Makefile
+++ b/drivers/net/hamradio/Makefile
@@ -22,6 +22,5 @@ obj-$(CONFIG_BAYCOM_SER_FDX) += baycom_ser_fdx.o hdlcdrv.o
obj-$(CONFIG_BAYCOM_SER_HDX) += baycom_ser_hdx.o hdlcdrv.o
obj-$(CONFIG_BAYCOM_PAR) += baycom_par.o hdlcdrv.o
obj-$(CONFIG_BAYCOM_EPP) += baycom_epp.o hdlcdrv.o
-obj-$(CONFIG_SOUNDMODEM) += soundmodem/ hdlcdrv.o
include $(TOPDIR)/Rules.make
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 9df09579092d..2d8c089d5c93 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -54,7 +54,6 @@
#include <linux/kmod.h>
#include <linux/hdlcdrv.h>
#include <linux/baycom.h>
-#include <linux/soundmodem.h>
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
/* prototypes for ax25_encapsulate and ax25_rebuild_header */
#include <net/ax25.h>
@@ -1200,7 +1199,6 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
struct baycom_state *bc;
struct baycom_ioctl bi;
struct hdlcdrv_ioctl hi;
- struct sm_ioctl si;
baycom_paranoia_check(dev, "baycom_ioctl", -EINVAL);
bc = (struct baycom_state *)dev->priv;
@@ -1208,28 +1206,6 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -ENOIOCTLCMD;
if (get_user(cmd, (int *)ifr->ifr_data))
return -EFAULT;
-#ifdef BAYCOM_DEBUG
- if (cmd == BAYCOMCTL_GETDEBUG) {
- bi.data.dbg.debug1 = bc->ptt_keyed;
- bi.data.dbg.debug2 = bc->debug_vals.last_intcnt;
- bi.data.dbg.debug3 = bc->debug_vals.last_pllcorr;
- bc->debug_vals.last_intcnt = 0;
- if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
- return -EFAULT;
- return 0;
- }
- if (cmd == SMCTL_GETDEBUG) {
- si.data.dbg.int_rate = bc->debug_vals.last_intcnt;
- si.data.dbg.mod_cycles = bc->debug_vals.mod_cycles;
- si.data.dbg.demod_cycles = bc->debug_vals.demod_cycles;
- si.data.dbg.dma_residue = 0;
- bc->debug_vals.mod_cycles = bc->debug_vals.demod_cycles = 0;
- bc->debug_vals.last_intcnt = 0;
- if (copy_to_user(ifr->ifr_data, &si, sizeof(si)))
- return -EFAULT;
- return 0;
- }
-#endif /* BAYCOM_DEBUG */
if (copy_from_user(&hi, ifr->ifr_data, sizeof(hi)))
return -EFAULT;
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index 551d06f46d4d..b8d04451e34f 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -235,6 +235,8 @@ struct scc_priv {
int state;
unsigned long tx_start;
int rr0;
+ spinlock_t *register_lock; /* Per scc_info */
+ spinlock_t ring_lock;
};
struct scc_info {
@@ -243,6 +245,7 @@ struct scc_info {
struct net_device dev[2];
struct scc_priv priv[2];
struct scc_info *next;
+ spinlock_t register_lock; /* Per device register lock */
};
@@ -371,7 +374,7 @@ int __init dmascc_init(void) {
/* Cards found = 0 */
n = 0;
/* Warning message */
- if (!io[0]) printk("dmascc: autoprobing (dangerous)\n");
+ if (!io[0]) printk(KERN_INFO "dmascc: autoprobing (dangerous)\n");
/* Run autodetection for each card type */
for (h = 0; h < NUM_TYPES; h++) {
@@ -456,7 +459,7 @@ int __init dmascc_init(void) {
if (n) return 0;
/* If no adapter found, return error */
- printk("dmascc: no adapters found\n");
+ printk(KERN_INFO "dmascc: no adapters found\n");
return -EIO;
}
@@ -475,18 +478,21 @@ int __init setup_adapter(int card_base, int type, int n) {
/* Allocate memory */
info = kmalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA);
if (!info) {
- printk("dmascc: could not allocate memory for %s at %#3x\n",
+ printk(KERN_ERR "dmascc: could not allocate memory for %s at %#3x\n",
hw[type].name, card_base);
return -1;
}
/* Initialize what is necessary for write_scc and write_scc_data */
memset(info, 0, sizeof(struct scc_info));
+ spin_lock_init(&info->register_lock);
+
priv = &info->priv[0];
priv->type = type;
priv->card_base = card_base;
priv->scc_cmd = scc_base + SCCA_CMD;
priv->scc_data = scc_base + SCCA_DATA;
+ priv->register_lock = &info->register_lock;
/* Reset SCC */
write_scc(priv, R9, FHWRES | MIE | NV);
@@ -510,7 +516,6 @@ int __init setup_adapter(int card_base, int type, int n) {
write_scc(priv, R15, 0);
/* Start IRQ auto-detection */
- sti();
irqs = probe_irq_on();
/* Enable interrupts */
@@ -543,7 +548,7 @@ int __init setup_adapter(int card_base, int type, int n) {
}
if (irq <= 0) {
- printk("dmascc: could not find irq of %s at %#3x (irq=%d)\n",
+ printk(KERN_ERR "dmascc: could not find irq of %s at %#3x (irq=%d)\n",
hw[type].name, card_base, irq);
kfree(info);
return -1;
@@ -558,6 +563,8 @@ int __init setup_adapter(int card_base, int type, int n) {
priv->dev = dev;
priv->info = info;
priv->channel = i;
+ spin_lock_init(&priv->ring_lock);
+ priv->register_lock = &info->register_lock;
priv->card_base = card_base;
priv->scc_cmd = scc_base + (i ? SCCB_CMD : SCCA_CMD);
priv->scc_data = scc_base + (i ? SCCB_DATA : SCCA_DATA);
@@ -594,7 +601,7 @@ int __init setup_adapter(int card_base, int type, int n) {
memcpy(dev->dev_addr, ax25_test, 7);
rtnl_lock();
if (register_netdevice(dev)) {
- printk("dmascc: could not register %s\n", dev->name);
+ printk(KERN_ERR "dmascc: could not register %s\n", dev->name);
}
rtnl_unlock();
}
@@ -603,7 +610,7 @@ int __init setup_adapter(int card_base, int type, int n) {
info->next = first;
first = info;
- printk("dmascc: found %s (%s) at %#3x, irq %d\n", hw[type].name,
+ printk(KERN_INFO "dmascc: found %s (%s) at %#3x, irq %d\n", hw[type].name,
chipnames[chip], card_base, irq);
return 0;
}
@@ -623,13 +630,12 @@ static void write_scc(struct scc_priv *priv, int reg, int val) {
outb_p(val, priv->scc_cmd);
return;
default:
- save_flags(flags);
- cli();
+ spin_lock_irqsave(priv->register_lock, flags);
outb_p(0, priv->card_base + PI_DREQ_MASK);
if (reg) outb_p(reg, priv->scc_cmd);
outb_p(val, priv->scc_cmd);
outb(1, priv->card_base + PI_DREQ_MASK);
- restore_flags(flags);
+ spin_unlock_irqrestore(priv->register_lock, flags);
return;
}
}
@@ -647,12 +653,11 @@ static void write_scc_data(struct scc_priv *priv, int val, int fast) {
default:
if (fast) outb_p(val, priv->scc_data);
else {
- save_flags(flags);
- cli();
+ spin_lock_irqsave(priv->register_lock, flags);
outb_p(0, priv->card_base + PI_DREQ_MASK);
outb_p(val, priv->scc_data);
outb(1, priv->card_base + PI_DREQ_MASK);
- restore_flags(flags);
+ spin_unlock_irqrestore(priv->register_lock, flags);
}
return;
}
@@ -670,13 +675,12 @@ static int read_scc(struct scc_priv *priv, int reg) {
if (reg) outb_p(reg, priv->scc_cmd);
return inb_p(priv->scc_cmd);
default:
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&priv->register_lock, flags);
outb_p(0, priv->card_base + PI_DREQ_MASK);
if (reg) outb_p(reg, priv->scc_cmd);
rc = inb_p(priv->scc_cmd);
outb(1, priv->card_base + PI_DREQ_MASK);
- restore_flags(flags);
+ spin_unlock_irqrestore(priv->register_lock, flags);
return rc;
}
}
@@ -691,12 +695,11 @@ static int read_scc_data(struct scc_priv *priv) {
case TYPE_TWIN:
return inb_p(priv->scc_data);
default:
- save_flags(flags);
- cli();
+ spin_lock_irqsave(priv->register_lock, flags);
outb_p(0, priv->card_base + PI_DREQ_MASK);
rc = inb_p(priv->scc_data);
outb(1, priv->card_base + PI_DREQ_MASK);
- restore_flags(flags);
+ spin_unlock_irqrestore(priv->register_lock, flags);
return rc;
}
}
@@ -905,9 +908,8 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev) {
priv->tx_len[i] = skb->len-1;
/* Clear interrupts while we touch our circular buffers */
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&priv->ring_lock, flags);
/* Move the ring buffer's head */
priv->tx_head = (i + 1) % NUM_TX_BUF;
priv->tx_count++;
@@ -928,7 +930,7 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev) {
}
/* Turn interrupts back on and free buffer */
- restore_flags(flags);
+ spin_unlock_irqrestore(&priv->ring_lock, flags);
dev_kfree_skb(skb);
return 0;
@@ -951,6 +953,7 @@ static int scc_set_mac_address(struct net_device *dev, void *sa) {
static void scc_isr(int irq, void *dev_id, struct pt_regs * regs) {
struct scc_info *info = dev_id;
+ spin_lock(info->priv[0].register_lock);
/* At this point interrupts are enabled, and the interrupt under service
is already acknowledged, but masked off.
@@ -978,6 +981,7 @@ static void scc_isr(int irq, void *dev_id, struct pt_regs * regs) {
}
}
} else z8530_isr(info);
+ spin_unlock(info->priv[0].register_lock);
}
@@ -1002,7 +1006,7 @@ static inline void z8530_isr(struct scc_info *info) {
i++;
}
if (i < 0) {
- printk("dmascc: stuck in ISR with RR3=0x%02x.\n", is);
+ printk(KERN_ERR "dmascc: stuck in ISR with RR3=0x%02x.\n", is);
}
/* Ok, no interrupts pending from this 8530. The INT line should
be inactive now. */
@@ -1099,11 +1103,9 @@ static void rx_bh(void *arg) {
struct sk_buff *skb;
unsigned char *data;
- save_flags(flags);
- cli();
-
+ spin_lock_irqsave(&priv->ring_lock, flags);
while (priv->rx_count) {
- restore_flags(flags);
+ spin_unlock_irqrestore(&priv->ring_lock, flags);
cb = priv->rx_len[i];
/* Allocate buffer */
skb = dev_alloc_skb(cb+1);
@@ -1123,14 +1125,12 @@ static void rx_bh(void *arg) {
priv->stats.rx_packets++;
priv->stats.rx_bytes += cb;
}
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&priv->ring_lock, flags);
/* Move tail */
priv->rx_tail = i = (i + 1) % NUM_RX_BUF;
priv->rx_count--;
}
-
- restore_flags(flags);
+ spin_unlock_irqrestore(&priv->ring_lock, flags);
}
@@ -1319,12 +1319,11 @@ static inline void tx_on(struct scc_priv *priv) {
else
write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN | WT_RDY_ENAB);
/* Write first byte(s) */
- save_flags(flags);
- cli();
+ spin_lock_irqsave(priv->register_lock, flags);
for (i = 0; i < n; i++)
write_scc_data(priv, priv->tx_buf[priv->tx_tail][i], 1);
enable_dma(priv->param.dma);
- restore_flags(flags);
+ spin_unlock_irqrestore(priv->register_lock, flags);
} else {
write_scc(priv, R15, TxUIE);
write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN | TxINT_ENAB);
diff --git a/drivers/net/hamradio/soundmodem/Makefile b/drivers/net/hamradio/soundmodem/Makefile
deleted file mode 100644
index 1922038ea574..000000000000
--- a/drivers/net/hamradio/soundmodem/Makefile
+++ /dev/null
@@ -1,42 +0,0 @@
-#
-# Makefile for the soundmodem device driver.
-#
-
-obj-$(CONFIG_SOUNDMODEM) += soundmodem.o
-
-soundmodem-y := sm.o
-soundmodem-$(CONFIG_SOUNDMODEM_SBC) += sm_sbc.o
-soundmodem-$(CONFIG_SOUNDMODEM_WSS) += sm_wss.o
-soundmodem-$(CONFIG_SOUNDMODEM_AFSK1200) += sm_afsk1200.o
-soundmodem-$(CONFIG_SOUNDMODEM_AFSK2400_7) += sm_afsk2400_7.o
-soundmodem-$(CONFIG_SOUNDMODEM_AFSK2400_8) += sm_afsk2400_8.o
-soundmodem-$(CONFIG_SOUNDMODEM_AFSK2666) += sm_afsk2666.o
-soundmodem-$(CONFIG_SOUNDMODEM_HAPN4800) += sm_hapn4800.o
-soundmodem-$(CONFIG_SOUNDMODEM_PSK4800) += sm_psk4800.o
-soundmodem-$(CONFIG_SOUNDMODEM_FSK9600) += sm_fsk9600.o
-soundmodem-objs := $(soundmodem-y)
-
-host-progs := gentbl
-HOST_LOADLIBES := -lm
-
-# Files generated that shall be removed upon make clean
-clean-files := sm_tbl_afsk1200.h sm_tbl_afsk2400_7.h \
- sm_tbl_afsk2400_8.h sm_tbl_afsk2666.h \
- sm_tbl_psk4800.h sm_tbl_hapn4800.h \
- sm_tbl_fsk9600.h
-
-include $(TOPDIR)/Rules.make
-
-# Dependencies on generates files need to be listed explicitly
-
-$(obj)/sm_afsk1200.o: $(obj)/sm_tbl_afsk1200.h
-$(obj)/sm_afsk2400_7.o: $(obj)/sm_tbl_afsk2400_7.h
-$(obj)/sm_afsk2400_8.o: $(obj)/sm_tbl_afsk2400_8.h
-$(obj)/sm_afsk2666.o: $(obj)/sm_tbl_afsk2666.h
-$(obj)/sm_psk4800.o: $(obj)/sm_tbl_psk4800.h
-$(obj)/sm_hapn4800.o: $(obj)/sm_tbl_hapn4800.h
-$(obj)/sm_fsk9600.o: $(obj)/sm_tbl_fsk9600.h
-
-$(obj)/sm_tbl_%: $(obj)/gentbl
- cd $(obj) && ./gentbl
-
diff --git a/drivers/net/hamradio/soundmodem/gentbl.c b/drivers/net/hamradio/soundmodem/gentbl.c
deleted file mode 100644
index a2ff74f018b1..000000000000
--- a/drivers/net/hamradio/soundmodem/gentbl.c
+++ /dev/null
@@ -1,689 +0,0 @@
-/*****************************************************************************/
-
-/*
- * gentbl.c -- soundcard radio modem driver table generator.
- *
- * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Please note that the GPL allows you to use the driver, NOT the radio.
- * In order to use the radio, you need a license from the communications
- * authority of your country.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-
-/* -------------------------------------------------------------------- */
-
-static void gentbl_offscostab(FILE *f, unsigned int nbits)
-{
- int i;
-
- fprintf(f, "\n/*\n * small cosine table in U8 format\n */\n"
- "#define OFFSCOSTABBITS %u\n"
- "#define OFFSCOSTABSIZE (1<<OFFSCOSTABBITS)\n\n",
- nbits);
- fprintf(f, "static unsigned char offscostab[OFFSCOSTABSIZE] = {\n\t");
- for (i = 0; i < (1<<nbits); i++) {
- fprintf(f, "%4u", (int)
- (128+127.0*cos(i*2.0*M_PI/(1<<nbits))));
- if (i < (1<<nbits)-1)
- fprintf(f, "%s", (i & 7) == 7 ? ",\n\t" : ",");
- }
- fprintf(f, "\n};\n\n"
- "#define OFFSCOS(x) offscostab[((x)>>%d)&0x%x]\n\n",
- 16-nbits, (1<<nbits)-1);
-}
-
-/* -------------------------------------------------------------------- */
-
-static void gentbl_costab(FILE *f, unsigned int nbits)
-{
- int i;
-
- fprintf(f, "\n/*\n * more accurate cosine table\n */\n\n"
- "static const short costab[%d] = {", (1<<nbits));
- for (i = 0; i < (1<<nbits); i++) {
- if (!(i & 7))
- fprintf(f, "\n\t");
- fprintf(f, "%6d", (int)(32767.0*cos(i*2.0*M_PI/(1<<nbits))));
- if (i != ((1<<nbits)-1))
- fprintf(f, ", ");
- }
- fprintf(f, "\n};\n\n#define COS(x) costab[((x)>>%d)&0x%x]\n"
- "#define SIN(x) COS((x)+0xc000)\n\n", 16-nbits,
- (1<<nbits)-1);
-}
-
-/* -------------------------------------------------------------------- */
-
-#define AFSK12_SAMPLE_RATE 9600
-#define AFSK12_TX_FREQ_LO 1200
-#define AFSK12_TX_FREQ_HI 2200
-#define AFSK12_CORRLEN 8
-
-static void gentbl_afsk1200(FILE *f)
-{
- int i, v, sum;
-
-#define ARGLO(x) 2.0*M_PI*(double)x*(double)AFSK12_TX_FREQ_LO/(double)AFSK12_SAMPLE_RATE
-#define ARGHI(x) 2.0*M_PI*(double)x*(double)AFSK12_TX_FREQ_HI/(double)AFSK12_SAMPLE_RATE
-
- fprintf(f, "\n/*\n * afsk1200 specific tables\n */\n"
- "#define AFSK12_SAMPLE_RATE %u\n"
- "#define AFSK12_TX_FREQ_LO %u\n"
- "#define AFSK12_TX_FREQ_HI %u\n"
- "#define AFSK12_CORRLEN %u\n\n",
- AFSK12_SAMPLE_RATE, AFSK12_TX_FREQ_LO,
- AFSK12_TX_FREQ_HI, AFSK12_CORRLEN);
- fprintf(f, "static const int afsk12_tx_lo_i[] = {\n\t");
- for(sum = i = 0; i < AFSK12_CORRLEN; i++) {
- sum += (v = 127.0*cos(ARGLO(i)));
- fprintf(f, " %4i%c", v, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
- }
- fprintf(f, "\n};\n#define SUM_AFSK12_TX_LO_I %d\n\n"
- "static const int afsk12_tx_lo_q[] = {\n\t", sum);
- for(sum = i = 0; i < AFSK12_CORRLEN; i++) {
- sum += (v = 127.0*sin(ARGLO(i)));
- fprintf(f, " %4i%c", v, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
- }
- fprintf(f, "\n};\n#define SUM_AFSK12_TX_LO_Q %d\n\n"
- "static const int afsk12_tx_hi_i[] = {\n\t", sum);
- for(sum = i = 0; i < AFSK12_CORRLEN; i++) {
- sum += (v = 127.0*cos(ARGHI(i)));
- fprintf(f, " %4i%c", v, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
- }
- fprintf(f, "\n};\n#define SUM_AFSK12_TX_HI_I %d\n\n"
- "static const int afsk12_tx_hi_q[] = {\n\t", sum);
- for(sum = i = 0; i < AFSK12_CORRLEN; i++) {
- sum += (v = 127.0*sin(ARGHI(i)));
- fprintf(f, " %4i%c", v, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
- }
- fprintf(f, "\n};\n#define SUM_AFSK12_TX_HI_Q %d\n\n", sum);
-#undef ARGLO
-#undef ARGHI
-}
-
-/* -------------------------------------------------------------------- */
-
-static const float fsk96_tx_coeff_4[32] = {
- -0.001152, 0.000554, 0.002698, 0.002753,
- -0.002033, -0.008861, -0.008002, 0.006607,
- 0.023727, 0.018905, -0.018056, -0.057957,
- -0.044368, 0.055683, 0.207667, 0.322048,
- 0.322048, 0.207667, 0.055683, -0.044368,
- -0.057957, -0.018056, 0.018905, 0.023727,
- 0.006607, -0.008002, -0.008861, -0.002033,
- 0.002753, 0.002698, 0.000554, -0.001152
-};
-
-static const float fsk96_tx_coeff_5[40] = {
- -0.001009, -0.000048, 0.001376, 0.002547,
- 0.002061, -0.001103, -0.005795, -0.008170,
- -0.004017, 0.006924, 0.018225, 0.019238,
- 0.002925, -0.025777, -0.048064, -0.039683,
- 0.013760, 0.104144, 0.200355, 0.262346,
- 0.262346, 0.200355, 0.104144, 0.013760,
- -0.039683, -0.048064, -0.025777, 0.002925,
- 0.019238, 0.018225, 0.006924, -0.004017,
- -0.008170, -0.005795, -0.001103, 0.002061,
- 0.002547, 0.001376, -0.000048, -0.001009
-};
-
-#define HAMMING(x) (0.54-0.46*cos(2*M_PI*(x)));
-
-static inline float hamming(float x)
-{
- return 0.54-0.46*cos(2*M_PI*x);
-}
-
-static inline float sinc(float x)
-{
- if (x == 0)
- return 1;
- x *= M_PI;
- return sin(x)/x;
-}
-
-static void gentbl_fsk9600(FILE *f)
-{
- int i, j, k, l, m;
- float s;
- float c[44];
- float min, max;
-
- fprintf(f, "\n/*\n * fsk9600 specific tables\n */\n");
- min = max = 0;
- memset(c, 0, sizeof(c));
-#if 0
- memcpy(c+2, fsk96_tx_coeff_4, sizeof(fsk96_tx_coeff_4));
-#else
- for (i = 0; i < 29; i++)
- c[3+i] = sinc(1.2*((i-14.0)/4.0))*hamming(i/28.0)/3.5;
-#endif
- fprintf(f, "static unsigned char fsk96_txfilt_4[] = {\n\t");
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 256; j++) {
- for (k = 1, s = 0, l = i; k < 256; k <<= 1) {
- if (j & k) {
- for (m = 0; m < 4; m++, l++)
- s += c[l];
- } else {
- for (m = 0; m < 4; m++, l++)
- s -= c[l];
- }
- }
- s *= 0.75;
- if (s > max)
- max = s;
- if (s < min)
- min = s;
- fprintf(f, "%4d", (int)(128+127*s));
- if (i < 3 || j < 255)
- fprintf(f, ",%s", (j & 7) == 7
- ? "\n\t" : "");
- }
- }
-#ifdef VERBOSE
- fprintf(stderr, "fsk9600: txfilt4: min = %f; max = %f\n", min, max);
-#endif
- fprintf(f, "\n};\n\n");
- min = max = 0;
- memset(c, 0, sizeof(c));
-#if 0
- memcpy(c+2, fsk96_tx_coeff_5, sizeof(fsk96_tx_coeff_5));
-#else
- for (i = 0; i < 36; i++)
- c[4+i] = sinc(1.2*((i-17.5)/5.0))*hamming(i/35.0)/4.5;
-#endif
- fprintf(f, "static unsigned char fsk96_txfilt_5[] = {\n\t");
- for (i = 0; i < 5; i++) {
- for (j = 0; j < 256; j++) {
- for (k = 1, s = 0, l = i; k < 256; k <<= 1) {
- if (j & k) {
- for (m = 0; m < 5; m++, l++)
- s += c[l];
- } else {
- for (m = 0; m < 5; m++, l++)
- s -= c[l];
- }
- }
- s *= 0.75;
- if (s > max)
- max = s;
- if (s < min)
- min = s;
- fprintf(f, "%4d", (int)(128+127*s));
- if (i < 4 || j < 255)
- fprintf(f, ",%s", (j & 7) == 7
- ? "\n\t" : "");
- }
- }
-#ifdef VERBOSE
- fprintf(stderr, "fsk9600: txfilt5: min = %f; max = %f\n", min, max);
-#endif
- fprintf(f, "\n};\n\n");
-}
-
-/* -------------------------------------------------------------------- */
-
-#define AFSK26_SAMPLERATE 16000
-
-#define AFSK26_NUMCAR 2
-#define AFSK26_FIRSTCAR 2000
-#define AFSK26_MSK_LEN 6
-#define AFSK26_RXOVER 2
-
-#define AFSK26_DEMCORRLEN (2*AFSK26_MSK_LEN)
-
-#define AFSK26_WINDOW(x) ((1-cos(2.0*M_PI*(x)))/2.0)
-
-#define AFSK26_AMPL(x) (((x)?1.0:0.7))
-
-#undef AFSK26_AMPL
-#define AFSK26_AMPL(x) 1
-
-static void gentbl_afsk2666(FILE *f)
-{
- int i, j, k, l, o, v, sumi, sumq;
- float window[AFSK26_DEMCORRLEN*AFSK26_RXOVER];
- int cfreq[AFSK26_NUMCAR];
-
- fprintf(f, "\n/*\n * afsk2666 specific tables\n */\n"
- "#define AFSK26_DEMCORRLEN %d\n"
- "#define AFSK26_SAMPLERATE %d\n\n", AFSK26_DEMCORRLEN,
- AFSK26_SAMPLERATE);
- fprintf(f, "static const unsigned int afsk26_carfreq[%d] = { ",
- AFSK26_NUMCAR);
- for (i = 0; i < AFSK26_NUMCAR; i++) {
- cfreq[i] = 0x10000*AFSK26_FIRSTCAR/AFSK26_SAMPLERATE+
- 0x10000*i/AFSK26_MSK_LEN/2;
- fprintf(f, "0x%x", cfreq[i]);
- if (i < AFSK26_NUMCAR-1)
- fprintf(f, ", ");
- }
- fprintf(f, " };\n\n");
- for (i = 0; i < AFSK26_DEMCORRLEN*AFSK26_RXOVER; i++)
- window[i] = AFSK26_WINDOW(((float)i)/(AFSK26_DEMCORRLEN*
- AFSK26_RXOVER)) * 127.0;
- fprintf(f, "\nstatic const struct {\n\t"
- "int i[%d];\n\tint q[%d];\n} afsk26_dem_tables[%d][%d] = {\n",
- AFSK26_DEMCORRLEN, AFSK26_DEMCORRLEN, AFSK26_RXOVER, AFSK26_NUMCAR);
- for (o = AFSK26_RXOVER-1; o >= 0; o--) {
- fprintf(f, "\t{\n");
- for (i = 0; i < AFSK26_NUMCAR; i++) {
- j = cfreq[i];
- fprintf(f, "\t\t{{ ");
- for (l = AFSK26_DEMCORRLEN-1, k = (j * o)/AFSK26_RXOVER, sumi = 0; l >= 0;
- l--, k = (k+j)&0xffffu) {
- sumi += (v = AFSK26_AMPL(i)*window[l*AFSK26_RXOVER+o]*
- cos(M_PI*k/32768.0));
- fprintf(f, "%6d%s", v, l ? ", " : " }, { ");
- }
- for (l = AFSK26_DEMCORRLEN-1, k = (j * o)/AFSK26_RXOVER, sumq = 0; l >= 0;
- l--, k = (k+j)&0xffffu) {
- sumq += (v = AFSK26_AMPL(i)*window[l*AFSK26_RXOVER+o]*
- sin(M_PI*k/32768.0));
- fprintf(f, "%6d%s", v, l ? ", " : " }}");
- }
- if (i < 1)
- fprintf(f, ",");
- fprintf(f, "\n#define AFSK26_DEM_SUM_I_%d_%d %d\n"
- "#define AFSK26_DEM_SUM_Q_%d_%d %d\n",
- AFSK26_RXOVER-1-o, i, sumi, AFSK26_RXOVER-1-o, i, sumq);
- }
- fprintf(f, "\t}%s\n", o ? "," : "");
- }
- fprintf(f, "};\n\n");
-}
-
-/* -------------------------------------------------------------------- */
-
-#define ATAN_TABLEN 1024
-
-static void gentbl_atantab(FILE *f)
-{
- int i;
- short x;
-
- fprintf(f, "\n/*\n"
- " * arctan table (indexed by i/q; should really be indexed by i/(i+q)\n"
- " */\n""#define ATAN_TABLEN %d\n\n"
- "static const unsigned short atan_tab[ATAN_TABLEN+2] = {",
- ATAN_TABLEN);
- for (i = 0; i <= ATAN_TABLEN; i++) {
- if (!(i & 7))
- fprintf(f, "\n\t");
- x = atan(i / (float)ATAN_TABLEN) / M_PI * 0x8000;
- fprintf(f, "%6d, ", x);
- }
- fprintf(f, "%6d\n};\n\n", x);
-
-}
-
-/* -------------------------------------------------------------------- */
-
-#define PSK48_TXF_OVERSAMPLING 5
-#define PSK48_TXF_NUMSAMPLES 16
-#define PSK48_RXF_LEN 64
-
-static const float psk48_tx_coeff[80] = {
- -0.000379, -0.000640, -0.000000, 0.000772,
- 0.000543, -0.000629, -0.001187, -0.000000,
- 0.001634, 0.001183, -0.001382, -0.002603,
- -0.000000, 0.003481, 0.002472, -0.002828,
- -0.005215, -0.000000, 0.006705, 0.004678,
- -0.005269, -0.009584, -0.000000, 0.012065,
- 0.008360, -0.009375, -0.017028, -0.000000,
- 0.021603, 0.015123, -0.017229, -0.032012,
- -0.000000, 0.043774, 0.032544, -0.040365,
- -0.084963, -0.000000, 0.201161, 0.374060,
- 0.374060, 0.201161, -0.000000, -0.084963,
- -0.040365, 0.032544, 0.043774, -0.000000,
- -0.032012, -0.017229, 0.015123, 0.021603,
- -0.000000, -0.017028, -0.009375, 0.008360,
- 0.012065, -0.000000, -0.009584, -0.005269,
- 0.004678, 0.006705, -0.000000, -0.005215,
- -0.002828, 0.002472, 0.003481, -0.000000,
- -0.002603, -0.001382, 0.001183, 0.001634,
- -0.000000, -0.001187, -0.000629, 0.000543,
- 0.000772, -0.000000, -0.000640, -0.000379
-};
-
-static const float psk48_rx_coeff[PSK48_RXF_LEN] = {
- -0.000219, 0.000360, 0.000873, 0.001080,
- 0.000747, -0.000192, -0.001466, -0.002436,
- -0.002328, -0.000699, 0.002101, 0.004809,
- 0.005696, 0.003492, -0.001633, -0.007660,
- -0.011316, -0.009627, -0.001780, 0.009712,
- 0.019426, 0.021199, 0.011342, -0.008583,
- -0.030955, -0.044093, -0.036634, -0.002651,
- 0.054742, 0.123101, 0.184198, 0.220219,
- 0.220219, 0.184198, 0.123101, 0.054742,
- -0.002651, -0.036634, -0.044093, -0.030955,
- -0.008583, 0.011342, 0.021199, 0.019426,
- 0.009712, -0.001780, -0.009627, -0.011316,
- -0.007660, -0.001633, 0.003492, 0.005696,
- 0.004809, 0.002101, -0.000699, -0.002328,
- -0.002436, -0.001466, -0.000192, 0.000747,
- 0.001080, 0.000873, 0.000360, -0.000219
-};
-
-static void gentbl_psk4800(FILE *f)
-{
- int i, j, k;
- short x;
-
- fprintf(f, "\n/*\n * psk4800 specific tables\n */\n"
- "#define PSK48_TXF_OVERSAMPLING %d\n"
- "#define PSK48_TXF_NUMSAMPLES %d\n\n"
- "#define PSK48_SAMPLERATE 8000\n"
- "#define PSK48_CAR_FREQ 2000\n"
- "#define PSK48_PSK_LEN 5\n"
- "#define PSK48_RXF_LEN %u\n"
- "#define PSK48_PHASEINC (0x10000*PSK48_CAR_FREQ/PSK48_SAMPLERATE)\n"
- "#define PSK48_SPHASEINC (0x10000/(2*PSK48_PSK_LEN))\n\n"
- "static const short psk48_tx_table[PSK48_TXF_OVERSAMPLING*"
- "PSK48_TXF_NUMSAMPLES*8*2] = {",
- PSK48_TXF_OVERSAMPLING, PSK48_TXF_NUMSAMPLES, PSK48_RXF_LEN);
- for (i = 0; i < PSK48_TXF_OVERSAMPLING; i++) {
- for (j = 0; j < PSK48_TXF_NUMSAMPLES; j++) {
- fprintf(f, "\n\t");
- for (k = 0; k < 8; k++) {
- x = 32767.0 * cos(k*M_PI/4.0) *
- psk48_tx_coeff[j * PSK48_TXF_OVERSAMPLING + i];
- fprintf(f, "%6d, ", x);
- }
- fprintf(f, "\n\t");
- for (k = 0; k < 8; k++) {
- x = 32767.0 * sin(k*M_PI/4.0) *
- psk48_tx_coeff[j * PSK48_TXF_OVERSAMPLING + i];
- fprintf(f, "%6d", x);
- if (k != 7 || j != PSK48_TXF_NUMSAMPLES-1 ||
- i != PSK48_TXF_OVERSAMPLING-1)
- fprintf(f, ", ");
- }
- }
- }
- fprintf(f, "\n};\n\n");
-
- fprintf(f, "static const short psk48_rx_coeff[PSK48_RXF_LEN] = {\n\t");
- for (i = 0; i < PSK48_RXF_LEN; i++) {
- fprintf(f, "%6d", (int)(psk48_rx_coeff[i]*32767.0));
- if (i < PSK48_RXF_LEN-1)
- fprintf(f, ",%s", (i & 7) == 7 ? "\n\t" : "");
- }
- fprintf(f, "\n};\n\n");
-}
-
-/* -------------------------------------------------------------------- */
-
-static void gentbl_hapn4800(FILE *f)
-{
- int i, j, k, l;
- float s;
- float c[44];
- float min, max;
-
- fprintf(f, "\n/*\n * hapn4800 specific tables\n */\n\n");
- /*
- * firstly generate tables for the FM transmitter modulator
- */
- min = max = 0;
- memset(c, 0, sizeof(c));
- for (i = 0; i < 24; i++)
- c[8+i] = sinc(1.5*((i-11.5)/8.0))*hamming(i/23.0)/2.4;
- for (i = 0; i < 24; i++)
- c[i] -= c[i+8];
- fprintf(f, "static unsigned char hapn48_txfilt_8[] = {\n\t");
- for (i = 0; i < 8; i++) {
- for (j = 0; j < 16; j++) {
- for (k = 1, s = 0, l = i; k < 16; k <<= 1, l += 8) {
- if (j & k)
- s += c[l];
- else
- s -= c[l];
- }
- if (s > max)
- max = s;
- if (s < min)
- min = s;
- fprintf(f, "%4d", (int)(128+127*s));
- if (i < 7 || j < 15)
- fprintf(f, ",%s", (j & 7) == 7
- ? "\n\t" : "");
- }
- }
-#ifdef VERBOSE
- fprintf(stderr, "hapn4800: txfilt8: min = %f; max = %f\n", min, max);
-#endif
- fprintf(f, "\n};\n\n");
- min = max = 0;
- memset(c, 0, sizeof(c));
- for (i = 0; i < 30; i++)
- c[10+i] = sinc(1.5*((i-14.5)/10.0))*hamming(i/29.0)/2.4;
- for (i = 0; i < 30; i++)
- c[i] -= c[i+10];
- fprintf(f, "static unsigned char hapn48_txfilt_10[] = {\n\t");
- for (i = 0; i < 10; i++) {
- for (j = 0; j < 16; j++) {
- for (k = 1, s = 0, l = i; k < 16; k <<= 1, l += 10) {
- if (j & k)
- s += c[l];
- else
- s -= c[l];
- }
- if (s > max)
- max = s;
- if (s < min)
- min = s;
- fprintf(f, "%4d", (int)(128+127*s));
- if (i < 9 || j < 15)
- fprintf(f, ",%s", (j & 7) == 7
- ? "\n\t" : "");
- }
- }
-#ifdef VERBOSE
- fprintf(stderr, "hapn4800: txfilt10: min = %f; max = %f\n", min, max);
-#endif
- fprintf(f, "\n};\n\n");
- /*
- * secondly generate tables for the PM transmitter modulator
- */
- min = max = 0;
- memset(c, 0, sizeof(c));
- for (i = 0; i < 25; i++)
- c[i] = sinc(1.4*((i-12.0)/8.0))*hamming(i/24.0)/6.3;
- for (i = 0; i < 25; i++)
- for (j = 1; j < 8; j++)
- c[i] += c[i+j];
- fprintf(f, "static unsigned char hapn48_txfilt_pm8[] = {\n\t");
- for (i = 0; i < 8; i++) {
- for (j = 0; j < 16; j++) {
- for (k = 1, s = 0, l = i; k < 16; k <<= 1, l += 8) {
- if (j & k)
- s += c[l];
- else
- s -= c[l];
- }
- if (s > max)
- max = s;
- if (s < min)
- min = s;
- fprintf(f, "%4d", (int)(128+127*s));
- if (i < 7 || j < 15)
- fprintf(f, ",%s", (j & 7) == 7
- ? "\n\t" : "");
- }
- }
-#ifdef VERBOSE
- fprintf(stderr, "hapn4800: txfiltpm8: min = %f; max = %f\n", min, max);
-#endif
- fprintf(f, "\n};\n\n");
- min = max = 0;
- memset(c, 0, sizeof(c));
- for (i = 0; i < 31; i++)
- c[10+i] = sinc(1.4*((i-15.0)/10.0))*hamming(i/30.0)/7.9;
- for (i = 0; i < 31; i++)
- for (j = 1; j < 10; j++)
- c[i] += c[i+j];
- fprintf(f, "static unsigned char hapn48_txfilt_pm10[] = {\n\t");
- for (i = 0; i < 10; i++) {
- for (j = 0; j < 16; j++) {
- for (k = 1, s = 0, l = i; k < 16; k <<= 1, l += 10) {
- if (j & k)
- s += c[l];
- else
- s -= c[l];
- }
- if (s > max)
- max = s;
- if (s < min)
- min = s;
- fprintf(f, "%4d", (int)(128+127*s));
- if (i < 9 || j < 15)
- fprintf(f, ",%s", (j & 7) == 7
- ? "\n\t" : "");
- }
- }
-#ifdef VERBOSE
- fprintf(stderr, "hapn4800: txfiltpm10: min = %f; max = %f\n", min, max);
-#endif
- fprintf(f, "\n};\n\n");
-
-}
-
-/* -------------------------------------------------------------------- */
-
-#define AFSK24_SAMPLERATE 16000
-#define AFSK24_CORRLEN 14
-
-static void gentbl_afsk2400(FILE *f, float tcm3105clk)
-{
- int i, sum, v;
-
- fprintf(f, "\n/*\n * afsk2400 specific tables (tcm3105 clk %7fHz)\n */\n"
- "#define AFSK24_TX_FREQ_LO %d\n"
- "#define AFSK24_TX_FREQ_HI %d\n"
- "#define AFSK24_BITPLL_INC %d\n"
- "#define AFSK24_SAMPLERATE %d\n\n", tcm3105clk,
- (int)(tcm3105clk/3694.0), (int)(tcm3105clk/2015.0),
- 0x10000*2400/AFSK24_SAMPLERATE, AFSK24_SAMPLERATE);
-
-#define ARGLO(x) 2.0*M_PI*(double)x*(tcm3105clk/3694.0)/(double)AFSK24_SAMPLERATE
-#define ARGHI(x) 2.0*M_PI*(double)x*(tcm3105clk/2015.0)/(double)AFSK24_SAMPLERATE
-#define WINDOW(x) hamming((float)(x)/(AFSK24_CORRLEN-1.0))
-
- fprintf(f, "static const int afsk24_tx_lo_i[] = {\n\t");
- for(sum = i = 0; i < AFSK24_CORRLEN; i++) {
- sum += (v = 127.0*cos(ARGLO(i))*WINDOW(i));
- fprintf(f, " %4i%c", v, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
- }
- fprintf(f, "\n};\n#define SUM_AFSK24_TX_LO_I %d\n\n"
- "static const int afsk24_tx_lo_q[] = {\n\t", sum);
- for(sum = i = 0; i < AFSK24_CORRLEN; i++) {
- sum += (v = 127.0*sin(ARGLO(i))*WINDOW(i));
- fprintf(f, " %4i%c", v, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
- }
- fprintf(f, "\n};\n#define SUM_AFSK24_TX_LO_Q %d\n\n"
- "static const int afsk24_tx_hi_i[] = {\n\t", sum);
- for(sum = i = 0; i < AFSK24_CORRLEN; i++) {
- sum += (v = 127.0*cos(ARGHI(i))*WINDOW(i));
- fprintf(f, " %4i%c", v, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
- }
- fprintf(f, "\n};\n#define SUM_AFSK24_TX_HI_I %d\n\n"
- "static const int afsk24_tx_hi_q[] = {\n\t", sum);
- for(sum = i = 0; i < AFSK24_CORRLEN; i++) {
- sum += (v = 127.0*sin(ARGHI(i))*WINDOW(i));
- fprintf(f, " %4i%c", v, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
- }
- fprintf(f, "\n};\n#define SUM_AFSK24_TX_HI_Q %d\n\n", sum);
-#undef ARGLO
-#undef ARGHI
-#undef WINDOW
-}
-
-/* -------------------------------------------------------------------- */
-
-static char *progname;
-
-static void gentbl_banner(FILE *f)
-{
- fprintf(f, "/*\n * THIS FILE IS GENERATED AUTOMATICALLY BY %s, "
- "DO NOT EDIT!\n */\n\n", progname);
-}
-
-/* -------------------------------------------------------------------- */
-
-int main(int argc, char *argv[])
-{
- FILE *f;
-
- progname = argv[0];
- if (!(f = fopen("sm_tbl_afsk1200.h", "w")))
- exit(1);
- gentbl_banner(f);
- gentbl_offscostab(f, 6);
- gentbl_costab(f, 6);
- gentbl_afsk1200(f);
- fclose(f);
- if (!(f = fopen("sm_tbl_afsk2666.h", "w")))
- exit(1);
- gentbl_banner(f);
- gentbl_offscostab(f, 6);
- gentbl_costab(f, 6);
- gentbl_afsk2666(f);
- fclose(f);
- if (!(f = fopen("sm_tbl_psk4800.h", "w")))
- exit(1);
- gentbl_banner(f);
- gentbl_psk4800(f);
- gentbl_costab(f, 8);
- gentbl_atantab(f);
- fclose(f);
- if (!(f = fopen("sm_tbl_hapn4800.h", "w")))
- exit(1);
- gentbl_banner(f);
- gentbl_hapn4800(f);
- fclose(f);
- if (!(f = fopen("sm_tbl_fsk9600.h", "w")))
- exit(1);
- gentbl_banner(f);
- gentbl_fsk9600(f);
- fclose(f);
- if (!(f = fopen("sm_tbl_afsk2400_8.h", "w")))
- exit(1);
- gentbl_banner(f);
- gentbl_offscostab(f, 6);
- gentbl_costab(f, 6);
- gentbl_afsk2400(f, 8000000);
- fclose(f);
- if (!(f = fopen("sm_tbl_afsk2400_7.h", "w")))
- exit(1);
- gentbl_banner(f);
- gentbl_offscostab(f, 6);
- gentbl_costab(f, 6);
- gentbl_afsk2400(f, 7372800);
- fclose(f);
- exit(0);
-}
-
-
-/* -------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/soundmodem/sm.c b/drivers/net/hamradio/soundmodem/sm.c
deleted file mode 100644
index bc389262d348..000000000000
--- a/drivers/net/hamradio/soundmodem/sm.c
+++ /dev/null
@@ -1,759 +0,0 @@
-/*****************************************************************************/
-
-/*
- * sm.c -- soundcard radio modem driver.
- *
- * Copyright (C) 1996-2000 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Please note that the GPL allows you to use the driver, NOT the radio.
- * In order to use the radio, you need a license from the communications
- * authority of your country.
- *
- *
- * Command line options (insmod command line)
- *
- * mode mode string; eg. "wss:afsk1200"
- * iobase base address of the soundcard; common values are 0x220 for sbc,
- * 0x530 for wss
- * irq interrupt number; common values are 7 or 5 for sbc, 11 for wss
- * dma dma number; common values are 0 or 1
- *
- *
- * History:
- * 0.1 21.09.1996 Started
- * 18.10.1996 Changed to new user space access routines (copy_{to,from}_user)
- * 0.4 21.01.1997 Separately compileable soundcard/modem modules
- * 0.5 03.03.1997 fixed LPT probing (check_lpt result was interpreted the wrong way round)
- * 0.6 16.04.1997 init code/data tagged
- * 0.7 30.07.1997 fixed halfduplex interrupt handlers/hotfix for CS423X
- * 0.8 14.04.1998 cleanups
- * 0.9 03.08.1999 adapt to Linus' new __setup/__initcall
- * use parport lowlevel drivers instead of directly writing to a parallel port
- * removed some pre-2.2 kernel compatibility cruft
- * 0.10 10.08.1999 Check if parport can do SPP and is safe to access during interrupt contexts
- * 0.11 12.02.2000 adapted to softnet driver interface
- * 0.12 03.07.2000 fix interface name handling
- */
-
-/*****************************************************************************/
-
-#include <linux/config.h>
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/parport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include "sm.h"
-
-/* --------------------------------------------------------------------- */
-
-/*static*/ const char sm_drvname[] = "soundmodem";
-static const char sm_drvinfo[] = KERN_INFO "soundmodem: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
-KERN_INFO "soundmodem: version 0.12 compiled " __TIME__ " " __DATE__ "\n";
-
-/* --------------------------------------------------------------------- */
-
-/*static*/ const struct modem_tx_info *sm_modem_tx_table[] = {
-#ifdef CONFIG_SOUNDMODEM_AFSK1200
- &sm_afsk1200_tx,
-#endif /* CONFIG_SOUNDMODEM_AFSK1200 */
-#ifdef CONFIG_SOUNDMODEM_AFSK2400_7
- &sm_afsk2400_7_tx,
-#endif /* CONFIG_SOUNDMODEM_AFSK2400_7 */
-#ifdef CONFIG_SOUNDMODEM_AFSK2400_8
- &sm_afsk2400_8_tx,
-#endif /* CONFIG_SOUNDMODEM_AFSK2400_8 */
-#ifdef CONFIG_SOUNDMODEM_AFSK2666
- &sm_afsk2666_tx,
-#endif /* CONFIG_SOUNDMODEM_AFSK2666 */
-#ifdef CONFIG_SOUNDMODEM_PSK4800
- &sm_psk4800_tx,
-#endif /* CONFIG_SOUNDMODEM_PSK4800 */
-#ifdef CONFIG_SOUNDMODEM_HAPN4800
- &sm_hapn4800_8_tx,
- &sm_hapn4800_10_tx,
- &sm_hapn4800_pm8_tx,
- &sm_hapn4800_pm10_tx,
-#endif /* CONFIG_SOUNDMODEM_HAPN4800 */
-#ifdef CONFIG_SOUNDMODEM_FSK9600
- &sm_fsk9600_4_tx,
- &sm_fsk9600_5_tx,
-#endif /* CONFIG_SOUNDMODEM_FSK9600 */
- NULL
-};
-
-/*static*/ const struct modem_rx_info *sm_modem_rx_table[] = {
-#ifdef CONFIG_SOUNDMODEM_AFSK1200
- &sm_afsk1200_rx,
-#endif /* CONFIG_SOUNDMODEM_AFSK1200 */
-#ifdef CONFIG_SOUNDMODEM_AFSK2400_7
- &sm_afsk2400_7_rx,
-#endif /* CONFIG_SOUNDMODEM_AFSK2400_7 */
-#ifdef CONFIG_SOUNDMODEM_AFSK2400_8
- &sm_afsk2400_8_rx,
-#endif /* CONFIG_SOUNDMODEM_AFSK2400_8 */
-#ifdef CONFIG_SOUNDMODEM_AFSK2666
- &sm_afsk2666_rx,
-#endif /* CONFIG_SOUNDMODEM_AFSK2666 */
-#ifdef CONFIG_SOUNDMODEM_PSK4800
- &sm_psk4800_rx,
-#endif /* CONFIG_SOUNDMODEM_PSK4800 */
-#ifdef CONFIG_SOUNDMODEM_HAPN4800
- &sm_hapn4800_8_rx,
- &sm_hapn4800_10_rx,
- &sm_hapn4800_pm8_rx,
- &sm_hapn4800_pm10_rx,
-#endif /* CONFIG_SOUNDMODEM_HAPN4800 */
-#ifdef CONFIG_SOUNDMODEM_FSK9600
- &sm_fsk9600_4_rx,
- &sm_fsk9600_5_rx,
-#endif /* CONFIG_SOUNDMODEM_FSK9600 */
- NULL
-};
-
-static const struct hardware_info *sm_hardware_table[] = {
-#ifdef CONFIG_SOUNDMODEM_SBC
- &sm_hw_sbc,
- &sm_hw_sbcfdx,
-#endif /* CONFIG_SOUNDMODEM_SBC */
-#ifdef CONFIG_SOUNDMODEM_WSS
- &sm_hw_wss,
- &sm_hw_wssfdx,
-#endif /* CONFIG_SOUNDMODEM_WSS */
- NULL
-};
-
-/* --------------------------------------------------------------------- */
-
-#define NR_PORTS 4
-
-static struct net_device sm_device[NR_PORTS];
-
-/* --------------------------------------------------------------------- */
-
-#define UART_RBR(iobase) (iobase+0)
-#define UART_THR(iobase) (iobase+0)
-#define UART_IER(iobase) (iobase+1)
-#define UART_IIR(iobase) (iobase+2)
-#define UART_FCR(iobase) (iobase+2)
-#define UART_LCR(iobase) (iobase+3)
-#define UART_MCR(iobase) (iobase+4)
-#define UART_LSR(iobase) (iobase+5)
-#define UART_MSR(iobase) (iobase+6)
-#define UART_SCR(iobase) (iobase+7)
-#define UART_DLL(iobase) (iobase+0)
-#define UART_DLM(iobase) (iobase+1)
-
-#define SER_EXTENT 8
-
-#define MIDI_DATA(iobase) (iobase)
-#define MIDI_STATUS(iobase) (iobase+1)
-#define MIDI_READ_FULL 0x80 /* attention: negative logic!! */
-#define MIDI_WRITE_EMPTY 0x40 /* attention: negative logic!! */
-
-#define MIDI_EXTENT 2
-
-/* ---------------------------------------------------------------------- */
-
-#define PARAM_TXDELAY 1
-#define PARAM_PERSIST 2
-#define PARAM_SLOTTIME 3
-#define PARAM_TXTAIL 4
-#define PARAM_FULLDUP 5
-#define PARAM_HARDWARE 6
-#define PARAM_RETURN 255
-
-#define SP_SER 1
-#define SP_PAR 2
-#define SP_MIDI 4
-
-/*
- * ===================== port checking routines ========================
- */
-
-enum uart { c_uart_unknown, c_uart_8250,
- c_uart_16450, c_uart_16550, c_uart_16550A};
-static const char *uart_str[] =
- { "unknown", "8250", "16450", "16550", "16550A" };
-
-static enum uart check_uart(unsigned int iobase)
-{
- unsigned char b1,b2,b3;
- enum uart u;
- enum uart uart_tab[] =
- { c_uart_16450, c_uart_unknown, c_uart_16550, c_uart_16550A };
-
- if (iobase <= 0 || iobase > 0x1000-SER_EXTENT)
- return c_uart_unknown;
- if (check_region(iobase, SER_EXTENT))
- return c_uart_unknown;
- b1 = inb(UART_MCR(iobase));
- outb(b1 | 0x10, UART_MCR(iobase)); /* loopback mode */
- b2 = inb(UART_MSR(iobase));
- outb(0x1a, UART_MCR(iobase));
- b3 = inb(UART_MSR(iobase)) & 0xf0;
- outb(b1, UART_MCR(iobase)); /* restore old values */
- outb(b2, UART_MSR(iobase));
- if (b3 != 0x90)
- return c_uart_unknown;
- inb(UART_RBR(iobase));
- inb(UART_RBR(iobase));
- outb(0x01, UART_FCR(iobase)); /* enable FIFOs */
- u = uart_tab[(inb(UART_IIR(iobase)) >> 6) & 3];
- if (u == c_uart_16450) {
- outb(0x5a, UART_SCR(iobase));
- b1 = inb(UART_SCR(iobase));
- outb(0xa5, UART_SCR(iobase));
- b2 = inb(UART_SCR(iobase));
- if ((b1 != 0x5a) || (b2 != 0xa5))
- u = c_uart_8250;
- }
- return u;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int check_midi(unsigned int iobase)
-{
- unsigned long timeout;
- unsigned long flags;
- unsigned char b;
-
- if (iobase <= 0 || iobase > 0x1000-MIDI_EXTENT)
- return 0;
- if (check_region(iobase, MIDI_EXTENT))
- return 0;
- timeout = jiffies + (HZ / 100);
- while (inb(MIDI_STATUS(iobase)) & MIDI_WRITE_EMPTY)
- if ((signed)(jiffies - timeout) > 0)
- return 0;
- save_flags(flags);
- cli();
- outb(0xff, MIDI_DATA(iobase));
- b = inb(MIDI_STATUS(iobase));
- restore_flags(flags);
- if (!(b & MIDI_WRITE_EMPTY))
- return 0;
- while (inb(MIDI_STATUS(iobase)) & MIDI_WRITE_EMPTY)
- if ((signed)(jiffies - timeout) > 0)
- return 0;
- return 1;
-}
-
-/* --------------------------------------------------------------------- */
-
-void sm_output_status(struct sm_state *sm)
-{
- int invert_dcd = 0;
- int invert_ptt = 0;
-
- int ptt = /*hdlcdrv_ptt(&sm->hdrv)*/(sm->dma.ptt_cnt > 0) ^ invert_ptt;
- int dcd = (!!sm->hdrv.hdlcrx.dcd) ^ invert_dcd;
-
- if (sm->hdrv.ptt_out.flags & SP_SER) {
- outb(dcd | (ptt << 1), UART_MCR(sm->hdrv.ptt_out.seriobase));
- outb(0x40 & (-ptt), UART_LCR(sm->hdrv.ptt_out.seriobase));
- }
- if (sm->hdrv.ptt_out.flags & SP_PAR && sm->pardev && sm->pardev->port)
- parport_write_data(sm->pardev->port, ptt | (dcd << 1));
- if (sm->hdrv.ptt_out.flags & SP_MIDI && hdlcdrv_ptt(&sm->hdrv))
- outb(0, MIDI_DATA(sm->hdrv.ptt_out.midiiobase));
-}
-
-/* --------------------------------------------------------------------- */
-
-static void sm_output_open(struct sm_state *sm, const char *ifname)
-{
- enum uart u = c_uart_unknown;
- struct parport *pp = NULL;
-
- sm->hdrv.ptt_out.flags = 0;
- if (sm->hdrv.ptt_out.seriobase > 0 &&
- sm->hdrv.ptt_out.seriobase <= 0x1000-SER_EXTENT &&
- ((u = check_uart(sm->hdrv.ptt_out.seriobase))) != c_uart_unknown) {
- sm->hdrv.ptt_out.flags |= SP_SER;
- request_region(sm->hdrv.ptt_out.seriobase, SER_EXTENT, "sm ser ptt");
- outb(0, UART_IER(sm->hdrv.ptt_out.seriobase));
- /* 5 bits, 1 stop, no parity, no break, Div latch access */
- outb(0x80, UART_LCR(sm->hdrv.ptt_out.seriobase));
- outb(0, UART_DLM(sm->hdrv.ptt_out.seriobase));
- outb(1, UART_DLL(sm->hdrv.ptt_out.seriobase)); /* as fast as possible */
- /* LCR and MCR set by output_status */
- }
- sm->pardev = NULL;
- if (sm->hdrv.ptt_out.pariobase > 0) {
- pp = parport_enumerate();
- while (pp && pp->base != sm->hdrv.ptt_out.pariobase)
- pp = pp->next;
- if (!pp)
- printk(KERN_WARNING "%s: parport at address 0x%x not found\n", sm_drvname, sm->hdrv.ptt_out.pariobase);
- else if ((~pp->modes) & (PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT))
- printk(KERN_WARNING "%s: parport at address 0x%x cannot be used\n", sm_drvname, sm->hdrv.ptt_out.pariobase);
- else {
- sm->pardev = parport_register_device(pp, ifname, NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
- if (!sm->pardev) {
- pp = NULL;
- printk(KERN_WARNING "%s: cannot register parport device (address 0x%x)\n", sm_drvname, sm->hdrv.ptt_out.pariobase);
- } else {
- if (parport_claim(sm->pardev)) {
- parport_unregister_device(sm->pardev);
- sm->pardev = NULL;
- printk(KERN_WARNING "%s: cannot claim parport at address 0x%x\n", sm_drvname, sm->hdrv.ptt_out.pariobase);
- } else
- sm->hdrv.ptt_out.flags |= SP_PAR;
- }
- }
- }
- if (sm->hdrv.ptt_out.midiiobase > 0 &&
- sm->hdrv.ptt_out.midiiobase <= 0x1000-MIDI_EXTENT &&
- check_midi(sm->hdrv.ptt_out.midiiobase)) {
- sm->hdrv.ptt_out.flags |= SP_MIDI;
- request_region(sm->hdrv.ptt_out.midiiobase, MIDI_EXTENT,
- "sm midi ptt");
- }
- sm_output_status(sm);
-
- printk(KERN_INFO "%s: ptt output:", sm_drvname);
- if (sm->hdrv.ptt_out.flags & SP_SER)
- printk(" serial interface at 0x%x, uart %s", sm->hdrv.ptt_out.seriobase,
- uart_str[u]);
- if (sm->hdrv.ptt_out.flags & SP_PAR)
- printk(" parallel interface at 0x%x", sm->hdrv.ptt_out.pariobase);
- if (sm->hdrv.ptt_out.flags & SP_MIDI)
- printk(" mpu401 (midi) interface at 0x%x", sm->hdrv.ptt_out.midiiobase);
- if (!sm->hdrv.ptt_out.flags)
- printk(" none");
- printk("\n");
-}
-
-/* --------------------------------------------------------------------- */
-
-static void sm_output_close(struct sm_state *sm)
-{
- /* release regions used for PTT output */
- sm->hdrv.hdlctx.ptt = sm->hdrv.hdlctx.calibrate = 0;
- sm_output_status(sm);
- if (sm->hdrv.ptt_out.flags & SP_SER)
- release_region(sm->hdrv.ptt_out.seriobase, SER_EXTENT);
- if (sm->hdrv.ptt_out.flags & SP_PAR && sm->pardev) {
- parport_release(sm->pardev);
- parport_unregister_device(sm->pardev);
- }
- if (sm->hdrv.ptt_out.flags & SP_MIDI)
- release_region(sm->hdrv.ptt_out.midiiobase, MIDI_EXTENT);
- sm->hdrv.ptt_out.flags = 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sm_open(struct net_device *dev);
-static int sm_close(struct net_device *dev);
-static int sm_ioctl(struct net_device *dev, struct ifreq *ifr,
- struct hdlcdrv_ioctl *hi, int cmd);
-
-/* --------------------------------------------------------------------- */
-
-static const struct hdlcdrv_ops sm_ops = {
- sm_drvname, sm_drvinfo, sm_open, sm_close, sm_ioctl
-};
-
-/* --------------------------------------------------------------------- */
-
-static int sm_open(struct net_device *dev)
-{
- struct sm_state *sm;
- int err;
-
- if (!dev || !dev->priv ||
- ((struct sm_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
- printk(KERN_ERR "sm_open: invalid device struct\n");
- return -EINVAL;
- }
- sm = (struct sm_state *)dev->priv;
-
- if (!sm->mode_tx || !sm->mode_rx || !sm->hwdrv || !sm->hwdrv->open)
- return -ENODEV;
- sm->hdrv.par.bitrate = sm->mode_rx->bitrate;
- err = sm->hwdrv->open(dev, sm);
- if (err)
- return err;
- sm_output_open(sm, dev->name);
- MOD_INC_USE_COUNT;
- printk(KERN_INFO "%s: %s mode %s.%s at iobase 0x%lx irq %u dma %u dma2 %u\n",
- sm_drvname, sm->hwdrv->hw_name, sm->mode_tx->name,
- sm->mode_rx->name, dev->base_addr, dev->irq, dev->dma, sm->hdrv.ptt_out.dma2);
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sm_close(struct net_device *dev)
-{
- struct sm_state *sm;
- int err = -ENODEV;
-
- if (!dev || !dev->priv ||
- ((struct sm_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
- printk(KERN_ERR "sm_close: invalid device struct\n");
- return -EINVAL;
- }
- sm = (struct sm_state *)dev->priv;
-
-
- if (sm->hwdrv && sm->hwdrv->close)
- err = sm->hwdrv && sm->hwdrv->close(dev, sm);
- sm_output_close(sm);
- MOD_DEC_USE_COUNT;
- printk(KERN_INFO "%s: close %s at iobase 0x%lx irq %u dma %u\n",
- sm_drvname, sm->hwdrv->hw_name, dev->base_addr, dev->irq, dev->dma);
- return err;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sethw(struct net_device *dev, struct sm_state *sm, char *mode)
-{
- char *cp = strchr(mode, ':');
- const struct hardware_info **hwp = sm_hardware_table;
-
- if (!cp)
- cp = mode;
- else {
- *cp++ = '\0';
- while (hwp && (*hwp) && (*hwp)->hw_name && strcmp((*hwp)->hw_name, mode))
- hwp++;
- if (!hwp || !*hwp || !(*hwp)->hw_name)
- return -EINVAL;
- if ((*hwp)->loc_storage > sizeof(sm->hw)) {
- printk(KERN_ERR "%s: insufficient storage for hw driver %s (%d)\n",
- sm_drvname, (*hwp)->hw_name, (*hwp)->loc_storage);
- return -EINVAL;
- }
- sm->hwdrv = *hwp;
- }
- if (!*cp)
- return 0;
- if (sm->hwdrv && sm->hwdrv->sethw)
- return sm->hwdrv->sethw(dev, sm, cp);
- return -EINVAL;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sm_ioctl(struct net_device *dev, struct ifreq *ifr,
- struct hdlcdrv_ioctl *hi, int cmd)
-{
- struct sm_state *sm;
- struct sm_ioctl bi;
- unsigned long flags;
- unsigned int newdiagmode;
- unsigned int newdiagflags;
- char *cp;
- const struct modem_tx_info **mtp = sm_modem_tx_table;
- const struct modem_rx_info **mrp = sm_modem_rx_table;
- const struct hardware_info **hwp = sm_hardware_table;
-
- if (!dev || !dev->priv ||
- ((struct sm_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
- printk(KERN_ERR "sm_ioctl: invalid device struct\n");
- return -EINVAL;
- }
- sm = (struct sm_state *)dev->priv;
-
- if (cmd != SIOCDEVPRIVATE) {
- if (!sm->hwdrv || !sm->hwdrv->ioctl)
- return sm->hwdrv->ioctl(dev, sm, ifr, hi, cmd);
- return -ENOIOCTLCMD;
- }
- switch (hi->cmd) {
- default:
- if (sm->hwdrv && sm->hwdrv->ioctl)
- return sm->hwdrv->ioctl(dev, sm, ifr, hi, cmd);
- return -ENOIOCTLCMD;
-
- case HDLCDRVCTL_GETMODE:
- cp = hi->data.modename;
- if (sm->hwdrv && sm->hwdrv->hw_name)
- cp += sprintf(cp, "%s:", sm->hwdrv->hw_name);
- else
- cp += sprintf(cp, "<unspec>:");
- if (sm->mode_tx && sm->mode_tx->name)
- cp += sprintf(cp, "%s", sm->mode_tx->name);
- else
- cp += sprintf(cp, "<unspec>");
- if (!sm->mode_rx || !sm->mode_rx ||
- strcmp(sm->mode_rx->name, sm->mode_tx->name)) {
- if (sm->mode_rx && sm->mode_rx->name)
- cp += sprintf(cp, ",%s", sm->mode_rx->name);
- else
- cp += sprintf(cp, ",<unspec>");
- }
- if (copy_to_user(ifr->ifr_data, hi, sizeof(*hi)))
- return -EFAULT;
- return 0;
-
- case HDLCDRVCTL_SETMODE:
- if (netif_running(dev) || !capable(CAP_NET_ADMIN))
- return -EACCES;
- hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
- return sethw(dev, sm, hi->data.modename);
-
- case HDLCDRVCTL_MODELIST:
- cp = hi->data.modename;
- while (*hwp) {
- if ((*hwp)->hw_name)
- cp += sprintf(cp, "%s:,", (*hwp)->hw_name);
- hwp++;
- }
- while (*mtp) {
- if ((*mtp)->name)
- cp += sprintf(cp, ">%s,", (*mtp)->name);
- mtp++;
- }
- while (*mrp) {
- if ((*mrp)->name)
- cp += sprintf(cp, "<%s,", (*mrp)->name);
- mrp++;
- }
- cp[-1] = '\0';
- if (copy_to_user(ifr->ifr_data, hi, sizeof(*hi)))
- return -EFAULT;
- return 0;
-
-#ifdef SM_DEBUG
- case SMCTL_GETDEBUG:
- if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
- return -EFAULT;
- bi.data.dbg.int_rate = sm->debug_vals.last_intcnt;
- bi.data.dbg.mod_cycles = sm->debug_vals.mod_cyc;
- bi.data.dbg.demod_cycles = sm->debug_vals.demod_cyc;
- bi.data.dbg.dma_residue = sm->debug_vals.dma_residue;
- sm->debug_vals.mod_cyc = sm->debug_vals.demod_cyc =
- sm->debug_vals.dma_residue = 0;
- if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
- return -EFAULT;
- return 0;
-#endif /* SM_DEBUG */
-
- case SMCTL_DIAGNOSE:
- if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
- return -EFAULT;
- newdiagmode = bi.data.diag.mode;
- newdiagflags = bi.data.diag.flags;
- if (newdiagmode > SM_DIAGMODE_CONSTELLATION)
- return -EINVAL;
- bi.data.diag.mode = sm->diag.mode;
- bi.data.diag.flags = sm->diag.flags;
- bi.data.diag.samplesperbit = sm->mode_rx->sperbit;
- if (sm->diag.mode != newdiagmode) {
- save_flags(flags);
- cli();
- sm->diag.ptr = -1;
- sm->diag.flags = newdiagflags & ~SM_DIAGFLAG_VALID;
- sm->diag.mode = newdiagmode;
- restore_flags(flags);
- if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
- return -EFAULT;
- return 0;
- }
- if (sm->diag.ptr < 0 || sm->diag.mode == SM_DIAGMODE_OFF) {
- if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
- return -EFAULT;
- return 0;
- }
- if (bi.data.diag.datalen > DIAGDATALEN)
- bi.data.diag.datalen = DIAGDATALEN;
- if (sm->diag.ptr < bi.data.diag.datalen) {
- if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
- return -EFAULT;
- return 0;
- }
- if (copy_to_user(bi.data.diag.data, sm->diag.data,
- bi.data.diag.datalen * sizeof(short)))
- return -EFAULT;
- bi.data.diag.flags |= SM_DIAGFLAG_VALID;
- save_flags(flags);
- cli();
- sm->diag.ptr = -1;
- sm->diag.flags = newdiagflags & ~SM_DIAGFLAG_VALID;
- sm->diag.mode = newdiagmode;
- restore_flags(flags);
- if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
- return -EFAULT;
- return 0;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * command line settable parameters
- */
-static char *mode[NR_PORTS] = { [0 ... NR_PORTS-1] = NULL };
-static int iobase[NR_PORTS] = { [0 ... NR_PORTS-1] = -1 };
-static int irq[NR_PORTS] = { [0 ... NR_PORTS-1] = -1 };
-static int dma[NR_PORTS] = { [0 ... NR_PORTS-1] = -1 };
-static int dma2[NR_PORTS] = { [0 ... NR_PORTS-1] = -1 };
-static int serio[NR_PORTS] = { [0 ... NR_PORTS-1] = 0 };
-static int pario[NR_PORTS] = { [0 ... NR_PORTS-1] = 0 };
-static int midiio[NR_PORTS] = { [0 ... NR_PORTS-1] = 0 };
-
-MODULE_PARM(mode, "1-" __MODULE_STRING(NR_PORTS) "s");
-MODULE_PARM_DESC(mode, "soundmodem operating mode; eg. sbc:afsk1200 or wss:fsk9600");
-MODULE_PARM(iobase, "1-" __MODULE_STRING(NR_PORTS) "i");
-MODULE_PARM_DESC(iobase, "soundmodem base address");
-MODULE_PARM(irq, "1-" __MODULE_STRING(NR_PORTS) "i");
-MODULE_PARM_DESC(irq, "soundmodem interrupt");
-MODULE_PARM(dma, "1-" __MODULE_STRING(NR_PORTS) "i");
-MODULE_PARM_DESC(dma, "soundmodem dma channel");
-MODULE_PARM(dma2, "1-" __MODULE_STRING(NR_PORTS) "i");
-MODULE_PARM_DESC(dma2, "soundmodem 2nd dma channel; full duplex only");
-MODULE_PARM(serio, "1-" __MODULE_STRING(NR_PORTS) "i");
-MODULE_PARM_DESC(serio, "soundmodem PTT output on serial port");
-MODULE_PARM(pario, "1-" __MODULE_STRING(NR_PORTS) "i");
-MODULE_PARM_DESC(pario, "soundmodem PTT output on parallel port");
-MODULE_PARM(midiio, "1-" __MODULE_STRING(NR_PORTS) "i");
-MODULE_PARM_DESC(midiio, "soundmodem PTT output on midi port");
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("Soundcard amateur radio modem driver");
-
-/* --------------------------------------------------------------------- */
-
-static int __init init_soundmodem(void)
-{
- int i, j, found = 0;
- char set_hw = 1;
- struct sm_state *sm;
-
- printk(sm_drvinfo);
- /*
- * register net devices
- */
- for (i = 0; i < NR_PORTS; i++) {
- struct net_device *dev = sm_device+i;
- char ifname[IFNAMSIZ];
-
- sprintf(ifname, "sm%d", i);
- if (!mode[i])
- set_hw = 0;
- else {
- if (!strncmp(mode[i], "sbc", 3)) {
- if (iobase[i] == -1)
- iobase[i] = 0x220;
- if (irq[i] == -1)
- irq[i] = 5;
- if (dma[i] == -1)
- dma[i] = 1;
- } else {
- if (iobase[i] == -1)
- iobase[i] = 0x530;
- if (irq[i] == -1)
- irq[i] = 11;
- if (dma[i] == -1)
- dma[i] = 1;
- }
- }
- if (!set_hw)
- iobase[i] = irq[i] = 0;
- j = hdlcdrv_register_hdlcdrv(dev, &sm_ops, sizeof(struct sm_state), ifname, iobase[i], irq[i], dma[i]);
- if (!j) {
- sm = (struct sm_state *)dev->priv;
- sm->hdrv.ptt_out.dma2 = dma2[i];
- sm->hdrv.ptt_out.seriobase = serio[i];
- sm->hdrv.ptt_out.pariobase = pario[i];
- sm->hdrv.ptt_out.midiiobase = midiio[i];
- if (set_hw && sethw(dev, sm, mode[i]))
- set_hw = 0;
- found++;
- } else {
- printk(KERN_WARNING "%s: cannot register net device\n", sm_drvname);
- }
- }
- if (!found)
- return -ENXIO;
- return 0;
-}
-
-static void __exit cleanup_soundmodem(void)
-{
- int i;
-
- printk(KERN_INFO "sm: cleanup_module called\n");
-
- for(i = 0; i < NR_PORTS; i++) {
- struct net_device *dev = sm_device+i;
- struct sm_state *sm = (struct sm_state *)dev->priv;
-
- if (sm) {
- if (sm->hdrv.magic != HDLCDRV_MAGIC)
- printk(KERN_ERR "sm: invalid magic in "
- "cleanup_module\n");
- else
- hdlcdrv_unregister_hdlcdrv(dev);
- }
- }
-}
-
-module_init(init_soundmodem);
-module_exit(cleanup_soundmodem);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/*
- * format: soundmodem=io,irq,dma[,dma2[,serio[,pario]]],mode
- * mode: hw:modem
- * hw: sbc, wss, wssfdx
- * modem: afsk1200, fsk9600
- */
-
-static int __init sm_setup(char *str)
-{
- static unsigned nr_dev;
- int ints[8];
-
- if (nr_dev >= NR_PORTS)
- return 0;
- str = get_options(str, 8, ints);
- mode[nr_dev] = str;
- if (ints[0] >= 1)
- iobase[nr_dev] = ints[1];
- if (ints[0] >= 2)
- irq[nr_dev] = ints[2];
- if (ints[0] >= 3)
- dma[nr_dev] = ints[3];
- if (ints[0] >= 4)
- dma2[nr_dev] = ints[4];
- if (ints[0] >= 5)
- serio[nr_dev] = ints[5];
- if (ints[0] >= 6)
- pario[nr_dev] = ints[6];
- if (ints[0] >= 7)
- midiio[nr_dev] = ints[7];
- nr_dev++;
- return 1;
-}
-
-__setup("soundmodem=", sm_setup);
-
-#endif /* MODULE */
-/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/soundmodem/sm.h b/drivers/net/hamradio/soundmodem/sm.h
deleted file mode 100644
index 25c47f948ba7..000000000000
--- a/drivers/net/hamradio/soundmodem/sm.h
+++ /dev/null
@@ -1,383 +0,0 @@
-/*****************************************************************************/
-
-/*
- * sm.h -- soundcard radio modem driver internal header.
- *
- * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Please note that the GPL allows you to use the driver, NOT the radio.
- * In order to use the radio, you need a license from the communications
- * authority of your country.
- *
- */
-
-#ifndef _SM_H
-#define _SM_H
-
-/* ---------------------------------------------------------------------- */
-
-#include <linux/hdlcdrv.h>
-#include <linux/soundmodem.h>
-#include <asm/processor.h>
-#include <linux/bitops.h>
-#include <linux/parport.h>
-
-#define SM_DEBUG
-
-/* ---------------------------------------------------------------------- */
-/*
- * Information that need to be kept for each board.
- */
-
-struct sm_state {
- struct hdlcdrv_state hdrv;
-
- const struct modem_tx_info *mode_tx;
- const struct modem_rx_info *mode_rx;
-
- const struct hardware_info *hwdrv;
-
- struct pardevice *pardev;
-
- /*
- * Hardware (soundcard) access routines state
- */
- struct {
- void *ibuf;
- unsigned int ifragsz;
- unsigned int ifragptr;
- unsigned int i16bit;
- void *obuf;
- unsigned int ofragsz;
- unsigned int ofragptr;
- unsigned int o16bit;
- int ptt_cnt;
- } dma;
-
- union {
- long hw[32/sizeof(long)];
- } hw;
-
- /*
- * state of the modem code
- */
- union {
- long m[48/sizeof(long)];
- } m;
- union {
- long d[256/sizeof(long)];
- } d;
-
-#define DIAGDATALEN 64
- struct diag_data {
- unsigned int mode;
- unsigned int flags;
- volatile int ptr;
- short data[DIAGDATALEN];
- } diag;
-
-
-#ifdef SM_DEBUG
- struct debug_vals {
- unsigned long last_jiffies;
- unsigned cur_intcnt;
- unsigned last_intcnt;
- unsigned mod_cyc;
- unsigned demod_cyc;
- unsigned dma_residue;
- } debug_vals;
-#endif /* SM_DEBUG */
-};
-
-/* ---------------------------------------------------------------------- */
-/*
- * Mode definition structure
- */
-
-struct modem_tx_info {
- const char *name;
- unsigned int loc_storage;
- int srate;
- int bitrate;
- void (*modulator_u8)(struct sm_state *, unsigned char *, unsigned int);
- void (*modulator_s16)(struct sm_state *, short *, unsigned int);
- void (*init)(struct sm_state *);
-};
-
-struct modem_rx_info {
- const char *name;
- unsigned int loc_storage;
- int srate;
- int bitrate;
- unsigned int overlap;
- unsigned int sperbit;
- void (*demodulator_u8)(struct sm_state *, const unsigned char *, unsigned int);
- void (*demodulator_s16)(struct sm_state *, const short *, unsigned int);
- void (*init)(struct sm_state *);
-};
-
-/* ---------------------------------------------------------------------- */
-/*
- * Soundcard driver definition structure
- */
-
-struct hardware_info {
- char *hw_name; /* used for request_{region,irq,dma} */
- unsigned int loc_storage;
- /*
- * mode specific open/close
- */
- int (*open)(struct net_device *, struct sm_state *);
- int (*close)(struct net_device *, struct sm_state *);
- int (*ioctl)(struct net_device *, struct sm_state *, struct ifreq *,
- struct hdlcdrv_ioctl *, int);
- int (*sethw)(struct net_device *, struct sm_state *, char *);
-};
-
-/* --------------------------------------------------------------------- */
-
-extern const char sm_drvname[];
-extern const char sm_drvinfo[];
-
-/* --------------------------------------------------------------------- */
-/*
- * ===================== diagnostics stuff ===============================
- */
-
-static inline void diag_trigger(struct sm_state *sm)
-{
- if (sm->diag.ptr < 0)
- if (!(sm->diag.flags & SM_DIAGFLAG_DCDGATE) || sm->hdrv.hdlcrx.dcd)
- sm->diag.ptr = 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-#define SHRT_MAX ((short)(((unsigned short)(~0U))>>1))
-#define SHRT_MIN (-SHRT_MAX-1)
-
-static inline void diag_add(struct sm_state *sm, int valinp, int valdemod)
-{
- int val;
-
- if ((sm->diag.mode != SM_DIAGMODE_INPUT &&
- sm->diag.mode != SM_DIAGMODE_DEMOD) ||
- sm->diag.ptr >= DIAGDATALEN || sm->diag.ptr < 0)
- return;
- val = (sm->diag.mode == SM_DIAGMODE_DEMOD) ? valdemod : valinp;
- /* clip */
- if (val > SHRT_MAX)
- val = SHRT_MAX;
- if (val < SHRT_MIN)
- val = SHRT_MIN;
- sm->diag.data[sm->diag.ptr++] = val;
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void diag_add_one(struct sm_state *sm, int val)
-{
- if ((sm->diag.mode != SM_DIAGMODE_INPUT &&
- sm->diag.mode != SM_DIAGMODE_DEMOD) ||
- sm->diag.ptr >= DIAGDATALEN || sm->diag.ptr < 0)
- return;
- /* clip */
- if (val > SHRT_MAX)
- val = SHRT_MAX;
- if (val < SHRT_MIN)
- val = SHRT_MIN;
- sm->diag.data[sm->diag.ptr++] = val;
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void diag_add_constellation(struct sm_state *sm, int vali, int valq)
-{
- if ((sm->diag.mode != SM_DIAGMODE_CONSTELLATION) ||
- sm->diag.ptr >= DIAGDATALEN-1 || sm->diag.ptr < 0)
- return;
- /* clip */
- if (vali > SHRT_MAX)
- vali = SHRT_MAX;
- if (vali < SHRT_MIN)
- vali = SHRT_MIN;
- if (valq > SHRT_MAX)
- valq = SHRT_MAX;
- if (valq < SHRT_MIN)
- valq = SHRT_MIN;
- sm->diag.data[sm->diag.ptr++] = vali;
- sm->diag.data[sm->diag.ptr++] = valq;
-}
-
-/* --------------------------------------------------------------------- */
-/*
- * ===================== utility functions ===============================
- */
-
-#if 0
-static inline unsigned int hweight32(unsigned int w)
- __attribute__ ((unused));
-static inline unsigned int hweight16(unsigned short w)
- __attribute__ ((unused));
-static inline unsigned int hweight8(unsigned char w)
- __attribute__ ((unused));
-
-static inline unsigned int hweight32(unsigned int w)
-{
- unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
- res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
- res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
- res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
- return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
-}
-
-static inline unsigned int hweight16(unsigned short w)
-{
- unsigned short res = (w & 0x5555) + ((w >> 1) & 0x5555);
- res = (res & 0x3333) + ((res >> 2) & 0x3333);
- res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
- return (res & 0x00FF) + ((res >> 8) & 0x00FF);
-}
-
-static inline unsigned int hweight8(unsigned char w)
-{
- unsigned short res = (w & 0x55) + ((w >> 1) & 0x55);
- res = (res & 0x33) + ((res >> 2) & 0x33);
- return (res & 0x0F) + ((res >> 4) & 0x0F);
-}
-
-#endif
-
-static inline unsigned int gcd(unsigned int x, unsigned int y)
- __attribute__ ((unused));
-static inline unsigned int lcm(unsigned int x, unsigned int y)
- __attribute__ ((unused));
-
-static inline unsigned int gcd(unsigned int x, unsigned int y)
-{
- for (;;) {
- if (!x)
- return y;
- if (!y)
- return x;
- if (x > y)
- x %= y;
- else
- y %= x;
- }
-}
-
-static inline unsigned int lcm(unsigned int x, unsigned int y)
-{
- return x * y / gcd(x, y);
-}
-
-/* --------------------------------------------------------------------- */
-/*
- * ===================== profiling =======================================
- */
-
-
-#ifdef __i386__
-
-#include <asm/msr.h>
-
-/*
- * only do 32bit cycle counter arithmetic; we hope we won't overflow.
- * in fact, overflowing modems would require over 2THz CPU clock speeds :-)
- */
-
-#define time_exec(var,cmd) \
-({ \
- if (cpu_has_tsc) { \
- unsigned int cnt1, cnt2; \
- rdtscl(cnt1); \
- cmd; \
- rdtscl(cnt2); \
- var = cnt2-cnt1; \
- } else { \
- cmd; \
- } \
-})
-
-#else /* __i386__ */
-
-#define time_exec(var,cmd) cmd
-
-#endif /* __i386__ */
-
-/* --------------------------------------------------------------------- */
-
-extern const struct modem_tx_info sm_afsk1200_tx;
-extern const struct modem_tx_info sm_afsk2400_7_tx;
-extern const struct modem_tx_info sm_afsk2400_8_tx;
-extern const struct modem_tx_info sm_afsk2666_tx;
-extern const struct modem_tx_info sm_psk4800_tx;
-extern const struct modem_tx_info sm_hapn4800_8_tx;
-extern const struct modem_tx_info sm_hapn4800_10_tx;
-extern const struct modem_tx_info sm_hapn4800_pm8_tx;
-extern const struct modem_tx_info sm_hapn4800_pm10_tx;
-extern const struct modem_tx_info sm_fsk9600_4_tx;
-extern const struct modem_tx_info sm_fsk9600_5_tx;
-
-extern const struct modem_rx_info sm_afsk1200_rx;
-extern const struct modem_rx_info sm_afsk2400_7_rx;
-extern const struct modem_rx_info sm_afsk2400_8_rx;
-extern const struct modem_rx_info sm_afsk2666_rx;
-extern const struct modem_rx_info sm_psk4800_rx;
-extern const struct modem_rx_info sm_hapn4800_8_rx;
-extern const struct modem_rx_info sm_hapn4800_10_rx;
-extern const struct modem_rx_info sm_hapn4800_pm8_rx;
-extern const struct modem_rx_info sm_hapn4800_pm10_rx;
-extern const struct modem_rx_info sm_fsk9600_4_rx;
-extern const struct modem_rx_info sm_fsk9600_5_rx;
-
-extern const struct hardware_info sm_hw_sbc;
-extern const struct hardware_info sm_hw_sbcfdx;
-extern const struct hardware_info sm_hw_wss;
-extern const struct hardware_info sm_hw_wssfdx;
-
-extern const struct modem_tx_info *sm_modem_tx_table[];
-extern const struct modem_rx_info *sm_modem_rx_table[];
-extern const struct hardware_info *sm_hardware_table[];
-
-/* --------------------------------------------------------------------- */
-
-void sm_output_status(struct sm_state *sm);
-/*void sm_output_open(struct sm_state *sm);*/
-/*void sm_output_close(struct sm_state *sm);*/
-
-/* --------------------------------------------------------------------- */
-
-extern void inline sm_int_freq(struct sm_state *sm)
-{
-#ifdef SM_DEBUG
- unsigned long cur_jiffies = jiffies;
- /*
- * measure the interrupt frequency
- */
- sm->debug_vals.cur_intcnt++;
- if ((cur_jiffies - sm->debug_vals.last_jiffies) >= HZ) {
- sm->debug_vals.last_jiffies = cur_jiffies;
- sm->debug_vals.last_intcnt = sm->debug_vals.cur_intcnt;
- sm->debug_vals.cur_intcnt = 0;
- }
-#endif /* SM_DEBUG */
-}
-
-/* --------------------------------------------------------------------- */
-#endif /* _SM_H */
diff --git a/drivers/net/hamradio/soundmodem/sm_afsk1200.c b/drivers/net/hamradio/soundmodem/sm_afsk1200.c
deleted file mode 100644
index 1463d7fdd577..000000000000
--- a/drivers/net/hamradio/soundmodem/sm_afsk1200.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*****************************************************************************/
-
-/*
- * sm_afsk1200.c -- soundcard radio modem driver, 1200 baud AFSK modem
- *
- * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Please note that the GPL allows you to use the driver, NOT the radio.
- * In order to use the radio, you need a license from the communications
- * authority of your country.
- *
- */
-
-#include "sm.h"
-#include "sm_tbl_afsk1200.h"
-
-/* --------------------------------------------------------------------- */
-
-struct demod_state_afsk12 {
- unsigned int shreg;
- unsigned int bit_pll;
- unsigned char last_sample;
- unsigned int dcd_shreg;
- int dcd_sum0, dcd_sum1, dcd_sum2;
- unsigned int dcd_time;
- unsigned char last_rxbit;
-};
-
-struct mod_state_afsk12 {
- unsigned int shreg;
- unsigned char tx_bit;
- unsigned int bit_pll;
- unsigned int dds_inc;
- unsigned int txphase;
-};
-
-/* --------------------------------------------------------------------- */
-
-static const int dds_inc[2] = {
- AFSK12_TX_FREQ_LO*0x10000/AFSK12_SAMPLE_RATE,
- AFSK12_TX_FREQ_HI*0x10000/AFSK12_SAMPLE_RATE
-};
-
-static void modulator_1200_u8(struct sm_state *sm, unsigned char *buf,
- unsigned int buflen)
-{
- struct mod_state_afsk12 *st = (struct mod_state_afsk12 *)(&sm->m);
-
- for (; buflen > 0; buflen--) {
- if (!((st->txphase++) & 7)) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
- st->shreg >>= 1;
- }
- st->dds_inc = dds_inc[st->tx_bit & 1];
- *buf++ = OFFSCOS(st->bit_pll);
- st->bit_pll += st->dds_inc;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_1200_s16(struct sm_state *sm, short *buf, unsigned int buflen)
-{
- struct mod_state_afsk12 *st = (struct mod_state_afsk12 *)(&sm->m);
-
- for (; buflen > 0; buflen--) {
- if (!((st->txphase++) & 7)) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
- st->shreg >>= 1;
- }
- st->dds_inc = dds_inc[st->tx_bit & 1];
- *buf++ = COS(st->bit_pll);
- st->bit_pll += st->dds_inc;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static __inline__ int convolution8_u8(const unsigned char *st, const int *coeff, int csum)
-{
- int sum = -0x80 * csum;
-
- sum += (st[0] * coeff[0]);
- sum += (st[-1] * coeff[1]);
- sum += (st[-2] * coeff[2]);
- sum += (st[-3] * coeff[3]);
- sum += (st[-4] * coeff[4]);
- sum += (st[-5] * coeff[5]);
- sum += (st[-6] * coeff[6]);
- sum += (st[-7] * coeff[7]);
-
- sum >>= 7;
- return sum * sum;
-}
-
-static __inline__ int convolution8_s16(const short *st, const int *coeff, int csum)
-{
- int sum = 0;
-
- sum += (st[0] * coeff[0]);
- sum += (st[-1] * coeff[1]);
- sum += (st[-2] * coeff[2]);
- sum += (st[-3] * coeff[3]);
- sum += (st[-4] * coeff[4]);
- sum += (st[-5] * coeff[5]);
- sum += (st[-6] * coeff[6]);
- sum += (st[-7] * coeff[7]);
-
- sum >>= 15;
- return sum * sum;
-}
-
-static __inline__ int do_filter_1200_u8(const unsigned char *buf)
-{
- int sum = convolution8_u8(buf, afsk12_tx_lo_i, SUM_AFSK12_TX_LO_I);
- sum += convolution8_u8(buf, afsk12_tx_lo_q, SUM_AFSK12_TX_LO_Q);
- sum -= convolution8_u8(buf, afsk12_tx_hi_i, SUM_AFSK12_TX_HI_I);
- sum -= convolution8_u8(buf, afsk12_tx_hi_q, SUM_AFSK12_TX_HI_Q);
- return sum;
-}
-
-static __inline__ int do_filter_1200_s16(const short *buf)
-{
- int sum = convolution8_s16(buf, afsk12_tx_lo_i, SUM_AFSK12_TX_LO_I);
- sum += convolution8_s16(buf, afsk12_tx_lo_q, SUM_AFSK12_TX_LO_Q);
- sum -= convolution8_s16(buf, afsk12_tx_hi_i, SUM_AFSK12_TX_HI_I);
- sum -= convolution8_s16(buf, afsk12_tx_hi_q, SUM_AFSK12_TX_HI_Q);
- return sum;
-}
-
-/* --------------------------------------------------------------------- */
-
-static const int pll_corr[2] = { -0x1000, 0x1000 };
-
-static void demodulator_1200_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
-{
- struct demod_state_afsk12 *st = (struct demod_state_afsk12 *)(&sm->d);
- int j;
- int sum;
- unsigned char newsample;
-
- for (; buflen > 0; buflen--, buf++) {
- sum = do_filter_1200_u8(buf);
- st->dcd_shreg <<= 1;
- st->bit_pll += 0x2000;
- newsample = (sum > 0);
- if (st->last_sample ^ newsample) {
- st->last_sample = newsample;
- st->dcd_shreg |= 1;
- st->bit_pll += pll_corr
- [st->bit_pll < 0x9000];
- j = 4 * hweight8(st->dcd_shreg & 0x38)
- - hweight16(st->dcd_shreg & 0x7c0);
- st->dcd_sum0 += j;
- }
- hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 120;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->shreg >>= 1;
- st->shreg |= (!(st->last_rxbit ^
- st->last_sample)) << 16;
- st->last_rxbit = st->last_sample;
- diag_trigger(sm);
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- }
- diag_add(sm, (((int)*buf)-0x80) << 8, sum);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_1200_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
-{
- struct demod_state_afsk12 *st = (struct demod_state_afsk12 *)(&sm->d);
- int j;
- int sum;
- unsigned char newsample;
-
- for (; buflen > 0; buflen--, buf++) {
- sum = do_filter_1200_s16(buf);
- st->dcd_shreg <<= 1;
- st->bit_pll += 0x2000;
- newsample = (sum > 0);
- if (st->last_sample ^ newsample) {
- st->last_sample = newsample;
- st->dcd_shreg |= 1;
- st->bit_pll += pll_corr
- [st->bit_pll < 0x9000];
- j = 4 * hweight8(st->dcd_shreg & 0x38)
- - hweight16(st->dcd_shreg & 0x7c0);
- st->dcd_sum0 += j;
- }
- hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 120;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->shreg >>= 1;
- st->shreg |= (!(st->last_rxbit ^
- st->last_sample)) << 16;
- st->last_rxbit = st->last_sample;
- diag_trigger(sm);
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- }
- diag_add(sm, *buf, sum);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demod_init_1200(struct sm_state *sm)
-{
- struct demod_state_afsk12 *st = (struct demod_state_afsk12 *)(&sm->d);
-
- st->dcd_time = 120;
- st->dcd_sum0 = 2;
-}
-
-/* --------------------------------------------------------------------- */
-
-const struct modem_tx_info sm_afsk1200_tx = {
- "afsk1200", sizeof(struct mod_state_afsk12),
- AFSK12_SAMPLE_RATE, 1200, modulator_1200_u8, modulator_1200_s16, NULL
-};
-
-const struct modem_rx_info sm_afsk1200_rx = {
- "afsk1200", sizeof(struct demod_state_afsk12),
- AFSK12_SAMPLE_RATE, 1200, 8, AFSK12_SAMPLE_RATE/1200,
- demodulator_1200_u8, demodulator_1200_s16, demod_init_1200
-};
-
-/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/soundmodem/sm_afsk2400_7.c b/drivers/net/hamradio/soundmodem/sm_afsk2400_7.c
deleted file mode 100644
index 5d9f9ee9971a..000000000000
--- a/drivers/net/hamradio/soundmodem/sm_afsk2400_7.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*****************************************************************************/
-
-/*
- * sm_afsk2400_7.c -- soundcard radio modem driver, 2400 baud AFSK modem
- *
- * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Please note that the GPL allows you to use the driver, NOT the radio.
- * In order to use the radio, you need a license from the communications
- * authority of your country.
- *
- */
-
-/*
- * This driver is intended to be compatible with TCM3105 modems
- * overclocked to 7.3728MHz. The mark and space frequencies therefore
- * lie at 3658 and 1996 Hz.
- * Note that I do _not_ recommend the building of such links, I provide
- * this only for the users who live in the coverage area of such
- * a "legacy" link.
- */
-
-#include "sm.h"
-#include "sm_tbl_afsk2400_7.h"
-
-/* --------------------------------------------------------------------- */
-
-struct demod_state_afsk24 {
- unsigned int shreg;
- unsigned int bit_pll;
- unsigned char last_sample;
- unsigned int dcd_shreg;
- int dcd_sum0, dcd_sum1, dcd_sum2;
- unsigned int dcd_time;
- unsigned char last_rxbit;
-};
-
-struct mod_state_afsk24 {
- unsigned int shreg;
- unsigned char tx_bit;
- unsigned int bit_pll;
- unsigned int tx_seq;
- unsigned int phinc;
-};
-
-/* --------------------------------------------------------------------- */
-
-static const int dds_inc[2] = { AFSK24_TX_FREQ_LO*0x10000/AFSK24_SAMPLERATE,
- AFSK24_TX_FREQ_HI*0x10000/AFSK24_SAMPLERATE };
-
-static void modulator_2400_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
-{
- struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (st->tx_seq < 0x5555) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
- st->shreg >>= 1;
- st->phinc = dds_inc[st->tx_bit & 1];
- }
- st->tx_seq += 0x5555;
- st->tx_seq &= 0xffff;
- *buf = OFFSCOS(st->bit_pll);
- st->bit_pll += st->phinc;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_2400_s16(struct sm_state *sm, short *buf, unsigned int buflen)
-{
- struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (st->tx_seq < 0x5555) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
- st->shreg >>= 1;
- st->phinc = dds_inc[st->tx_bit & 1];
- }
- st->tx_seq += 0x5555;
- st->tx_seq &= 0xffff;
- *buf = COS(st->bit_pll);
- st->bit_pll += st->phinc;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static __inline__ int convolution14_u8(const unsigned char *st, const int *coeff, int csum)
-{
- int sum = -0x80 * csum;
-
- sum += (st[0] * coeff[0]);
- sum += (st[-1] * coeff[1]);
- sum += (st[-2] * coeff[2]);
- sum += (st[-3] * coeff[3]);
- sum += (st[-4] * coeff[4]);
- sum += (st[-5] * coeff[5]);
- sum += (st[-6] * coeff[6]);
- sum += (st[-7] * coeff[7]);
- sum += (st[-8] * coeff[8]);
- sum += (st[-9] * coeff[9]);
- sum += (st[-10] * coeff[10]);
- sum += (st[-11] * coeff[11]);
- sum += (st[-12] * coeff[12]);
- sum += (st[-13] * coeff[13]);
-
- sum >>= 7;
- return sum * sum;
-}
-
-static __inline__ int convolution14_s16(const short *st, const int *coeff, int csum)
-{
- int sum = 0;
-
- sum += (st[0] * coeff[0]);
- sum += (st[-1] * coeff[1]);
- sum += (st[-2] * coeff[2]);
- sum += (st[-3] * coeff[3]);
- sum += (st[-4] * coeff[4]);
- sum += (st[-5] * coeff[5]);
- sum += (st[-6] * coeff[6]);
- sum += (st[-7] * coeff[7]);
- sum += (st[-8] * coeff[8]);
- sum += (st[-9] * coeff[9]);
- sum += (st[-10] * coeff[10]);
- sum += (st[-11] * coeff[11]);
- sum += (st[-12] * coeff[12]);
- sum += (st[-13] * coeff[13]);
-
- sum >>= 15;
- return sum * sum;
-}
-
-static __inline__ int do_filter_2400_u8(const unsigned char *buf)
-{
- int sum = convolution14_u8(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
- sum += convolution14_u8(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
- sum -= convolution14_u8(buf, afsk24_tx_hi_i, SUM_AFSK24_TX_HI_I);
- sum -= convolution14_u8(buf, afsk24_tx_hi_q, SUM_AFSK24_TX_HI_Q);
- return sum;
-}
-
-static __inline__ int do_filter_2400_s16(const short *buf)
-{
- int sum = convolution14_s16(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
- sum += convolution14_s16(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
- sum -= convolution14_s16(buf, afsk24_tx_hi_i, SUM_AFSK24_TX_HI_I);
- sum -= convolution14_s16(buf, afsk24_tx_hi_q, SUM_AFSK24_TX_HI_Q);
- return sum;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_2400_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
-{
- struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
- int j;
- int sum;
- unsigned char newsample;
-
- for (; buflen > 0; buflen--, buf++) {
- sum = do_filter_2400_u8(buf);
- st->dcd_shreg <<= 1;
- st->bit_pll += AFSK24_BITPLL_INC;
- newsample = (sum > 0);
- if (st->last_sample ^ newsample) {
- st->last_sample = newsample;
- st->dcd_shreg |= 1;
- if (st->bit_pll < (0x8000+AFSK24_BITPLL_INC/2))
- st->bit_pll += AFSK24_BITPLL_INC/2;
- else
- st->bit_pll -= AFSK24_BITPLL_INC/2;
- j = /* 2 * */ hweight8(st->dcd_shreg & 0x1c)
- - hweight16(st->dcd_shreg & 0x1e0);
- st->dcd_sum0 += j;
- }
- hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 120;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->shreg >>= 1;
- st->shreg |= (!(st->last_rxbit ^
- st->last_sample)) << 16;
- st->last_rxbit = st->last_sample;
- diag_trigger(sm);
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- }
- diag_add(sm, (((int)*buf)-0x80) << 8, sum);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_2400_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
-{
- struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
- int j;
- int sum;
- unsigned char newsample;
-
- for (; buflen > 0; buflen--, buf++) {
- sum = do_filter_2400_s16(buf);
- st->dcd_shreg <<= 1;
- st->bit_pll += AFSK24_BITPLL_INC;
- newsample = (sum > 0);
- if (st->last_sample ^ newsample) {
- st->last_sample = newsample;
- st->dcd_shreg |= 1;
- if (st->bit_pll < (0x8000+AFSK24_BITPLL_INC/2))
- st->bit_pll += AFSK24_BITPLL_INC/2;
- else
- st->bit_pll -= AFSK24_BITPLL_INC/2;
- j = /* 2 * */ hweight8(st->dcd_shreg & 0x1c)
- - hweight16(st->dcd_shreg & 0x1e0);
- st->dcd_sum0 += j;
- }
- hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 120;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->shreg >>= 1;
- st->shreg |= (!(st->last_rxbit ^
- st->last_sample)) << 16;
- st->last_rxbit = st->last_sample;
- diag_trigger(sm);
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- }
- diag_add(sm, *buf, sum);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demod_init_2400(struct sm_state *sm)
-{
- struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
-
- st->dcd_time = 120;
- st->dcd_sum0 = 2;
-}
-
-/* --------------------------------------------------------------------- */
-
-const struct modem_tx_info sm_afsk2400_7_tx = {
- "afsk2400_7", sizeof(struct mod_state_afsk24), AFSK24_SAMPLERATE, 2400,
- modulator_2400_u8, modulator_2400_s16, NULL
-};
-
-const struct modem_rx_info sm_afsk2400_7_rx = {
- "afsk2400_7", sizeof(struct demod_state_afsk24),
- AFSK24_SAMPLERATE, 2400, 14, AFSK24_SAMPLERATE/2400,
- demodulator_2400_u8, demodulator_2400_s16, demod_init_2400
-};
-
-/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/soundmodem/sm_afsk2400_8.c b/drivers/net/hamradio/soundmodem/sm_afsk2400_8.c
deleted file mode 100644
index 435afee2ecef..000000000000
--- a/drivers/net/hamradio/soundmodem/sm_afsk2400_8.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*****************************************************************************/
-
-/*
- * sm_afsk2400_8.c -- soundcard radio modem driver, 2400 baud AFSK modem
- *
- * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Please note that the GPL allows you to use the driver, NOT the radio.
- * In order to use the radio, you need a license from the communications
- * authority of your country.
- *
- */
-
-/*
- * This driver is intended to be compatible with TCM3105 modems
- * overclocked to 8MHz. The mark and space frequencies therefore
- * lie at 3970 and 2165 Hz.
- * Note that I do _not_ recommend the building of such links, I provide
- * this only for the users who live in the coverage area of such
- * a "legacy" link.
- */
-
-#include "sm.h"
-#include "sm_tbl_afsk2400_8.h"
-
-/* --------------------------------------------------------------------- */
-
-struct demod_state_afsk24 {
- unsigned int shreg;
- unsigned int bit_pll;
- unsigned char last_sample;
- unsigned int dcd_shreg;
- int dcd_sum0, dcd_sum1, dcd_sum2;
- unsigned int dcd_time;
- unsigned char last_rxbit;
-};
-
-struct mod_state_afsk24 {
- unsigned int shreg;
- unsigned char tx_bit;
- unsigned int bit_pll;
- unsigned int tx_seq;
- unsigned int phinc;
-};
-
-/* --------------------------------------------------------------------- */
-
-static const int dds_inc[2] = { AFSK24_TX_FREQ_LO*0x10000/AFSK24_SAMPLERATE,
- AFSK24_TX_FREQ_HI*0x10000/AFSK24_SAMPLERATE };
-
-static void modulator_2400_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
-{
- struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (st->tx_seq < 0x5555) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
- st->shreg >>= 1;
- st->phinc = dds_inc[st->tx_bit & 1];
- }
- st->tx_seq += 0x5555;
- st->tx_seq &= 0xffff;
- *buf = OFFSCOS(st->bit_pll);
- st->bit_pll += st->phinc;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_2400_s16(struct sm_state *sm, short *buf, unsigned int buflen)
-{
- struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (st->tx_seq < 0x5555) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
- st->shreg >>= 1;
- st->phinc = dds_inc[st->tx_bit & 1];
- }
- st->tx_seq += 0x5555;
- st->tx_seq &= 0xffff;
- *buf = COS(st->bit_pll);
- st->bit_pll += st->phinc;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static __inline__ int convolution14_u8(const unsigned char *st, const int *coeff, int csum)
-{
- int sum = -0x80 * csum;
-
- sum += (st[0] * coeff[0]);
- sum += (st[-1] * coeff[1]);
- sum += (st[-2] * coeff[2]);
- sum += (st[-3] * coeff[3]);
- sum += (st[-4] * coeff[4]);
- sum += (st[-5] * coeff[5]);
- sum += (st[-6] * coeff[6]);
- sum += (st[-7] * coeff[7]);
- sum += (st[-8] * coeff[8]);
- sum += (st[-9] * coeff[9]);
- sum += (st[-10] * coeff[10]);
- sum += (st[-11] * coeff[11]);
- sum += (st[-12] * coeff[12]);
- sum += (st[-13] * coeff[13]);
-
- sum >>= 7;
- return sum * sum;
-}
-
-static __inline__ int convolution14_s16(const short *st, const int *coeff, int csum)
-{
- int sum = 0;
-
- sum += (st[0] * coeff[0]);
- sum += (st[-1] * coeff[1]);
- sum += (st[-2] * coeff[2]);
- sum += (st[-3] * coeff[3]);
- sum += (st[-4] * coeff[4]);
- sum += (st[-5] * coeff[5]);
- sum += (st[-6] * coeff[6]);
- sum += (st[-7] * coeff[7]);
- sum += (st[-8] * coeff[8]);
- sum += (st[-9] * coeff[9]);
- sum += (st[-10] * coeff[10]);
- sum += (st[-11] * coeff[11]);
- sum += (st[-12] * coeff[12]);
- sum += (st[-13] * coeff[13]);
-
- sum >>= 15;
- return sum * sum;
-}
-
-static __inline__ int do_filter_2400_u8(const unsigned char *buf)
-{
- int sum = convolution14_u8(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
- sum += convolution14_u8(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
- sum -= convolution14_u8(buf, afsk24_tx_hi_i, SUM_AFSK24_TX_HI_I);
- sum -= convolution14_u8(buf, afsk24_tx_hi_q, SUM_AFSK24_TX_HI_Q);
- return sum;
-}
-
-static __inline__ int do_filter_2400_s16(const short *buf)
-{
- int sum = convolution14_s16(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
- sum += convolution14_s16(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
- sum -= convolution14_s16(buf, afsk24_tx_hi_i, SUM_AFSK24_TX_HI_I);
- sum -= convolution14_s16(buf, afsk24_tx_hi_q, SUM_AFSK24_TX_HI_Q);
- return sum;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_2400_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
-{
- struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
- int j;
- int sum;
- unsigned char newsample;
-
- for (; buflen > 0; buflen--, buf++) {
- sum = do_filter_2400_u8(buf);
- st->dcd_shreg <<= 1;
- st->bit_pll += AFSK24_BITPLL_INC;
- newsample = (sum > 0);
- if (st->last_sample ^ newsample) {
- st->last_sample = newsample;
- st->dcd_shreg |= 1;
- if (st->bit_pll < (0x8000+AFSK24_BITPLL_INC/2))
- st->bit_pll += AFSK24_BITPLL_INC/2;
- else
- st->bit_pll -= AFSK24_BITPLL_INC/2;
- j = /* 2 * */ hweight8(st->dcd_shreg & 0x1c)
- - hweight16(st->dcd_shreg & 0x1e0);
- st->dcd_sum0 += j;
- }
- hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 120;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->shreg >>= 1;
- st->shreg |= (!(st->last_rxbit ^
- st->last_sample)) << 16;
- st->last_rxbit = st->last_sample;
- diag_trigger(sm);
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- }
- diag_add(sm, (((int)*buf)-0x80) << 8, sum);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_2400_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
-{
- struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
- int j;
- int sum;
- unsigned char newsample;
-
- for (; buflen > 0; buflen--, buf++) {
- sum = do_filter_2400_s16(buf);
- st->dcd_shreg <<= 1;
- st->bit_pll += AFSK24_BITPLL_INC;
- newsample = (sum > 0);
- if (st->last_sample ^ newsample) {
- st->last_sample = newsample;
- st->dcd_shreg |= 1;
- if (st->bit_pll < (0x8000+AFSK24_BITPLL_INC/2))
- st->bit_pll += AFSK24_BITPLL_INC/2;
- else
- st->bit_pll -= AFSK24_BITPLL_INC/2;
- j = /* 2 * */ hweight8(st->dcd_shreg & 0x1c)
- - hweight16(st->dcd_shreg & 0x1e0);
- st->dcd_sum0 += j;
- }
- hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 120;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->shreg >>= 1;
- st->shreg |= (!(st->last_rxbit ^
- st->last_sample)) << 16;
- st->last_rxbit = st->last_sample;
- diag_trigger(sm);
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- }
- diag_add(sm, *buf, sum);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demod_init_2400(struct sm_state *sm)
-{
- struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
-
- st->dcd_time = 120;
- st->dcd_sum0 = 2;
-}
-
-/* --------------------------------------------------------------------- */
-
-const struct modem_tx_info sm_afsk2400_8_tx = {
- "afsk2400_8", sizeof(struct mod_state_afsk24), AFSK24_SAMPLERATE, 2400,
- modulator_2400_u8, modulator_2400_s16, NULL
-};
-
-const struct modem_rx_info sm_afsk2400_8_rx = {
- "afsk2400_8", sizeof(struct demod_state_afsk24),
- AFSK24_SAMPLERATE, 2400, 14, AFSK24_SAMPLERATE/2400,
- demodulator_2400_u8, demodulator_2400_s16, demod_init_2400
-};
-
-/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/soundmodem/sm_afsk2666.c b/drivers/net/hamradio/soundmodem/sm_afsk2666.c
deleted file mode 100644
index 81d1fe27921e..000000000000
--- a/drivers/net/hamradio/soundmodem/sm_afsk2666.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*****************************************************************************/
-
-/*
- * sm_afsk2666.c -- soundcard radio modem driver, 2666 baud AFSK modem
- *
- * Copyright (C) 1997 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Please note that the GPL allows you to use the driver, NOT the radio.
- * In order to use the radio, you need a license from the communications
- * authority of your country.
- *
- */
-
-#include "sm.h"
-#include "sm_tbl_afsk2666.h"
-
-/* --------------------------------------------------------------------- */
-
-struct demod_state_afsk26 {
- unsigned int shreg;
- unsigned long descram;
- int dem_sum[8];
- int dem_sum_mean;
- int dem_cnt;
- unsigned int bit_pll;
- unsigned char last_sample;
- unsigned int dcd_shreg;
- int dcd_sum0, dcd_sum1, dcd_sum2;
- unsigned int dcd_time;
-};
-
-struct mod_state_afsk26 {
- unsigned int shreg;
- unsigned long scram;
- unsigned int bit_pll;
- unsigned int phinc;
- unsigned int tx_seq;
-};
-
-/* --------------------------------------------------------------------- */
-
-#define DESCRAM_TAP1 0x20000
-#define DESCRAM_TAP2 0x01000
-#define DESCRAM_TAP3 0x00001
-
-#define DESCRAM_TAPSH1 17
-#define DESCRAM_TAPSH2 12
-#define DESCRAM_TAPSH3 0
-
-#define SCRAM_TAP1 0x20000 /* X^17 */
-#define SCRAM_TAPN 0x00021 /* X^0+X^5 */
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_2666_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
-{
- struct mod_state_afsk26 *st = (struct mod_state_afsk26 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (!st->tx_seq++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->scram = ((st->scram << 1) | (st->scram & 1));
- st->scram ^= (!(st->shreg & 1));
- st->shreg >>= 1;
- if (st->scram & (SCRAM_TAP1 << 1))
- st->scram ^= SCRAM_TAPN << 1;
- st->phinc = afsk26_carfreq[!(st->scram & (SCRAM_TAP1 << 2))];
- }
- if (st->tx_seq >= 6)
- st->tx_seq = 0;
- *buf = OFFSCOS(st->bit_pll);
- st->bit_pll += st->phinc;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_2666_s16(struct sm_state *sm, short *buf, unsigned int buflen)
-{
- struct mod_state_afsk26 *st = (struct mod_state_afsk26 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (!st->tx_seq++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->scram = ((st->scram << 1) | (st->scram & 1));
- st->scram ^= (!(st->shreg & 1));
- st->shreg >>= 1;
- if (st->scram & (SCRAM_TAP1 << 1))
- st->scram ^= SCRAM_TAPN << 1;
- st->phinc = afsk26_carfreq[!(st->scram & (SCRAM_TAP1 << 2))];
- }
- if (st->tx_seq >= 6)
- st->tx_seq = 0;
- *buf = COS(st->bit_pll);
- st->bit_pll += st->phinc;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static __inline__ int convolution12_u8(const unsigned char *st, const int *coeff, int csum)
-{
- int sum = -0x80 * csum;
-
- sum += (st[0] * coeff[0]);
- sum += (st[-1] * coeff[1]);
- sum += (st[-2] * coeff[2]);
- sum += (st[-3] * coeff[3]);
- sum += (st[-4] * coeff[4]);
- sum += (st[-5] * coeff[5]);
- sum += (st[-6] * coeff[6]);
- sum += (st[-7] * coeff[7]);
- sum += (st[-8] * coeff[8]);
- sum += (st[-9] * coeff[9]);
- sum += (st[-10] * coeff[10]);
- sum += (st[-11] * coeff[11]);
-
- return sum;
-}
-
-static __inline__ int convolution12_s16(const short *st, const int *coeff, int csum)
-{
- int sum = 0;
-
- sum += (st[0] * coeff[0]);
- sum += (st[-1] * coeff[1]);
- sum += (st[-2] * coeff[2]);
- sum += (st[-3] * coeff[3]);
- sum += (st[-4] * coeff[4]);
- sum += (st[-5] * coeff[5]);
- sum += (st[-6] * coeff[6]);
- sum += (st[-7] * coeff[7]);
- sum += (st[-8] * coeff[8]);
- sum += (st[-9] * coeff[9]);
- sum += (st[-10] * coeff[10]);
- sum += (st[-11] * coeff[11]);
-
- sum >>= 8;
- return sum;
-}
-
-/* ---------------------------------------------------------------------- */
-
-#if 0
-static int binexp(unsigned int i)
-{
- int ret = 31;
-
- if (!i)
- return 0;
- if (i < 0x10000LU) {
- i <<= 16;
- ret -= 16;
- }
- if (i < 0x1000000LU) {
- i <<= 8;
- ret -= 8;
- }
- if (i < 0x10000000LU) {
- i <<= 4;
- ret -= 4;
- }
- if (i < 0x40000000LU) {
- i <<= 2;
- ret -= 2;
- }
- if (i < 0x80000000LU)
- ret -= 1;
- return ret;
-}
-
-static const sqrt_tab[16] = {
- 00000, 16384, 23170, 28378, 32768, 36636, 40132, 43348,
- 46341, 49152, 51811, 54340, 56756, 59073, 61303, 63455
-};
-
-
-static unsigned int int_sqrt_approx(unsigned int i)
-{
- unsigned int j;
-
- if (i < 16)
- return sqrt_tab[i] >> 14;
- j = binexp(i) >> 1;
- i >>= (j * 2 - 2);
- return (sqrt_tab[i & 0xf] << j) >> 15;
-}
-#endif
-
-/* --------------------------------------------------------------------- */
-
-extern unsigned int est_pwr(int i, int q)
-{
- unsigned int ui = abs(i);
- unsigned int uq = abs(q);
-
- if (uq > ui) {
- unsigned int tmp;
- tmp = ui;
- ui = uq;
- uq = tmp;
- }
- if (uq > (ui >> 1))
- return 7*(ui>>3) + 9*(uq>>4);
- else
- return ui + (uq>>2);
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demod_one_sample(struct sm_state *sm, struct demod_state_afsk26 *st, int curval,
- int loi, int loq, int hii, int hiq)
-{
- static const int pll_corr[2] = { -0xa00, 0xa00 };
- unsigned char curbit;
- unsigned int descx;
- int val;
-
- /*
- * estimate power
- */
- val = est_pwr(hii, hiq) - est_pwr(loi, loq);
- /*
- * estimate center value
- */
- st->dem_sum[0] += val >> 8;
- if ((++st->dem_cnt) >= 256) {
- st->dem_cnt = 0;
- st->dem_sum_mean = (st->dem_sum[0]+st->dem_sum[1]+
- st->dem_sum[2]+st->dem_sum[3]+
- st->dem_sum[4]+st->dem_sum[5]+
- st->dem_sum[6]+st->dem_sum[7]) >> 3;
- memmove(st->dem_sum+1, st->dem_sum,
- sizeof(st->dem_sum)-sizeof(st->dem_sum[0]));
- st->dem_sum[0] = 0;
- }
- /*
- * decision and bit clock regen
- */
- val -= st->dem_sum_mean;
- diag_add(sm, curval, val);
-
- st->dcd_shreg <<= 1;
- st->bit_pll += 0x1555;
- curbit = (val > 0);
- if (st->last_sample ^ curbit) {
- st->dcd_shreg |= 1;
- st->bit_pll += pll_corr[st->bit_pll < (0x8000+0x1555)];
- st->dcd_sum0 += 4*hweight8(st->dcd_shreg & 0x1e) -
- hweight16(st->dcd_shreg & 0xfe00);
- }
- st->last_sample = curbit;
- hdlcdrv_channelbit(&sm->hdrv, curbit);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 + st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 400;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffffu;
- st->descram = (st->descram << 1) | curbit;
- descx = st->descram ^ (st->descram >> 1);
- descx ^= ((descx >> DESCRAM_TAPSH1) ^
- (descx >> DESCRAM_TAPSH2));
- st->shreg >>= 1;
- st->shreg |= (!(descx & 1)) << 16;
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- diag_trigger(sm);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_2666_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
-{
- struct demod_state_afsk26 *st = (struct demod_state_afsk26 *)(&sm->d);
-
- for (; buflen > 0; buflen--, buf++) {
- demod_one_sample(sm, st, (*buf-0x80)<<8,
- convolution12_u8(buf, afsk26_dem_tables[0][0].i, AFSK26_DEM_SUM_I_0_0),
- convolution12_u8(buf, afsk26_dem_tables[0][0].q, AFSK26_DEM_SUM_Q_0_0),
- convolution12_u8(buf, afsk26_dem_tables[0][1].i, AFSK26_DEM_SUM_I_0_1),
- convolution12_u8(buf, afsk26_dem_tables[0][1].q, AFSK26_DEM_SUM_Q_0_1));
- demod_one_sample(sm, st, (*buf-0x80)<<8,
- convolution12_u8(buf, afsk26_dem_tables[1][0].i, AFSK26_DEM_SUM_I_1_0),
- convolution12_u8(buf, afsk26_dem_tables[1][0].q, AFSK26_DEM_SUM_Q_1_0),
- convolution12_u8(buf, afsk26_dem_tables[1][1].i, AFSK26_DEM_SUM_I_1_1),
- convolution12_u8(buf, afsk26_dem_tables[1][1].q, AFSK26_DEM_SUM_Q_1_1));
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_2666_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
-{
- struct demod_state_afsk26 *st = (struct demod_state_afsk26 *)(&sm->d);
-
- for (; buflen > 0; buflen--, buf++) {
- demod_one_sample(sm, st, *buf,
- convolution12_s16(buf, afsk26_dem_tables[0][0].i, AFSK26_DEM_SUM_I_0_0),
- convolution12_s16(buf, afsk26_dem_tables[0][0].q, AFSK26_DEM_SUM_Q_0_0),
- convolution12_s16(buf, afsk26_dem_tables[0][1].i, AFSK26_DEM_SUM_I_0_1),
- convolution12_s16(buf, afsk26_dem_tables[0][1].q, AFSK26_DEM_SUM_Q_0_1));
- demod_one_sample(sm, st, *buf,
- convolution12_s16(buf, afsk26_dem_tables[1][0].i, AFSK26_DEM_SUM_I_1_0),
- convolution12_s16(buf, afsk26_dem_tables[1][0].q, AFSK26_DEM_SUM_Q_1_0),
- convolution12_s16(buf, afsk26_dem_tables[1][1].i, AFSK26_DEM_SUM_I_1_1),
- convolution12_s16(buf, afsk26_dem_tables[1][1].q, AFSK26_DEM_SUM_Q_1_1));
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demod_init_2666(struct sm_state *sm)
-{
- struct demod_state_afsk26 *st = (struct demod_state_afsk26 *)(&sm->d);
-
- st->dcd_time = 400;
- st->dcd_sum0 = 2;
-}
-
-/* --------------------------------------------------------------------- */
-
-const struct modem_tx_info sm_afsk2666_tx = {
- "afsk2666", sizeof(struct mod_state_afsk26), AFSK26_SAMPLERATE, 2666,
- modulator_2666_u8, modulator_2666_s16, NULL
-};
-
-const struct modem_rx_info sm_afsk2666_rx = {
- "afsk2666", sizeof(struct demod_state_afsk26), AFSK26_SAMPLERATE, 2666, 12, 6,
- demodulator_2666_u8, demodulator_2666_s16, demod_init_2666
-};
-
-/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/soundmodem/sm_fsk9600.c b/drivers/net/hamradio/soundmodem/sm_fsk9600.c
deleted file mode 100644
index bc2fb53b15d3..000000000000
--- a/drivers/net/hamradio/soundmodem/sm_fsk9600.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*****************************************************************************/
-
-/*
- * sm_fsk9600.c -- soundcard radio modem driver,
- * 9600 baud G3RUH compatible FSK modem
- *
- * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Please note that the GPL allows you to use the driver, NOT the radio.
- * In order to use the radio, you need a license from the communications
- * authority of your country.
- *
- */
-
-#include "sm.h"
-#include "sm_tbl_fsk9600.h"
-
-/* --------------------------------------------------------------------- */
-
-struct demod_state_fsk96 {
- unsigned int shreg;
- unsigned long descram;
- unsigned int bit_pll;
- unsigned char last_sample;
- unsigned int dcd_shreg;
- int dcd_sum0, dcd_sum1, dcd_sum2;
- unsigned int dcd_time;
-};
-
-struct mod_state_fsk96 {
- unsigned int shreg;
- unsigned long scram;
- unsigned char tx_bit;
- unsigned char *txtbl;
- unsigned int txphase;
-};
-
-/* --------------------------------------------------------------------- */
-
-#define DESCRAM_TAP1 0x20000
-#define DESCRAM_TAP2 0x01000
-#define DESCRAM_TAP3 0x00001
-
-#define DESCRAM_TAPSH1 17
-#define DESCRAM_TAPSH2 12
-#define DESCRAM_TAPSH3 0
-
-#define SCRAM_TAP1 0x20000 /* X^17 */
-#define SCRAM_TAPN 0x00021 /* X^0+X^5 */
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_9600_4_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
-{
- struct mod_state_fsk96 *st = (struct mod_state_fsk96 *)(&sm->m);
-
- for (; buflen > 0; buflen--) {
- if (!st->txphase++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->scram = (st->scram << 1) | (st->scram & 1);
- st->scram ^= !(st->shreg & 1);
- st->shreg >>= 1;
- if (st->scram & (SCRAM_TAP1 << 1))
- st->scram ^= SCRAM_TAPN << 1;
- st->tx_bit = (st->tx_bit << 1) | (!!(st->scram & (SCRAM_TAP1 << 2)));
- st->txtbl = fsk96_txfilt_4 + (st->tx_bit & 0xff);
- }
- if (st->txphase >= 4)
- st->txphase = 0;
- *buf++ = *st->txtbl;
- st->txtbl += 0x100;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_9600_4_s16(struct sm_state *sm, short *buf, unsigned int buflen)
-{
- struct mod_state_fsk96 *st = (struct mod_state_fsk96 *)(&sm->m);
-
- for (; buflen > 0; buflen--) {
- if (!st->txphase++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->scram = (st->scram << 1) | (st->scram & 1);
- st->scram ^= !(st->shreg & 1);
- st->shreg >>= 1;
- if (st->scram & (SCRAM_TAP1 << 1))
- st->scram ^= SCRAM_TAPN << 1;
- st->tx_bit = (st->tx_bit << 1) | (!!(st->scram & (SCRAM_TAP1 << 2)));
- st->txtbl = fsk96_txfilt_4 + (st->tx_bit & 0xff);
- }
- if (st->txphase >= 4)
- st->txphase = 0;
- *buf++ = ((*st->txtbl)-0x80) << 8;
- st->txtbl += 0x100;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_9600_4_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
-{
- struct demod_state_fsk96 *st = (struct demod_state_fsk96 *)(&sm->d);
- static const int pll_corr[2] = { -0x1000, 0x1000 };
- unsigned char curbit;
- unsigned int descx;
-
- for (; buflen > 0; buflen--, buf++) {
- st->dcd_shreg <<= 1;
- st->bit_pll += 0x4000;
- curbit = (*buf >= 0x80);
- if (st->last_sample ^ curbit) {
- st->dcd_shreg |= 1;
- st->bit_pll += pll_corr[st->bit_pll < 0xa000];
- st->dcd_sum0 += 8 * hweight8(st->dcd_shreg & 0x0c) -
- !!(st->dcd_shreg & 0x10);
- }
- st->last_sample = curbit;
- hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 240;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->descram = (st->descram << 1) | curbit;
- descx = st->descram ^ (st->descram >> 1);
- descx ^= ((descx >> DESCRAM_TAPSH1) ^
- (descx >> DESCRAM_TAPSH2));
- st->shreg >>= 1;
- st->shreg |= (!(descx & 1)) << 16;
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- diag_trigger(sm);
- }
- diag_add_one(sm, ((short)(*buf - 0x80)) << 8);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_9600_4_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
-{
- struct demod_state_fsk96 *st = (struct demod_state_fsk96 *)(&sm->d);
- static const int pll_corr[2] = { -0x1000, 0x1000 };
- unsigned char curbit;
- unsigned int descx;
-
- for (; buflen > 0; buflen--, buf++) {
- st->dcd_shreg <<= 1;
- st->bit_pll += 0x4000;
- curbit = (*buf >= 0);
- if (st->last_sample ^ curbit) {
- st->dcd_shreg |= 1;
- st->bit_pll += pll_corr[st->bit_pll < 0xa000];
- st->dcd_sum0 += 8 * hweight8(st->dcd_shreg & 0x0c) -
- !!(st->dcd_shreg & 0x10);
- }
- st->last_sample = curbit;
- hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 240;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->descram = (st->descram << 1) | curbit;
- descx = st->descram ^ (st->descram >> 1);
- descx ^= ((descx >> DESCRAM_TAPSH1) ^
- (descx >> DESCRAM_TAPSH2));
- st->shreg >>= 1;
- st->shreg |= (!(descx & 1)) << 16;
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- diag_trigger(sm);
- }
- diag_add_one(sm, *buf);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_9600_5_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
-{
- struct mod_state_fsk96 *st = (struct mod_state_fsk96 *)(&sm->m);
-
- for (; buflen > 0; buflen--) {
- if (!st->txphase++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->scram = (st->scram << 1) | (st->scram & 1);
- st->scram ^= !(st->shreg & 1);
- st->shreg >>= 1;
- if (st->scram & (SCRAM_TAP1 << 1))
- st->scram ^= SCRAM_TAPN << 1;
- st->tx_bit = (st->tx_bit << 1) | (!!(st->scram & (SCRAM_TAP1 << 2)));
- st->txtbl = fsk96_txfilt_5 + (st->tx_bit & 0xff);
- }
- if (st->txphase >= 5)
- st->txphase = 0;
- *buf++ = *st->txtbl;
- st->txtbl += 0x100;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_9600_5_s16(struct sm_state *sm, short *buf, unsigned int buflen)
-{
- struct mod_state_fsk96 *st = (struct mod_state_fsk96 *)(&sm->m);
-
- for (; buflen > 0; buflen--) {
- if (!st->txphase++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->scram = (st->scram << 1) | (st->scram & 1);
- st->scram ^= !(st->shreg & 1);
- st->shreg >>= 1;
- if (st->scram & (SCRAM_TAP1 << 1))
- st->scram ^= SCRAM_TAPN << 1;
- st->tx_bit = (st->tx_bit << 1) | (!!(st->scram & (SCRAM_TAP1 << 2)));
- st->txtbl = fsk96_txfilt_5 + (st->tx_bit & 0xff);
- }
- if (st->txphase >= 5)
- st->txphase = 0;
- *buf++ = ((*st->txtbl)-0x80)<<8;
- st->txtbl += 0x100;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_9600_5_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
-{
- struct demod_state_fsk96 *st = (struct demod_state_fsk96 *)(&sm->d);
- static const int pll_corr[2] = { -0x1000, 0x1000 };
- unsigned char curbit;
- unsigned int descx;
-
- for (; buflen > 0; buflen--, buf++) {
- st->dcd_shreg <<= 1;
- st->bit_pll += 0x3333;
- curbit = (*buf >= 0x80);
- if (st->last_sample ^ curbit) {
- st->dcd_shreg |= 1;
- st->bit_pll += pll_corr[st->bit_pll < 0x9999];
- st->dcd_sum0 += 16 * hweight8(st->dcd_shreg & 0x0c) -
- hweight8(st->dcd_shreg & 0x70);
- }
- st->last_sample = curbit;
- hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 240;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->descram = (st->descram << 1) | curbit;
- descx = st->descram ^ (st->descram >> 1);
- descx ^= ((descx >> DESCRAM_TAPSH1) ^
- (descx >> DESCRAM_TAPSH2));
- st->shreg >>= 1;
- st->shreg |= (!(descx & 1)) << 16;
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- diag_trigger(sm);
- }
- diag_add_one(sm, ((short)(*buf - 0x80)) << 8);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_9600_5_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
-{
- struct demod_state_fsk96 *st = (struct demod_state_fsk96 *)(&sm->d);
- static const int pll_corr[2] = { -0x1000, 0x1000 };
- unsigned char curbit;
- unsigned int descx;
-
- for (; buflen > 0; buflen--, buf++) {
- st->dcd_shreg <<= 1;
- st->bit_pll += 0x3333;
- curbit = (*buf >= 0);
- if (st->last_sample ^ curbit) {
- st->dcd_shreg |= 1;
- st->bit_pll += pll_corr[st->bit_pll < 0x9999];
- st->dcd_sum0 += 16 * hweight8(st->dcd_shreg & 0x0c) -
- hweight8(st->dcd_shreg & 0x70);
- }
- st->last_sample = curbit;
- hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 240;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->descram = (st->descram << 1) | curbit;
- descx = st->descram ^ (st->descram >> 1);
- descx ^= ((descx >> DESCRAM_TAPSH1) ^
- (descx >> DESCRAM_TAPSH2));
- st->shreg >>= 1;
- st->shreg |= (!(descx & 1)) << 16;
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- diag_trigger(sm);
- }
- diag_add_one(sm, *buf);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demod_init_9600(struct sm_state *sm)
-{
- struct demod_state_fsk96 *st = (struct demod_state_fsk96 *)(&sm->d);
-
- st->dcd_time = 240;
- st->dcd_sum0 = 2;
-}
-
-/* --------------------------------------------------------------------- */
-
-const struct modem_tx_info sm_fsk9600_4_tx = {
- "fsk9600", sizeof(struct mod_state_fsk96), 38400, 9600,
- modulator_9600_4_u8, modulator_9600_4_s16, NULL
-};
-
-const struct modem_rx_info sm_fsk9600_4_rx = {
- "fsk9600", sizeof(struct demod_state_fsk96), 38400, 9600, 1, 4,
- demodulator_9600_4_u8, demodulator_9600_4_s16, demod_init_9600
-};
-
-/* --------------------------------------------------------------------- */
-
-const struct modem_tx_info sm_fsk9600_5_tx = {
- "fsk9600", sizeof(struct mod_state_fsk96), 48000, 9600,
- modulator_9600_5_u8, modulator_9600_5_s16, NULL
-};
-
-const struct modem_rx_info sm_fsk9600_5_rx = {
- "fsk9600", sizeof(struct demod_state_fsk96), 48000, 9600, 1, 5,
- demodulator_9600_5_u8, demodulator_9600_5_s16, demod_init_9600
-};
-
-/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/soundmodem/sm_hapn4800.c b/drivers/net/hamradio/soundmodem/sm_hapn4800.c
deleted file mode 100644
index f6babcd9d323..000000000000
--- a/drivers/net/hamradio/soundmodem/sm_hapn4800.c
+++ /dev/null
@@ -1,560 +0,0 @@
-/*****************************************************************************/
-
-/*
- * sm_hapn4800.c -- soundcard radio modem driver, 4800 baud HAPN modem
- *
- * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Please note that the GPL allows you to use the driver, NOT the radio.
- * In order to use the radio, you need a license from the communications
- * authority of your country.
- *
- *
- * This module implements a (hopefully) HAPN (Hamilton Area Packet
- * Network) compatible 4800 baud modem.
- * The HAPN modem uses kind of "duobinary signalling" (not really,
- * duobinary signalling gives ... 0 0 -1 0 1 0 0 ... at the sampling
- * instants, whereas HAPN signalling gives ... 0 0 -1 1 0 0 ..., see
- * Proakis, Digital Communications).
- * The code is untested. It is compatible with itself (i.e. it can decode
- * the packets it sent), but I could not test if it is compatible with
- * any "real" HAPN modem, since noone uses it in my region of the world.
- * Feedback therefore welcome.
- */
-
-#include "sm.h"
-#include "sm_tbl_hapn4800.h"
-
-/* --------------------------------------------------------------------- */
-
-struct demod_state_hapn48 {
- unsigned int shreg;
- unsigned int bit_pll;
- unsigned char last_bit;
- unsigned char last_bit2;
- unsigned int dcd_shreg;
- int dcd_sum0, dcd_sum1, dcd_sum2;
- unsigned int dcd_time;
- int lvlhi, lvllo;
-};
-
-struct mod_state_hapn48 {
- unsigned int shreg;
- unsigned char tx_bit;
- unsigned int tx_seq;
- const unsigned char *tbl;
-};
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_hapn4800_10_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
-{
- struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (!st->tx_seq++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = ((st->tx_bit << 1) |
- (st->tx_bit & 1));
- st->tx_bit ^= (!(st->shreg & 1));
- st->shreg >>= 1;
- st->tbl = hapn48_txfilt_10 + (st->tx_bit & 0xf);
- }
- if (st->tx_seq >= 10)
- st->tx_seq = 0;
- *buf = *st->tbl;
- st->tbl += 0x10;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_hapn4800_10_s16(struct sm_state *sm, short *buf, unsigned int buflen)
-{
- struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (!st->tx_seq++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = ((st->tx_bit << 1) |
- (st->tx_bit & 1));
- st->tx_bit ^= (!(st->shreg & 1));
- st->shreg >>= 1;
- st->tbl = hapn48_txfilt_10 + (st->tx_bit & 0xf);
- }
- if (st->tx_seq >= 10)
- st->tx_seq = 0;
- *buf = ((*st->tbl)-0x80)<<8;
- st->tbl += 0x10;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_hapn4800_8_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
-{
- struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (!st->tx_seq++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = (st->tx_bit << 1) | (st->tx_bit & 1);
- st->tx_bit ^= !(st->shreg & 1);
- st->shreg >>= 1;
- st->tbl = hapn48_txfilt_8 + (st->tx_bit & 0xf);
- }
- if (st->tx_seq >= 8)
- st->tx_seq = 0;
- *buf = *st->tbl;
- st->tbl += 0x10;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_hapn4800_8_s16(struct sm_state *sm, short *buf, unsigned int buflen)
-{
- struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (!st->tx_seq++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = (st->tx_bit << 1) | (st->tx_bit & 1);
- st->tx_bit ^= !(st->shreg & 1);
- st->shreg >>= 1;
- st->tbl = hapn48_txfilt_8 + (st->tx_bit & 0xf);
- }
- if (st->tx_seq >= 8)
- st->tx_seq = 0;
- *buf = ((*st->tbl)-0x80)<<8;
- st->tbl += 0x10;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_hapn4800_pm10_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
-{
- struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (!st->tx_seq++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = ((st->tx_bit << 1) |
- (st->tx_bit & 1));
- st->tx_bit ^= (!(st->shreg & 1));
- st->shreg >>= 1;
- st->tbl = hapn48_txfilt_pm10 + (st->tx_bit & 0xf);
- }
- if (st->tx_seq >= 10)
- st->tx_seq = 0;
- *buf = *st->tbl;
- st->tbl += 0x10;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_hapn4800_pm10_s16(struct sm_state *sm, short *buf, unsigned int buflen)
-{
- struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (!st->tx_seq++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = ((st->tx_bit << 1) |
- (st->tx_bit & 1));
- st->tx_bit ^= (!(st->shreg & 1));
- st->shreg >>= 1;
- st->tbl = hapn48_txfilt_pm10 + (st->tx_bit & 0xf);
- }
- if (st->tx_seq >= 10)
- st->tx_seq = 0;
- *buf = ((*st->tbl)-0x80)<<8;
- st->tbl += 0x10;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_hapn4800_pm8_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
-{
- struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (!st->tx_seq++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = (st->tx_bit << 1) | (st->tx_bit & 1);
- st->tx_bit ^= !(st->shreg & 1);
- st->shreg >>= 1;
- st->tbl = hapn48_txfilt_pm8 + (st->tx_bit & 0xf);
- }
- if (st->tx_seq >= 8)
- st->tx_seq = 0;
- *buf = *st->tbl;
- st->tbl += 0x10;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_hapn4800_pm8_s16(struct sm_state *sm, short *buf, unsigned int buflen)
-{
- struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
-
- for (; buflen > 0; buflen--, buf++) {
- if (!st->tx_seq++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = (st->tx_bit << 1) | (st->tx_bit & 1);
- st->tx_bit ^= !(st->shreg & 1);
- st->shreg >>= 1;
- st->tbl = hapn48_txfilt_pm8 + (st->tx_bit & 0xf);
- }
- if (st->tx_seq >= 8)
- st->tx_seq = 0;
- *buf = ((*st->tbl)-0x80)<<8;
- st->tbl += 0x10;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_hapn4800_10_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
-{
- struct demod_state_hapn48 *st = (struct demod_state_hapn48 *)(&sm->d);
- static const int pll_corr[2] = { -0x800, 0x800 };
- int curst, cursync;
- int inv;
-
- for (; buflen > 0; buflen--, buf++) {
- inv = ((int)(buf[-2])-0x80) << 8;
- st->lvlhi = (st->lvlhi * 65309) >> 16; /* decay */
- st->lvllo = (st->lvllo * 65309) >> 16; /* decay */
- if (inv > st->lvlhi)
- st->lvlhi = inv;
- if (inv < st->lvllo)
- st->lvllo = inv;
- if (buflen & 1)
- st->dcd_shreg <<= 1;
- st->bit_pll += 0x199a;
- curst = cursync = 0;
- if (inv > st->lvlhi >> 1) {
- curst = 1;
- cursync = (buf[-2] > buf[-1] && buf[-2] > buf[-3] &&
- buf[-2] > buf[-0] && buf[-2] > buf[-4]);
- } else if (inv < st->lvllo >> 1) {
- curst = -1;
- cursync = (buf[-2] < buf[-1] && buf[-2] < buf[-3] &&
- buf[-2] < buf[-0] && buf[-2] < buf[-4]);
- }
- if (cursync) {
- st->dcd_shreg |= cursync;
- st->bit_pll += pll_corr[((st->bit_pll - 0x8000u) & 0xffffu) < 0x8ccdu];
- st->dcd_sum0 += 16 * hweight32(st->dcd_shreg & 0x18c6318c) -
- hweight32(st->dcd_shreg & 0xe739ce70);
- }
- hdlcdrv_channelbit(&sm->hdrv, cursync);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 240;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->last_bit2 = st->last_bit;
- if (curst < 0)
- st->last_bit = 0;
- else if (curst > 0)
- st->last_bit = 1;
- st->shreg >>= 1;
- st->shreg |= ((st->last_bit ^ st->last_bit2 ^ 1) & 1) << 16;
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- diag_trigger(sm);
- }
- diag_add_one(sm, inv);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_hapn4800_10_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
-{
- struct demod_state_hapn48 *st = (struct demod_state_hapn48 *)(&sm->d);
- static const int pll_corr[2] = { -0x800, 0x800 };
- int curst, cursync;
- int inv;
-
- for (; buflen > 0; buflen--, buf++) {
- inv = buf[-2];
- st->lvlhi = (st->lvlhi * 65309) >> 16; /* decay */
- st->lvllo = (st->lvllo * 65309) >> 16; /* decay */
- if (inv > st->lvlhi)
- st->lvlhi = inv;
- if (inv < st->lvllo)
- st->lvllo = inv;
- if (buflen & 1)
- st->dcd_shreg <<= 1;
- st->bit_pll += 0x199a;
- curst = cursync = 0;
- if (inv > st->lvlhi >> 1) {
- curst = 1;
- cursync = (buf[-2] > buf[-1] && buf[-2] > buf[-3] &&
- buf[-2] > buf[-0] && buf[-2] > buf[-4]);
- } else if (inv < st->lvllo >> 1) {
- curst = -1;
- cursync = (buf[-2] < buf[-1] && buf[-2] < buf[-3] &&
- buf[-2] < buf[-0] && buf[-2] < buf[-4]);
- }
- if (cursync) {
- st->dcd_shreg |= cursync;
- st->bit_pll += pll_corr[((st->bit_pll - 0x8000u) & 0xffffu) < 0x8ccdu];
- st->dcd_sum0 += 16 * hweight32(st->dcd_shreg & 0x18c6318c) -
- hweight32(st->dcd_shreg & 0xe739ce70);
- }
- hdlcdrv_channelbit(&sm->hdrv, cursync);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 240;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->last_bit2 = st->last_bit;
- if (curst < 0)
- st->last_bit = 0;
- else if (curst > 0)
- st->last_bit = 1;
- st->shreg >>= 1;
- st->shreg |= ((st->last_bit ^ st->last_bit2 ^ 1) & 1) << 16;
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- diag_trigger(sm);
- }
- diag_add_one(sm, inv);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_hapn4800_8_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
-{
- struct demod_state_hapn48 *st = (struct demod_state_hapn48 *)(&sm->d);
- static const int pll_corr[2] = { -0x800, 0x800 };
- int curst, cursync;
- int inv;
-
- for (; buflen > 0; buflen--, buf++) {
- inv = ((int)(buf[-2])-0x80) << 8;
- st->lvlhi = (st->lvlhi * 65309) >> 16; /* decay */
- st->lvllo = (st->lvllo * 65309) >> 16; /* decay */
- if (inv > st->lvlhi)
- st->lvlhi = inv;
- if (inv < st->lvllo)
- st->lvllo = inv;
- if (buflen & 1)
- st->dcd_shreg <<= 1;
- st->bit_pll += 0x2000;
- curst = cursync = 0;
- if (inv > st->lvlhi >> 1) {
- curst = 1;
- cursync = (buf[-2] > buf[-1] && buf[-2] > buf[-3] &&
- buf[-2] > buf[-0] && buf[-2] > buf[-4]);
- } else if (inv < st->lvllo >> 1) {
- curst = -1;
- cursync = (buf[-2] < buf[-1] && buf[-2] < buf[-3] &&
- buf[-2] < buf[-0] && buf[-2] < buf[-4]);
- }
- if (cursync) {
- st->dcd_shreg |= cursync;
- st->bit_pll += pll_corr[((st->bit_pll - 0x8000u) & 0xffffu) < 0x9000u];
- st->dcd_sum0 += 16 * hweight32(st->dcd_shreg & 0x44444444) -
- hweight32(st->dcd_shreg & 0xbbbbbbbb);
- }
- hdlcdrv_channelbit(&sm->hdrv, cursync);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 240;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->last_bit2 = st->last_bit;
- if (curst < 0)
- st->last_bit = 0;
- else if (curst > 0)
- st->last_bit = 1;
- st->shreg >>= 1;
- st->shreg |= ((st->last_bit ^ st->last_bit2 ^ 1) & 1) << 16;
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- diag_trigger(sm);
- }
- diag_add_one(sm, inv);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_hapn4800_8_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
-{
- struct demod_state_hapn48 *st = (struct demod_state_hapn48 *)(&sm->d);
- static const int pll_corr[2] = { -0x800, 0x800 };
- int curst, cursync;
- int inv;
-
- for (; buflen > 0; buflen--, buf++) {
- inv = buf[-2];
- st->lvlhi = (st->lvlhi * 65309) >> 16; /* decay */
- st->lvllo = (st->lvllo * 65309) >> 16; /* decay */
- if (inv > st->lvlhi)
- st->lvlhi = inv;
- if (inv < st->lvllo)
- st->lvllo = inv;
- if (buflen & 1)
- st->dcd_shreg <<= 1;
- st->bit_pll += 0x2000;
- curst = cursync = 0;
- if (inv > st->lvlhi >> 1) {
- curst = 1;
- cursync = (buf[-2] > buf[-1] && buf[-2] > buf[-3] &&
- buf[-2] > buf[-0] && buf[-2] > buf[-4]);
- } else if (inv < st->lvllo >> 1) {
- curst = -1;
- cursync = (buf[-2] < buf[-1] && buf[-2] < buf[-3] &&
- buf[-2] < buf[-0] && buf[-2] < buf[-4]);
- }
- if (cursync) {
- st->dcd_shreg |= cursync;
- st->bit_pll += pll_corr[((st->bit_pll - 0x8000u) & 0xffffu) < 0x9000u];
- st->dcd_sum0 += 16 * hweight32(st->dcd_shreg & 0x44444444) -
- hweight32(st->dcd_shreg & 0xbbbbbbbb);
- }
- hdlcdrv_channelbit(&sm->hdrv, cursync);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 240;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffff;
- st->last_bit2 = st->last_bit;
- if (curst < 0)
- st->last_bit = 0;
- else if (curst > 0)
- st->last_bit = 1;
- st->shreg >>= 1;
- st->shreg |= ((st->last_bit ^ st->last_bit2 ^ 1) & 1) << 16;
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- diag_trigger(sm);
- }
- diag_add_one(sm, inv);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demod_init_hapn4800(struct sm_state *sm)
-{
- struct demod_state_hapn48 *st = (struct demod_state_hapn48 *)(&sm->d);
-
- st->dcd_time = 120;
- st->dcd_sum0 = 2;
-}
-
-/* --------------------------------------------------------------------- */
-
-const struct modem_tx_info sm_hapn4800_8_tx = {
- "hapn4800", sizeof(struct mod_state_hapn48), 38400, 4800,
- modulator_hapn4800_8_u8, modulator_hapn4800_8_s16, NULL
-};
-
-const struct modem_rx_info sm_hapn4800_8_rx = {
- "hapn4800", sizeof(struct demod_state_hapn48), 38400, 4800, 5, 8,
- demodulator_hapn4800_8_u8, demodulator_hapn4800_8_s16, demod_init_hapn4800
-};
-
-/* --------------------------------------------------------------------- */
-
-const struct modem_tx_info sm_hapn4800_10_tx = {
- "hapn4800", sizeof(struct mod_state_hapn48), 48000, 4800,
- modulator_hapn4800_10_u8, modulator_hapn4800_10_s16, NULL
-};
-
-const struct modem_rx_info sm_hapn4800_10_rx = {
- "hapn4800", sizeof(struct demod_state_hapn48), 48000, 4800, 5, 10,
- demodulator_hapn4800_10_u8, demodulator_hapn4800_10_s16, demod_init_hapn4800
-};
-
-/* --------------------------------------------------------------------- */
-
-const struct modem_tx_info sm_hapn4800_pm8_tx = {
- "hapn4800pm", sizeof(struct mod_state_hapn48), 38400, 4800,
- modulator_hapn4800_pm8_u8, modulator_hapn4800_pm8_s16, NULL
-};
-
-const struct modem_rx_info sm_hapn4800_pm8_rx = {
- "hapn4800pm", sizeof(struct demod_state_hapn48), 38400, 4800, 5, 8,
- demodulator_hapn4800_8_u8, demodulator_hapn4800_8_s16, demod_init_hapn4800
-};
-
-/* --------------------------------------------------------------------- */
-
-const struct modem_tx_info sm_hapn4800_pm10_tx = {
- "hapn4800pm", sizeof(struct mod_state_hapn48), 48000, 4800,
- modulator_hapn4800_pm10_u8, modulator_hapn4800_pm10_s16, NULL
-};
-
-const struct modem_rx_info sm_hapn4800_pm10_rx = {
- "hapn4800pm", sizeof(struct demod_state_hapn48), 48000, 4800, 5, 10,
- demodulator_hapn4800_10_u8, demodulator_hapn4800_10_s16, demod_init_hapn4800
-};
-
-/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/soundmodem/sm_psk4800.c b/drivers/net/hamradio/soundmodem/sm_psk4800.c
deleted file mode 100644
index cbb49042b508..000000000000
--- a/drivers/net/hamradio/soundmodem/sm_psk4800.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*****************************************************************************/
-
-/*
- * sm_psk4800.c -- soundcard radio modem driver, 4800 baud 8PSK modem
- *
- * Copyright (C) 1997 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Please note that the GPL allows you to use the driver, NOT the radio.
- * In order to use the radio, you need a license from the communications
- * authority of your country.
- *
- */
-
-#include "sm.h"
-#include "sm_tbl_psk4800.h"
-
-/* --------------------------------------------------------------------- */
-
-#define DESCRAM_TAP1 0x20000
-#define DESCRAM_TAP2 0x01000
-#define DESCRAM_TAP3 0x00001
-
-#define DESCRAM_TAPSH1 17
-#define DESCRAM_TAPSH2 12
-#define DESCRAM_TAPSH3 0
-
-#define SCRAM_TAP1 0x20000 /* X^17 */
-#define SCRAM_TAPN 0x00021 /* X^0+X^5 */
-
-#define SCRAM_SHIFT 17
-
-/* --------------------------------------------------------------------- */
-
-struct demod_state_psk48 {
- /*
- * input mixer and lowpass
- */
- short infi[PSK48_RXF_LEN/2], infq[PSK48_RXF_LEN/2];
- unsigned int downmixer;
- int ovrphase;
- short magi, magq;
- /*
- * sampling instant recovery
- */
- int pwrhist[5];
- unsigned int s_phase;
- int cur_sync;
- /*
- * phase recovery
- */
- short cur_phase_dev;
- short last_ph_err;
- unsigned short pskph;
- unsigned int phase;
- unsigned short last_pskph;
- unsigned char cur_raw, last_raw, rawbits;
- /*
- * decoding
- */
- unsigned int shreg;
- unsigned long descram;
- unsigned int bit_pll;
- unsigned char last_sample;
- unsigned int dcd_shreg;
- int dcd_sum0, dcd_sum1, dcd_sum2;
- unsigned int dcd_time;
-};
-
-struct mod_state_psk48 {
- unsigned char txbits[PSK48_TXF_NUMSAMPLES];
- unsigned short txphase;
- unsigned int shreg;
- unsigned long scram;
- const short *tbl;
- unsigned int txseq;
-};
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_4800_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
-{
- struct mod_state_psk48 *st = (struct mod_state_psk48 *)(&sm->m);
- int i, j;
- int si, sq;
-
- for (; buflen > 0; buflen--, buf++) {
- if (!st->txseq++) {
- memmove(st->txbits+1, st->txbits,
- sizeof(st->txbits)-sizeof(st->txbits[0]));
- for (i = 0; i < 3; i++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->scram = (st->scram << 1) |
- (st->shreg & 1);
- st->shreg >>= 1;
- if (st->scram & SCRAM_TAP1)
- st->scram ^= SCRAM_TAPN;
- }
- j = (st->scram >> (SCRAM_SHIFT+3)) & 7;
- st->txbits[0] -= (j ^ (j >> 1));
- st->txbits[0] &= 7;
- st->tbl = psk48_tx_table;
- }
- if (st->txseq >= PSK48_TXF_OVERSAMPLING)
- st->txseq = 0;
- for (j = si = sq = 0; j < PSK48_TXF_NUMSAMPLES; j++, st->tbl += 16) {
- si += st->tbl[st->txbits[j]];
- sq += st->tbl[st->txbits[j]+8];
- }
- *buf = ((si*COS(st->txphase)+ sq*SIN(st->txphase)) >> 23) + 0x80;
- st->txphase = (st->txphase + PSK48_PHASEINC) & 0xffffu;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void modulator_4800_s16(struct sm_state *sm, short *buf, unsigned int buflen)
-{
- struct mod_state_psk48 *st = (struct mod_state_psk48 *)(&sm->m);
- int i, j;
- int si, sq;
-
- for (; buflen > 0; buflen--, buf++) {
- if (!st->txseq++) {
- memmove(st->txbits+1, st->txbits,
- sizeof(st->txbits)-sizeof(st->txbits[0]));
- for (i = 0; i < 3; i++) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->scram = (st->scram << 1) |
- (st->shreg & 1);
- st->shreg >>= 1;
- if (st->scram & SCRAM_TAP1)
- st->scram ^= SCRAM_TAPN;
- }
- j = (st->scram >> (SCRAM_SHIFT+3)) & 7;
- st->txbits[0] -= (j ^ (j >> 1));
- st->txbits[0] &= 7;
- st->tbl = psk48_tx_table;
- }
- if (st->txseq >= PSK48_TXF_OVERSAMPLING)
- st->txseq = 0;
- for (j = si = sq = 0; j < PSK48_TXF_NUMSAMPLES; j++, st->tbl += 16) {
- si += st->tbl[st->txbits[j]];
- sq += st->tbl[st->txbits[j]+8];
- }
- *buf = (si*COS(st->txphase)+ sq*SIN(st->txphase)) >> 15;
- st->txphase = (st->txphase + PSK48_PHASEINC) & 0xffffu;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static __inline__ unsigned short tbl_atan(short q, short i)
-{
- short tmp;
- unsigned short argoffs = 0;
-
- if (i == 0 && q == 0)
- return 0;
- switch (((q < 0) << 1) | (i < 0)) {
- case 0:
- break;
- case 1:
- tmp = q;
- q = -i;
- i = tmp;
- argoffs = 0x4000;
- break;
- case 3:
- q = -q;
- i = -i;
- argoffs = 0x8000;
- break;
- case 2:
- tmp = -q;
- q = i;
- i = tmp;
- argoffs = 0xc000;
- break;
- }
- if (q > i) {
- tmp = i / q * ATAN_TABLEN;
- return (argoffs+0x4000-atan_tab[((i<<15)/q*ATAN_TABLEN>>15)])
- &0xffffu;
- }
- return (argoffs+atan_tab[((q<<15)/i*ATAN_TABLEN)>>15])&0xffffu;
-}
-
-#define ATAN(q,i) tbl_atan(q, i)
-
-/* --------------------------------------------------------------------- */
-
-static void demod_psk48_baseband(struct sm_state *sm, struct demod_state_psk48 *st,
- short vali, short valq)
-{
- int i, j;
-
- st->magi = vali;
- st->magq = valq;
- memmove(st->pwrhist+1, st->pwrhist,
- sizeof(st->pwrhist)-sizeof(st->pwrhist[0]));
- st->pwrhist[0] = st->magi * st->magi +
- st->magq * st->magq;
- st->cur_sync = ((st->pwrhist[4] >> 2) > st->pwrhist[2] &&
- (st->pwrhist[0] >> 2) > st->pwrhist[2] &&
- st-> pwrhist[3] > st->pwrhist[2] &&
- st->pwrhist[1] > st->pwrhist[2]);
- st->s_phase &= 0xffff;
- st->s_phase += PSK48_SPHASEINC;
- st->dcd_shreg <<= 1;
- if (st->cur_sync) {
- if (st->s_phase >= (0x8000 + 5*PSK48_SPHASEINC/2))
- st->s_phase -= PSK48_SPHASEINC/6;
- else
- st->s_phase += PSK48_SPHASEINC/6;
- st->dcd_sum0 = 4*hweight8(st->dcd_shreg & 0xf8)-
- hweight16(st->dcd_shreg & 0x1f00);
- }
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 + st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 240;
- }
- if (st->s_phase < 0x10000)
- return;
- /*
- * sample one constellation
- */
- st->last_pskph = st->pskph;
- st->pskph = (ATAN(st->magq, st->magi)-
- st->phase) & 0xffffu;
- st->last_ph_err = (st->pskph & 0x1fffu) - 0x1000;
- st->phase += st->last_ph_err/16;
- st->last_raw = st->cur_raw;
- st->cur_raw = ((st->pskph >> 13) & 7);
- i = (st->cur_raw - st->last_raw) & 7;
- st->rawbits = i ^ (i >> 1) ^ (i >> 2);
- st->descram = (st->descram << 3) | (st->rawbits);
- hdlcdrv_channelbit(&sm->hdrv, st->descram & 4);
- hdlcdrv_channelbit(&sm->hdrv, st->descram & 2);
- hdlcdrv_channelbit(&sm->hdrv, st->descram & 1);
- i = (((st->descram >> DESCRAM_TAPSH1) & 7) ^
- ((st->descram >> DESCRAM_TAPSH2) & 7) ^
- ((st->descram >> DESCRAM_TAPSH3) & 7));
- for (j = 4; j; j >>= 1) {
- st->shreg >>= 1;
- st->shreg |= (!!(i & j)) << 16;
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- }
-
-#if 0
- st->dcd_shreg <<= 1;
- st->bit_pll += 0x4000;
- curbit = (*buf >= 0x80);
- if (st->last_sample ^ curbit) {
- st->dcd_shreg |= 1;
- st->bit_pll += pll_corr
- [st->bit_pll < 0xa000];
- st->dcd_sum0 += 8 *
- hweight8(st->dcd_shreg & 0x0c) -
- !!(st->dcd_shreg & 0x10);
- }
- st->last_sample = curbit;
- hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
- if ((--st->dcd_time) <= 0) {
- hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
- st->dcd_sum1 +
- st->dcd_sum2) < 0);
- st->dcd_sum2 = st->dcd_sum1;
- st->dcd_sum1 = st->dcd_sum0;
- st->dcd_sum0 = 2; /* slight bias */
- st->dcd_time = 240;
- }
- if (st->bit_pll >= 0x10000) {
- st->bit_pll &= 0xffffu;
- st->descram = (st->descram << 1) | curbit;
- descx = st->descram ^ (st->descram >> 1);
- descx ^= ((descx >> DESCRAM_TAPSH1) ^
- (descx >> DESCRAM_TAPSH2));
- st->shreg >>= 1;
- st->shreg |= (!(descx & 1)) << 16;
- if (st->shreg & 1) {
- hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
- st->shreg = 0x10000;
- }
- diag_trigger(sm);
- }
- diag_add_one(sm, ((short)(*buf - 0x80)) << 8);
-#endif
-
- diag_trigger(sm);
- diag_add_constellation(sm, (vali*COS(st->phase)+ valq*SIN(st->phase)) >> 13,
- (valq*COS(st->phase) - vali*SIN(st->phase)) >> 13);
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_4800_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
-{
- struct demod_state_psk48 *st = (struct demod_state_psk48 *)(&sm->d);
- int i, si, sq;
- const short *coeff;
-
- for (; buflen > 0; buflen--, buf++) {
- memmove(st->infi+1, st->infi,
- sizeof(st->infi)-sizeof(st->infi[0]));
- memmove(st->infq+1, st->infq,
- sizeof(st->infq)-sizeof(st->infq[0]));
- si = *buf;
- si &= 0xff;
- si -= 128;
- diag_add_one(sm, si << 8);
- st->infi[0] = (si * COS(st->downmixer))>>7;
- st->infq[0] = (si * SIN(st->downmixer))>>7;
- st->downmixer = (st->downmixer-PSK48_PHASEINC)&0xffffu;
- for (i = si = sq = 0, coeff = psk48_rx_coeff; i < (PSK48_RXF_LEN/2);
- i++, coeff += 2) {
- si += st->infi[i] * (*coeff);
- sq += st->infq[i] * (*coeff);
- }
- demod_psk48_baseband(sm, st, si >> 15, sq >> 15);
- for (i = si = sq = 0, coeff = psk48_rx_coeff + 1; i < (PSK48_RXF_LEN/2);
- i++, coeff += 2) {
- si += st->infi[i] * (*coeff);
- sq += st->infq[i] * (*coeff);
- }
- demod_psk48_baseband(sm, st, si >> 15, sq >> 15);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demodulator_4800_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
-{
- struct demod_state_psk48 *st = (struct demod_state_psk48 *)(&sm->d);
- int i, si, sq;
- const short *coeff;
-
- for (; buflen > 0; buflen--, buf++) {
- memmove(st->infi+1, st->infi,
- sizeof(st->infi)-sizeof(st->infi[0]));
- memmove(st->infq+1, st->infq,
- sizeof(st->infq)-sizeof(st->infq[0]));
- si = *buf;
- diag_add_one(sm, si);
- st->infi[0] = (si * COS(st->downmixer))>>15;
- st->infq[0] = (si * SIN(st->downmixer))>>15;
- st->downmixer = (st->downmixer-PSK48_PHASEINC)&0xffffu;
- for (i = si = sq = 0, coeff = psk48_rx_coeff; i < (PSK48_RXF_LEN/2);
- i++, coeff += 2) {
- si += st->infi[i] * (*coeff);
- sq += st->infq[i] * (*coeff);
- }
- demod_psk48_baseband(sm, st, si >> 15, sq >> 15);
- for (i = si = sq = 0, coeff = psk48_rx_coeff + 1; i < (PSK48_RXF_LEN/2);
- i++, coeff += 2) {
- si += st->infi[i] * (*coeff);
- sq += st->infq[i] * (*coeff);
- }
- demod_psk48_baseband(sm, st, si >> 15, sq >> 15);
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void mod_init_4800(struct sm_state *sm)
-{
- struct mod_state_psk48 *st = (struct mod_state_psk48 *)(&sm->m);
-
- st->scram = 1;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void demod_init_4800(struct sm_state *sm)
-{
- struct demod_state_psk48 *st = (struct demod_state_psk48 *)(&sm->d);
-
- st->dcd_time = 120;
- st->dcd_sum0 = 2;
-}
-
-/* --------------------------------------------------------------------- */
-
-const struct modem_tx_info sm_psk4800_tx = {
- "psk4800", sizeof(struct mod_state_psk48),
- PSK48_SAMPLERATE, 4800,
- modulator_4800_u8, modulator_4800_s16, mod_init_4800
-};
-
-const struct modem_rx_info sm_psk4800_rx = {
- "psk4800", sizeof(struct demod_state_psk48),
- PSK48_SAMPLERATE, 4800, 1, PSK48_TXF_OVERSAMPLING,
- demodulator_4800_u8, demodulator_4800_s16, demod_init_4800
-};
-
-/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/soundmodem/sm_sbc.c b/drivers/net/hamradio/soundmodem/sm_sbc.c
deleted file mode 100644
index 18fa7e8e5a8d..000000000000
--- a/drivers/net/hamradio/soundmodem/sm_sbc.c
+++ /dev/null
@@ -1,942 +0,0 @@
-
-
-/*
- * sm_sbc.c -- soundcard radio modem driver soundblaster hardware driver
- *
- * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Please note that the GPL allows you to use the driver, NOT the radio.
- * In order to use the radio, you need a license from the communications
- * authority of your country.
- *
- */
-
-#include <linux/ptrace.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/soundmodem.h>
-#include <linux/delay.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include "sm.h"
-#include "smdma.h"
-
-/* --------------------------------------------------------------------- */
-
-/*
- * currently this module is supposed to support both module styles, i.e.
- * the old one present up to about 2.1.9, and the new one functioning
- * starting with 2.1.21. The reason is I have a kit allowing to compile
- * this module also under 2.0.x which was requested by several people.
- * This will go in 2.2
- */
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE >= 0x20100
-#include <asm/uaccess.h>
-#else
-#include <asm/segment.h>
-#include <linux/mm.h>
-
-#undef put_user
-#undef get_user
-
-#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
-#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
-
-static inline int copy_from_user(void *to, const void *from, unsigned long n)
-{
- int i = verify_area(VERIFY_READ, from, n);
- if (i)
- return i;
- memcpy_fromfs(to, from, n);
- return 0;
-}
-
-static inline int copy_to_user(void *to, const void *from, unsigned long n)
-{
- int i = verify_area(VERIFY_WRITE, to, n);
- if (i)
- return i;
- memcpy_tofs(to, from, n);
- return 0;
-}
-#endif
-
-/* --------------------------------------------------------------------- */
-
-struct sc_state_sbc {
- unsigned char revhi, revlo;
- unsigned char fmt[2];
- unsigned int sr[2];
-};
-
-#define SCSTATE ((struct sc_state_sbc *)(&sm->hw))
-
-/* --------------------------------------------------------------------- */
-/*
- * the sbc converter's registers
- */
-#define DSP_RESET(iobase) (iobase+0x6)
-#define DSP_READ_DATA(iobase) (iobase+0xa)
-#define DSP_WRITE_DATA(iobase) (iobase+0xc)
-#define DSP_WRITE_STATUS(iobase) (iobase+0xc)
-#define DSP_DATA_AVAIL(iobase) (iobase+0xe)
-#define DSP_MIXER_ADDR(iobase) (iobase+0x4)
-#define DSP_MIXER_DATA(iobase) (iobase+0x5)
-#define DSP_INTACK_16BIT(iobase) (iobase+0xf)
-#define SBC_EXTENT 16
-
-/* --------------------------------------------------------------------- */
-/*
- * SBC commands
- */
-#define SBC_OUTPUT 0x14
-#define SBC_INPUT 0x24
-#define SBC_BLOCKSIZE 0x48
-#define SBC_HI_OUTPUT 0x91
-#define SBC_HI_INPUT 0x99
-#define SBC_LO_OUTPUT_AUTOINIT 0x1c
-#define SBC_LO_INPUT_AUTOINIT 0x2c
-#define SBC_HI_OUTPUT_AUTOINIT 0x90
-#define SBC_HI_INPUT_AUTOINIT 0x98
-#define SBC_IMMED_INT 0xf2
-#define SBC_GET_REVISION 0xe1
-#define ESS_GET_REVISION 0xe7
-#define SBC_SPEAKER_ON 0xd1
-#define SBC_SPEAKER_OFF 0xd3
-#define SBC_DMA_ON 0xd0
-#define SBC_DMA_OFF 0xd4
-#define SBC_SAMPLE_RATE 0x40
-#define SBC_SAMPLE_RATE_OUT 0x41
-#define SBC_SAMPLE_RATE_IN 0x42
-#define SBC_MONO_8BIT 0xa0
-#define SBC_MONO_16BIT 0xa4
-#define SBC_STEREO_8BIT 0xa8
-#define SBC_STEREO_16BIT 0xac
-
-#define SBC4_OUT8_AI 0xc6
-#define SBC4_IN8_AI 0xce
-#define SBC4_MODE_UNS_MONO 0x00
-#define SBC4_MODE_SIGN_MONO 0x10
-
-#define SBC4_OUT16_AI 0xb6
-#define SBC4_IN16_AI 0xbe
-
-/* --------------------------------------------------------------------- */
-
-static int inline reset_dsp(struct net_device *dev)
-{
- int i;
-
- outb(1, DSP_RESET(dev->base_addr));
- udelay(300);
- outb(0, DSP_RESET(dev->base_addr));
- for (i = 0; i < 0xffff; i++)
- if (inb(DSP_DATA_AVAIL(dev->base_addr)) & 0x80)
- if (inb(DSP_READ_DATA(dev->base_addr)) == 0xaa)
- return 1;
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void inline write_dsp(struct net_device *dev, unsigned char data)
-{
- int i;
-
- for (i = 0; i < 0xffff; i++)
- if (!(inb(DSP_WRITE_STATUS(dev->base_addr)) & 0x80)) {
- outb(data, DSP_WRITE_DATA(dev->base_addr));
- return;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static int inline read_dsp(struct net_device *dev, unsigned char *data)
-{
- int i;
-
- if (!data)
- return 0;
- for (i = 0; i < 0xffff; i++)
- if (inb(DSP_DATA_AVAIL(dev->base_addr)) & 0x80) {
- *data = inb(DSP_READ_DATA(dev->base_addr));
- return 1;
- }
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int config_resources(struct net_device *dev, struct sm_state *sm, int fdx)
-{
- unsigned char irqreg = 0, dmareg = 0, realirq, realdma;
- unsigned long flags;
-
- switch (dev->irq) {
- case 2:
- case 9:
- irqreg |= 0x01;
- break;
-
- case 5:
- irqreg |= 0x02;
- break;
-
- case 7:
- irqreg |= 0x04;
- break;
-
- case 10:
- irqreg |= 0x08;
- break;
-
- default:
- return -ENODEV;
- }
-
- switch (dev->dma) {
- case 0:
- dmareg |= 0x01;
- break;
-
- case 1:
- dmareg |= 0x02;
- break;
-
- case 3:
- dmareg |= 0x08;
- break;
-
- default:
- return -ENODEV;
- }
-
- if (fdx) {
- switch (sm->hdrv.ptt_out.dma2) {
- case 5:
- dmareg |= 0x20;
- break;
-
- case 6:
- dmareg |= 0x40;
- break;
-
- case 7:
- dmareg |= 0x80;
- break;
-
- default:
- return -ENODEV;
- }
- }
- save_flags(flags);
- cli();
- outb(0x80, DSP_MIXER_ADDR(dev->base_addr));
- outb(irqreg, DSP_MIXER_DATA(dev->base_addr));
- realirq = inb(DSP_MIXER_DATA(dev->base_addr));
- outb(0x81, DSP_MIXER_ADDR(dev->base_addr));
- outb(dmareg, DSP_MIXER_DATA(dev->base_addr));
- realdma = inb(DSP_MIXER_DATA(dev->base_addr));
- restore_flags(flags);
- if ((~realirq) & irqreg || (~realdma) & dmareg) {
- printk(KERN_ERR "%s: sbc resource registers cannot be set; PnP device "
- "and IRQ/DMA specified wrongly?\n", sm_drvname);
- return -EINVAL;
- }
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void inline sbc_int_ack_8bit(struct net_device *dev)
-{
- inb(DSP_DATA_AVAIL(dev->base_addr));
-}
-
-/* --------------------------------------------------------------------- */
-
-static void inline sbc_int_ack_16bit(struct net_device *dev)
-{
- inb(DSP_INTACK_16BIT(dev->base_addr));
-}
-
-/* --------------------------------------------------------------------- */
-
-static void setup_dma_dsp(struct net_device *dev, struct sm_state *sm, int send)
-{
- unsigned long flags;
- static const unsigned char sbcmode[2][2] = {
- { SBC_LO_INPUT_AUTOINIT, SBC_LO_OUTPUT_AUTOINIT },
- { SBC_HI_INPUT_AUTOINIT, SBC_HI_OUTPUT_AUTOINIT }
- };
- static const unsigned char sbc4mode[2] = { SBC4_IN8_AI, SBC4_OUT8_AI };
- static const unsigned char sbcskr[2] = { SBC_SPEAKER_OFF, SBC_SPEAKER_ON };
- unsigned int nsamps;
-
- send = !!send;
- if (!reset_dsp(dev)) {
- printk(KERN_ERR "%s: sbc: cannot reset sb dsp\n", sm_drvname);
- return;
- }
- save_flags(flags);
- cli();
- sbc_int_ack_8bit(dev);
- write_dsp(dev, SBC_SAMPLE_RATE); /* set sampling rate */
- write_dsp(dev, SCSTATE->fmt[send]);
- write_dsp(dev, sbcskr[send]);
- nsamps = dma_setup(sm, send, dev->dma) - 1;
- sbc_int_ack_8bit(dev);
- if (SCSTATE->revhi >= 4) {
- write_dsp(dev, sbc4mode[send]);
- write_dsp(dev, SBC4_MODE_UNS_MONO);
- write_dsp(dev, nsamps & 0xff);
- write_dsp(dev, nsamps >> 8);
- } else {
- write_dsp(dev, SBC_BLOCKSIZE);
- write_dsp(dev, nsamps & 0xff);
- write_dsp(dev, nsamps >> 8);
- write_dsp(dev, sbcmode[SCSTATE->fmt[send] >= 180][send]);
- /* hispeed mode if sample rate > 13kHz */
- }
- restore_flags(flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-static void sbc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct net_device *dev = (struct net_device *)dev_id;
- struct sm_state *sm = (struct sm_state *)dev->priv;
- unsigned int curfrag;
-
- if (!dev || !sm || sm->hdrv.magic != HDLCDRV_MAGIC)
- return;
- cli();
- sbc_int_ack_8bit(dev);
- disable_dma(dev->dma);
- clear_dma_ff(dev->dma);
- dma_ptr(sm, sm->dma.ptt_cnt > 0, dev->dma, &curfrag);
- enable_dma(dev->dma);
- sm_int_freq(sm);
- sti();
- if (sm->dma.ptt_cnt <= 0) {
- dma_receive(sm, curfrag);
- hdlcdrv_arbitrate(dev, &sm->hdrv);
- if (hdlcdrv_ptt(&sm->hdrv)) {
- /* starting to transmit */
- disable_dma(dev->dma);
- hdlcdrv_transmitter(dev, &sm->hdrv); /* prefill HDLC buffer */
- dma_start_transmit(sm);
- setup_dma_dsp(dev, sm, 1);
- dma_transmit(sm);
- }
- } else if (dma_end_transmit(sm, curfrag)) {
- /* stopping transmission */
- disable_dma(dev->dma);
- sti();
- dma_init_receive(sm);
- setup_dma_dsp(dev, sm, 0);
- } else
- dma_transmit(sm);
- sm_output_status(sm);
- hdlcdrv_transmitter(dev, &sm->hdrv);
- hdlcdrv_receiver(dev, &sm->hdrv);
-
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sbc_open(struct net_device *dev, struct sm_state *sm)
-{
- int err;
- unsigned int dmasz, u;
-
- if (sizeof(sm->m) < sizeof(struct sc_state_sbc)) {
- printk(KERN_ERR "sm sbc: sbc state too big: %d > %d\n",
- sizeof(struct sc_state_sbc), sizeof(sm->m));
- return -ENODEV;
- }
- if (!dev || !sm)
- return -ENXIO;
- if (dev->base_addr <= 0 || dev->base_addr > 0x1000-SBC_EXTENT ||
- dev->irq < 2 || dev->irq > 15 || dev->dma > 3)
- return -ENXIO;
- if (check_region(dev->base_addr, SBC_EXTENT))
- return -EACCES;
- /*
- * check if a card is available
- */
- if (!reset_dsp(dev)) {
- printk(KERN_ERR "%s: sbc: no card at io address 0x%lx\n",
- sm_drvname, dev->base_addr);
- return -ENODEV;
- }
- write_dsp(dev, SBC_GET_REVISION);
- if (!read_dsp(dev, &SCSTATE->revhi) ||
- !read_dsp(dev, &SCSTATE->revlo))
- return -ENODEV;
- printk(KERN_INFO "%s: SoundBlaster DSP revision %d.%d\n", sm_drvname,
- SCSTATE->revhi, SCSTATE->revlo);
- if (SCSTATE->revhi < 2) {
- printk(KERN_ERR "%s: your card is an antiquity, at least DSP "
- "rev 2.00 required\n", sm_drvname);
- return -ENODEV;
- }
- if (SCSTATE->revhi < 3 &&
- (SCSTATE->fmt[0] >= 180 || SCSTATE->fmt[1] >= 180)) {
- printk(KERN_ERR "%s: sbc io 0x%lx: DSP rev %d.%02d too "
- "old, at least 3.00 required\n", sm_drvname,
- dev->base_addr, SCSTATE->revhi, SCSTATE->revlo);
- return -ENODEV;
- }
- if (SCSTATE->revhi >= 4 &&
- (err = config_resources(dev, sm, 0))) {
- printk(KERN_ERR "%s: invalid IRQ and/or DMA specified\n", sm_drvname);
- return err;
- }
- /*
- * initialize some variables
- */
- dma_init_receive(sm);
- dmasz = (NUM_FRAGMENTS + 1) * sm->dma.ifragsz;
- u = NUM_FRAGMENTS * sm->dma.ofragsz;
- if (u > dmasz)
- dmasz = u;
- if (!(sm->dma.ibuf = sm->dma.obuf = kmalloc(dmasz, GFP_KERNEL | GFP_DMA)))
- return -ENOMEM;
- dma_init_transmit(sm);
- dma_init_receive(sm);
-
- memset(&sm->m, 0, sizeof(sm->m));
- memset(&sm->d, 0, sizeof(sm->d));
- if (sm->mode_tx->init)
- sm->mode_tx->init(sm);
- if (sm->mode_rx->init)
- sm->mode_rx->init(sm);
-
- if (request_dma(dev->dma, sm->hwdrv->hw_name)) {
- kfree(sm->dma.obuf);
- return -EBUSY;
- }
- if (request_irq(dev->irq, sbc_interrupt, SA_INTERRUPT,
- sm->hwdrv->hw_name, dev)) {
- free_dma(dev->dma);
- kfree(sm->dma.obuf);
- return -EBUSY;
- }
- request_region(dev->base_addr, SBC_EXTENT, sm->hwdrv->hw_name);
- setup_dma_dsp(dev, sm, 0);
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sbc_close(struct net_device *dev, struct sm_state *sm)
-{
- if (!dev || !sm)
- return -EINVAL;
- /*
- * disable interrupts
- */
- disable_dma(dev->dma);
- reset_dsp(dev);
- free_irq(dev->irq, dev);
- free_dma(dev->dma);
- release_region(dev->base_addr, SBC_EXTENT);
- kfree(sm->dma.obuf);
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sbc_sethw(struct net_device *dev, struct sm_state *sm, char *mode)
-{
- char *cp = strchr(mode, '.');
- const struct modem_tx_info **mtp = sm_modem_tx_table;
- const struct modem_rx_info **mrp;
-
- if (!strcmp(mode, "off")) {
- sm->mode_tx = NULL;
- sm->mode_rx = NULL;
- return 0;
- }
- if (cp)
- *cp++ = '\0';
- else
- cp = mode;
- for (; *mtp; mtp++) {
- if ((*mtp)->loc_storage > sizeof(sm->m)) {
- printk(KERN_ERR "%s: insufficient storage for modulator %s (%d)\n",
- sm_drvname, (*mtp)->name, (*mtp)->loc_storage);
- continue;
- }
- if (!(*mtp)->name || strcmp((*mtp)->name, mode))
- continue;
- if ((*mtp)->srate < 5000 || (*mtp)->srate > 44100)
- continue;
- if (!(*mtp)->modulator_u8)
- continue;
- for (mrp = sm_modem_rx_table; *mrp; mrp++) {
- if ((*mrp)->loc_storage > sizeof(sm->d)) {
- printk(KERN_ERR "%s: insufficient storage for demodulator %s (%d)\n",
- sm_drvname, (*mrp)->name, (*mrp)->loc_storage);
- continue;
- }
- if (!(*mrp)->demodulator_u8)
- continue;
- if ((*mrp)->name && !strcmp((*mrp)->name, cp) &&
- (*mrp)->srate >= 5000 && (*mrp)->srate <= 44100) {
- sm->mode_tx = *mtp;
- sm->mode_rx = *mrp;
- SCSTATE->fmt[0] = 256-((1000000L+sm->mode_rx->srate/2)/
- sm->mode_rx->srate);
- SCSTATE->fmt[1] = 256-((1000000L+sm->mode_tx->srate/2)/
- sm->mode_tx->srate);
- sm->dma.ifragsz = (sm->mode_rx->srate + 50)/100;
- sm->dma.ofragsz = (sm->mode_tx->srate + 50)/100;
- if (sm->dma.ifragsz < sm->mode_rx->overlap)
- sm->dma.ifragsz = sm->mode_rx->overlap;
- sm->dma.i16bit = sm->dma.o16bit = 0;
- return 0;
- }
- }
- }
- return -EINVAL;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sbc_ioctl(struct net_device *dev, struct sm_state *sm, struct ifreq *ifr,
- struct hdlcdrv_ioctl *hi, int cmd)
-{
- struct sm_ioctl bi;
- unsigned long flags;
- int i;
-
- if (cmd != SIOCDEVPRIVATE)
- return -ENOIOCTLCMD;
-
- if (hi->cmd == HDLCDRVCTL_MODEMPARMASK)
- return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ |
- HDLCDRV_PARMASK_DMA | HDLCDRV_PARMASK_SERIOBASE |
- HDLCDRV_PARMASK_PARIOBASE | HDLCDRV_PARMASK_MIDIIOBASE;
-
- if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
- return -EFAULT;
-
- switch (bi.cmd) {
- default:
- return -ENOIOCTLCMD;
-
- case SMCTL_GETMIXER:
- i = 0;
- bi.data.mix.sample_rate = sm->mode_rx->srate;
- bi.data.mix.bit_rate = sm->hdrv.par.bitrate;
- bi.data.mix.mixer_type = SM_MIXER_INVALID;
- switch (SCSTATE->revhi) {
- case 2:
- bi.data.mix.mixer_type = SM_MIXER_CT1335;
- break;
- case 3:
- bi.data.mix.mixer_type = SM_MIXER_CT1345;
- break;
- case 4:
- bi.data.mix.mixer_type = SM_MIXER_CT1745;
- break;
- }
- if (bi.data.mix.mixer_type != SM_MIXER_INVALID &&
- bi.data.mix.reg < 0x80) {
- save_flags(flags);
- cli();
- outb(bi.data.mix.reg, DSP_MIXER_ADDR(dev->base_addr));
- bi.data.mix.data = inb(DSP_MIXER_DATA(dev->base_addr));
- restore_flags(flags);
- i = 1;
- }
- if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
- return -EFAULT;
- return i;
-
- case SMCTL_SETMIXER:
- if (!capable(CAP_SYS_RAWIO))
- return -EACCES;
- switch (SCSTATE->revhi) {
- case 2:
- if (bi.data.mix.mixer_type != SM_MIXER_CT1335)
- return -EINVAL;
- break;
- case 3:
- if (bi.data.mix.mixer_type != SM_MIXER_CT1345)
- return -EINVAL;
- break;
- case 4:
- if (bi.data.mix.mixer_type != SM_MIXER_CT1745)
- return -EINVAL;
- break;
- default:
- return -ENODEV;
- }
- if (bi.data.mix.reg >= 0x80)
- return -EACCES;
- save_flags(flags);
- cli();
- outb(bi.data.mix.reg, DSP_MIXER_ADDR(dev->base_addr));
- outb(bi.data.mix.data, DSP_MIXER_DATA(dev->base_addr));
- restore_flags(flags);
- return 0;
-
- }
- if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
- return -EFAULT;
- return 0;
-
-}
-
-/* --------------------------------------------------------------------- */
-
-const struct hardware_info sm_hw_sbc = {
- "sbc", sizeof(struct sc_state_sbc),
- sbc_open, sbc_close, sbc_ioctl, sbc_sethw
-};
-
-/* --------------------------------------------------------------------- */
-
-static void setup_dma_fdx_dsp(struct net_device *dev, struct sm_state *sm)
-{
- unsigned long flags;
- unsigned int isamps, osamps;
-
- if (!reset_dsp(dev)) {
- printk(KERN_ERR "%s: sbc: cannot reset sb dsp\n", sm_drvname);
- return;
- }
- save_flags(flags);
- cli();
- sbc_int_ack_8bit(dev);
- sbc_int_ack_16bit(dev);
- /* should eventually change to set rates individually by SBC_SAMPLE_RATE_{IN/OUT} */
- write_dsp(dev, SBC_SAMPLE_RATE_IN);
- write_dsp(dev, SCSTATE->sr[0] >> 8);
- write_dsp(dev, SCSTATE->sr[0] & 0xff);
- write_dsp(dev, SBC_SAMPLE_RATE_OUT);
- write_dsp(dev, SCSTATE->sr[1] >> 8);
- write_dsp(dev, SCSTATE->sr[1] & 0xff);
- write_dsp(dev, SBC_SPEAKER_ON);
- if (sm->dma.o16bit) {
- /*
- * DMA channel 1 (8bit) does input (capture),
- * DMA channel 2 (16bit) does output (playback)
- */
- isamps = dma_setup(sm, 0, dev->dma) - 1;
- osamps = dma_setup(sm, 1, sm->hdrv.ptt_out.dma2) - 1;
- sbc_int_ack_8bit(dev);
- sbc_int_ack_16bit(dev);
- write_dsp(dev, SBC4_IN8_AI);
- write_dsp(dev, SBC4_MODE_UNS_MONO);
- write_dsp(dev, isamps & 0xff);
- write_dsp(dev, isamps >> 8);
- write_dsp(dev, SBC4_OUT16_AI);
- write_dsp(dev, SBC4_MODE_SIGN_MONO);
- write_dsp(dev, osamps & 0xff);
- write_dsp(dev, osamps >> 8);
- } else {
- /*
- * DMA channel 1 (8bit) does output (playback),
- * DMA channel 2 (16bit) does input (capture)
- */
- isamps = dma_setup(sm, 0, sm->hdrv.ptt_out.dma2) - 1;
- osamps = dma_setup(sm, 1, dev->dma) - 1;
- sbc_int_ack_8bit(dev);
- sbc_int_ack_16bit(dev);
- write_dsp(dev, SBC4_OUT8_AI);
- write_dsp(dev, SBC4_MODE_UNS_MONO);
- write_dsp(dev, osamps & 0xff);
- write_dsp(dev, osamps >> 8);
- write_dsp(dev, SBC4_IN16_AI);
- write_dsp(dev, SBC4_MODE_SIGN_MONO);
- write_dsp(dev, isamps & 0xff);
- write_dsp(dev, isamps >> 8);
- }
- dma_init_receive(sm);
- dma_init_transmit(sm);
- restore_flags(flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-static void sbcfdx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct net_device *dev = (struct net_device *)dev_id;
- struct sm_state *sm = (struct sm_state *)dev->priv;
- unsigned char intsrc, pbint = 0, captint = 0;
- unsigned int ocfrag, icfrag;
- unsigned long flags;
-
- if (!dev || !sm || sm->hdrv.magic != HDLCDRV_MAGIC)
- return;
- save_flags(flags);
- cli();
- outb(0x82, DSP_MIXER_ADDR(dev->base_addr));
- intsrc = inb(DSP_MIXER_DATA(dev->base_addr));
- if (intsrc & 0x01) {
- sbc_int_ack_8bit(dev);
- if (sm->dma.o16bit) {
- captint = 1;
- disable_dma(dev->dma);
- clear_dma_ff(dev->dma);
- dma_ptr(sm, 0, dev->dma, &icfrag);
- enable_dma(dev->dma);
- } else {
- pbint = 1;
- disable_dma(dev->dma);
- clear_dma_ff(dev->dma);
- dma_ptr(sm, 1, dev->dma, &ocfrag);
- enable_dma(dev->dma);
- }
- }
- if (intsrc & 0x02) {
- sbc_int_ack_16bit(dev);
- if (sm->dma.o16bit) {
- pbint = 1;
- disable_dma(sm->hdrv.ptt_out.dma2);
- clear_dma_ff(sm->hdrv.ptt_out.dma2);
- dma_ptr(sm, 1, sm->hdrv.ptt_out.dma2, &ocfrag);
- enable_dma(sm->hdrv.ptt_out.dma2);
- } else {
- captint = 1;
- disable_dma(sm->hdrv.ptt_out.dma2);
- clear_dma_ff(sm->hdrv.ptt_out.dma2);
- dma_ptr(sm, 0, sm->hdrv.ptt_out.dma2, &icfrag);
- enable_dma(sm->hdrv.ptt_out.dma2);
- }
- }
- restore_flags(flags);
- sm_int_freq(sm);
- sti();
- if (pbint) {
- if (dma_end_transmit(sm, ocfrag))
- dma_clear_transmit(sm);
- dma_transmit(sm);
- }
- if (captint) {
- dma_receive(sm, icfrag);
- hdlcdrv_arbitrate(dev, &sm->hdrv);
- }
- sm_output_status(sm);
- hdlcdrv_transmitter(dev, &sm->hdrv);
- hdlcdrv_receiver(dev, &sm->hdrv);
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sbcfdx_open(struct net_device *dev, struct sm_state *sm)
-{
- int err;
-
- if (sizeof(sm->m) < sizeof(struct sc_state_sbc)) {
- printk(KERN_ERR "sm sbc: sbc state too big: %d > %d\n",
- sizeof(struct sc_state_sbc), sizeof(sm->m));
- return -ENODEV;
- }
- if (!dev || !sm)
- return -ENXIO;
- if (dev->base_addr <= 0 || dev->base_addr > 0x1000-SBC_EXTENT ||
- dev->irq < 2 || dev->irq > 15 || dev->dma > 3)
- return -ENXIO;
- if (check_region(dev->base_addr, SBC_EXTENT))
- return -EACCES;
- /*
- * check if a card is available
- */
- if (!reset_dsp(dev)) {
- printk(KERN_ERR "%s: sbc: no card at io address 0x%lx\n",
- sm_drvname, dev->base_addr);
- return -ENODEV;
- }
- write_dsp(dev, SBC_GET_REVISION);
- if (!read_dsp(dev, &SCSTATE->revhi) ||
- !read_dsp(dev, &SCSTATE->revlo))
- return -ENODEV;
- printk(KERN_INFO "%s: SoundBlaster DSP revision %d.%d\n", sm_drvname,
- SCSTATE->revhi, SCSTATE->revlo);
- if (SCSTATE->revhi < 4) {
- printk(KERN_ERR "%s: at least DSP rev 4.00 required\n", sm_drvname);
- return -ENODEV;
- }
- if ((err = config_resources(dev, sm, 1))) {
- printk(KERN_ERR "%s: invalid IRQ and/or DMA specified\n", sm_drvname);
- return err;
- }
- /*
- * initialize some variables
- */
- if (!(sm->dma.ibuf = kmalloc(sm->dma.ifragsz * (NUM_FRAGMENTS+1), GFP_KERNEL | GFP_DMA)))
- return -ENOMEM;
- if (!(sm->dma.obuf = kmalloc(sm->dma.ofragsz * NUM_FRAGMENTS, GFP_KERNEL | GFP_DMA))) {
- kfree(sm->dma.ibuf);
- return -ENOMEM;
- }
- dma_init_transmit(sm);
- dma_init_receive(sm);
-
- memset(&sm->m, 0, sizeof(sm->m));
- memset(&sm->d, 0, sizeof(sm->d));
- if (sm->mode_tx->init)
- sm->mode_tx->init(sm);
- if (sm->mode_rx->init)
- sm->mode_rx->init(sm);
-
- if (request_dma(dev->dma, sm->hwdrv->hw_name)) {
- kfree(sm->dma.ibuf);
- kfree(sm->dma.obuf);
- return -EBUSY;
- }
- if (request_dma(sm->hdrv.ptt_out.dma2, sm->hwdrv->hw_name)) {
- kfree(sm->dma.ibuf);
- kfree(sm->dma.obuf);
- free_dma(dev->dma);
- return -EBUSY;
- }
- if (request_irq(dev->irq, sbcfdx_interrupt, SA_INTERRUPT,
- sm->hwdrv->hw_name, dev)) {
- kfree(sm->dma.ibuf);
- kfree(sm->dma.obuf);
- free_dma(dev->dma);
- free_dma(sm->hdrv.ptt_out.dma2);
- return -EBUSY;
- }
- request_region(dev->base_addr, SBC_EXTENT, sm->hwdrv->hw_name);
- setup_dma_fdx_dsp(dev, sm);
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sbcfdx_close(struct net_device *dev, struct sm_state *sm)
-{
- if (!dev || !sm)
- return -EINVAL;
- /*
- * disable interrupts
- */
- disable_dma(dev->dma);
- disable_dma(sm->hdrv.ptt_out.dma2);
- reset_dsp(dev);
- free_irq(dev->irq, dev);
- free_dma(dev->dma);
- free_dma(sm->hdrv.ptt_out.dma2);
- release_region(dev->base_addr, SBC_EXTENT);
- kfree(sm->dma.ibuf);
- kfree(sm->dma.obuf);
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sbcfdx_sethw(struct net_device *dev, struct sm_state *sm, char *mode)
-{
- char *cp = strchr(mode, '.');
- const struct modem_tx_info **mtp = sm_modem_tx_table;
- const struct modem_rx_info **mrp;
-
- if (!strcmp(mode, "off")) {
- sm->mode_tx = NULL;
- sm->mode_rx = NULL;
- return 0;
- }
- if (cp)
- *cp++ = '\0';
- else
- cp = mode;
- for (; *mtp; mtp++) {
- if ((*mtp)->loc_storage > sizeof(sm->m)) {
- printk(KERN_ERR "%s: insufficient storage for modulator %s (%d)\n",
- sm_drvname, (*mtp)->name, (*mtp)->loc_storage);
- continue;
- }
- if (!(*mtp)->name || strcmp((*mtp)->name, mode))
- continue;
- if ((*mtp)->srate < 5000 || (*mtp)->srate > 44100)
- continue;
- for (mrp = sm_modem_rx_table; *mrp; mrp++) {
- if ((*mrp)->loc_storage > sizeof(sm->d)) {
- printk(KERN_ERR "%s: insufficient storage for demodulator %s (%d)\n",
- sm_drvname, (*mrp)->name, (*mrp)->loc_storage);
- continue;
- }
- if ((*mrp)->name && !strcmp((*mrp)->name, cp) &&
- (*mtp)->srate >= 5000 && (*mtp)->srate <= 44100 &&
- (*mrp)->srate == (*mtp)->srate) {
- sm->mode_tx = *mtp;
- sm->mode_rx = *mrp;
- SCSTATE->sr[0] = sm->mode_rx->srate;
- SCSTATE->sr[1] = sm->mode_tx->srate;
- sm->dma.ifragsz = (sm->mode_rx->srate + 50)/100;
- sm->dma.ofragsz = (sm->mode_tx->srate + 50)/100;
- if (sm->dma.ifragsz < sm->mode_rx->overlap)
- sm->dma.ifragsz = sm->mode_rx->overlap;
- if (sm->mode_rx->demodulator_s16 && sm->mode_tx->modulator_u8) {
- sm->dma.i16bit = 1;
- sm->dma.o16bit = 0;
- sm->dma.ifragsz <<= 1;
- } else if (sm->mode_rx->demodulator_u8 && sm->mode_tx->modulator_s16) {
- sm->dma.i16bit = 0;
- sm->dma.o16bit = 1;
- sm->dma.ofragsz <<= 1;
- } else {
- printk(KERN_INFO "%s: mode %s or %s unusable\n", sm_drvname,
- sm->mode_rx->name, sm->mode_tx->name);
- sm->mode_tx = NULL;
- sm->mode_rx = NULL;
- return -EINVAL;
- }
- return 0;
- }
- }
- }
- return -EINVAL;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sbcfdx_ioctl(struct net_device *dev, struct sm_state *sm, struct ifreq *ifr,
- struct hdlcdrv_ioctl *hi, int cmd)
-{
- if (cmd != SIOCDEVPRIVATE)
- return -ENOIOCTLCMD;
-
- if (hi->cmd == HDLCDRVCTL_MODEMPARMASK)
- return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ |
- HDLCDRV_PARMASK_DMA | HDLCDRV_PARMASK_DMA2 | HDLCDRV_PARMASK_SERIOBASE |
- HDLCDRV_PARMASK_PARIOBASE | HDLCDRV_PARMASK_MIDIIOBASE;
-
- return sbc_ioctl(dev, sm, ifr, hi, cmd);
-}
-
-/* --------------------------------------------------------------------- */
-
-const struct hardware_info sm_hw_sbcfdx = {
- "sbcfdx", sizeof(struct sc_state_sbc),
- sbcfdx_open, sbcfdx_close, sbcfdx_ioctl, sbcfdx_sethw
-};
-
-/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/soundmodem/sm_wss.c b/drivers/net/hamradio/soundmodem/sm_wss.c
deleted file mode 100644
index b255df1d2cc1..000000000000
--- a/drivers/net/hamradio/soundmodem/sm_wss.c
+++ /dev/null
@@ -1,968 +0,0 @@
-/*****************************************************************************/
-
-/*
- * sm_wss.c -- soundcard radio modem driver, WSS (half duplex) driver
- *
- * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Please note that the GPL allows you to use the driver, NOT the radio.
- * In order to use the radio, you need a license from the communications
- * authority of your country.
- *
- */
-
-#include <linux/ptrace.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/soundmodem.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include "sm.h"
-#include "smdma.h"
-
-/* --------------------------------------------------------------------- */
-
-/*
- * currently this module is supposed to support both module styles, i.e.
- * the old one present up to about 2.1.9, and the new one functioning
- * starting with 2.1.21. The reason is I have a kit allowing to compile
- * this module also under 2.0.x which was requested by several people.
- * This will go in 2.2
- */
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE >= 0x20100
-#include <asm/uaccess.h>
-#else
-#include <asm/segment.h>
-#include <linux/mm.h>
-
-#undef put_user
-#undef get_user
-
-#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
-#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
-
-static inline int copy_from_user(void *to, const void *from, unsigned long n)
-{
- int i = verify_area(VERIFY_READ, from, n);
- if (i)
- return i;
- memcpy_fromfs(to, from, n);
- return 0;
-}
-
-static inline int copy_to_user(void *to, const void *from, unsigned long n)
-{
- int i = verify_area(VERIFY_WRITE, to, n);
- if (i)
- return i;
- memcpy_tofs(to, from, n);
- return 0;
-}
-#endif
-
-/* --------------------------------------------------------------------- */
-
-struct sc_state_wss {
- unsigned char revwss, revid, revv, revcid;
- unsigned char fmt[2];
- unsigned char crystal;
-};
-
-#define SCSTATE ((struct sc_state_wss *)(&sm->hw))
-
-/* --------------------------------------------------------------------- */
-
-#define WSS_CONFIG(iobase) (iobase+0)
-#define WSS_STATUS(iobase) (iobase+3)
-#define WSS_CODEC_IA(iobase) (iobase+4)
-#define WSS_CODEC_ID(iobase) (iobase+5)
-#define WSS_CODEC_STATUS(iobase) (iobase+6)
-#define WSS_CODEC_DATA(iobase) (iobase+7)
-
-#define WSS_EXTENT 8
-
-#define CS423X_HOTFIX
-
-/* --------------------------------------------------------------------- */
-
-static void write_codec(struct net_device *dev, unsigned char idx,
- unsigned char data)
-{
- int timeout = 900000;
-
- /* wait until codec ready */
- while (timeout > 0 && inb(WSS_CODEC_IA(dev->base_addr)) & 0x80)
- timeout--;
- outb(idx, WSS_CODEC_IA(dev->base_addr));
- outb(data, WSS_CODEC_ID(dev->base_addr));
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static unsigned char read_codec(struct net_device *dev, unsigned char idx)
-{
- int timeout = 900000;
-
- /* wait until codec ready */
- while (timeout > 0 && inb(WSS_CODEC_IA(dev->base_addr)) & 0x80)
- timeout--;
- outb(idx & 0x1f, WSS_CODEC_IA(dev->base_addr));
- return inb(WSS_CODEC_ID(dev->base_addr));
-}
-
-/* --------------------------------------------------------------------- */
-
-extern void inline wss_ack_int(struct net_device *dev)
-{
- outb(0, WSS_CODEC_STATUS(dev->base_addr));
-}
-
-/* --------------------------------------------------------------------- */
-
-static int wss_srate_tab[16] = {
- 8000, 5510, 16000, 11025, 27420, 18900, 32000, 22050,
- -1, 37800, -1, 44100, 48000, 33075, 9600, 6620
-};
-
-static int wss_srate_index(int srate)
-{
- int i;
-
- for (i = 0; i < (sizeof(wss_srate_tab)/sizeof(wss_srate_tab[0])); i++)
- if (srate == wss_srate_tab[i] && wss_srate_tab[i] > 0)
- return i;
- return -1;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int wss_set_codec_fmt(struct net_device *dev, struct sm_state *sm, unsigned char fmt,
- unsigned char fmt2, char fdx, char fullcalib)
-{
- unsigned long time;
- unsigned long flags;
-
- save_flags(flags);
- cli();
- /* Clock and data format register */
- write_codec(dev, 0x48, fmt);
- if (SCSTATE->crystal) {
- write_codec(dev, 0x5c, fmt2 & 0xf0);
- /* MCE and interface config reg */
- write_codec(dev, 0x49, (fdx ? 0 : 0x4) | (fullcalib ? 0x18 : 0));
- } else
- /* MCE and interface config reg */
- write_codec(dev, 0x49, fdx ? 0x8 : 0xc);
- outb(0xb, WSS_CODEC_IA(dev->base_addr)); /* leave MCE */
- if (SCSTATE->crystal && !fullcalib) {
- restore_flags(flags);
- return 0;
- }
- /*
- * wait for ACI start
- */
- time = 1000;
- while (!(read_codec(dev, 0x0b) & 0x20))
- if (!(--time)) {
- printk(KERN_WARNING "%s: ad1848 auto calibration timed out (1)\n",
- sm_drvname);
- restore_flags(flags);
- return -1;
- }
- /*
- * wait for ACI end
- */
- sti();
- time = jiffies + HZ/4;
- while ((read_codec(dev, 0x0b) & 0x20) && ((signed)(jiffies - time) < 0));
- restore_flags(flags);
- if ((signed)(jiffies - time) >= 0) {
- printk(KERN_WARNING "%s: ad1848 auto calibration timed out (2)\n",
- sm_drvname);
- return -1;
- }
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int wss_init_codec(struct net_device *dev, struct sm_state *sm, char fdx,
- unsigned char src_l, unsigned char src_r,
- int igain_l, int igain_r,
- int ogain_l, int ogain_r)
-{
- unsigned char tmp, reg0, reg1, reg6, reg7;
- static const signed char irqtab[16] =
- { -1, -1, 0x10, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20, -1, -1,
- -1, -1 };
- static const signed char dmatab[4] = { 1, 2, -1, 3 };
-
- tmp = inb(WSS_STATUS(dev->base_addr));
- if ((tmp & 0x3f) != 0x04 && (tmp & 0x3f) != 0x00 &&
- (tmp & 0x3f) != 0x0f) {
- printk(KERN_WARNING "sm: WSS card id register not found, "
- "address 0x%lx, ID register 0x%02x\n",
- dev->base_addr, (int)tmp);
- /* return -1; */
- SCSTATE->revwss = 0;
- } else {
- if ((tmp & 0x80) && ((dev->dma == 0) ||
- ((dev->irq >= 8) && (dev->irq != 9)))) {
- printk(KERN_ERR "%s: WSS: DMA0 and/or IRQ8..IRQ15 "
- "(except IRQ9) cannot be used on an 8bit "
- "card\n", sm_drvname);
- return -1;
- }
- if (dev->irq > 15 || irqtab[dev->irq] == -1) {
- printk(KERN_ERR "%s: WSS: invalid interrupt %d\n",
- sm_drvname, (int)dev->irq);
- return -1;
- }
- if (dev->dma > 3 || dmatab[dev->dma] == -1) {
- printk(KERN_ERR "%s: WSS: invalid dma channel %d\n",
- sm_drvname, (int)dev->dma);
- return -1;
- }
- tmp = irqtab[dev->irq] | dmatab[dev->dma];
- /* irq probe */
- outb((tmp & 0x38) | 0x40, WSS_CONFIG(dev->base_addr));
- if (!(inb(WSS_STATUS(dev->base_addr)) & 0x40)) {
- outb(0, WSS_CONFIG(dev->base_addr));
- printk(KERN_ERR "%s: WSS: IRQ%d is not free!\n",
- sm_drvname, dev->irq);
- }
- outb(tmp, WSS_CONFIG(dev->base_addr));
- SCSTATE->revwss = inb(WSS_STATUS(dev->base_addr)) & 0x3f;
- }
- /*
- * initialize the codec
- */
- if (igain_l < 0)
- igain_l = 0;
- if (igain_r < 0)
- igain_r = 0;
- if (ogain_l > 0)
- ogain_l = 0;
- if (ogain_r > 0)
- ogain_r = 0;
- reg0 = (src_l << 6) & 0xc0;
- reg1 = (src_r << 6) & 0xc0;
- if (reg0 == 0x80 && igain_l >= 20) {
- reg0 |= 0x20;
- igain_l -= 20;
- }
- if (reg1 == 0x80 && igain_r >= 20) {
- reg1 |= 0x20;
- igain_r -= 20;
- }
- if (igain_l > 23)
- igain_l = 23;
- if (igain_r > 23)
- igain_r = 23;
- reg0 |= igain_l * 2 / 3;
- reg1 |= igain_r * 2 / 3;
- reg6 = (ogain_l < -95) ? 0x80 : (ogain_l * (-2) / 3);
- reg7 = (ogain_r < -95) ? 0x80 : (ogain_r * (-2) / 3);
- write_codec(dev, 9, 0);
- write_codec(dev, 0, 0x45);
- if (read_codec(dev, 0) != 0x45)
- goto codec_err;
- write_codec(dev, 0, 0xaa);
- if (read_codec(dev, 0) != 0xaa)
- goto codec_err;
- write_codec(dev, 12, 0x40); /* enable MODE2 */
- write_codec(dev, 16, 0);
- write_codec(dev, 0, 0x45);
- SCSTATE->crystal = (read_codec(dev, 16) != 0x45);
- write_codec(dev, 0, 0xaa);
- SCSTATE->crystal &= (read_codec(dev, 16) != 0xaa);
- if (SCSTATE->crystal) {
- SCSTATE->revcid = read_codec(dev, 0x19);
- SCSTATE->revv = (SCSTATE->revcid >> 5) & 7;
- SCSTATE->revcid &= 7;
- write_codec(dev, 0x10, 0x80); /* maximum output level */
- write_codec(dev, 0x11, 0x02); /* xtal enable and no HPF */
- write_codec(dev, 0x12, 0x80); /* left line input control */
- write_codec(dev, 0x13, 0x80); /* right line input control */
- write_codec(dev, 0x16, 0); /* disable alternative freq sel */
- write_codec(dev, 0x1a, 0xe0); /* mono IO disable */
- write_codec(dev, 0x1b, 0x00); /* left out no att */
- write_codec(dev, 0x1d, 0x00); /* right out no att */
- }
-
- if (wss_set_codec_fmt(dev, sm, SCSTATE->fmt[0], SCSTATE->fmt[0], fdx, 1))
- goto codec_err;
-
- write_codec(dev, 0, reg0); /* left input control */
- write_codec(dev, 1, reg1); /* right input control */
- write_codec(dev, 2, 0x80); /* left aux#1 input control */
- write_codec(dev, 3, 0x80); /* right aux#1 input control */
- write_codec(dev, 4, 0x80); /* left aux#2 input control */
- write_codec(dev, 5, 0x80); /* right aux#2 input control */
- write_codec(dev, 6, reg6); /* left dac control */
- write_codec(dev, 7, reg7); /* right dac control */
- write_codec(dev, 0xa, 0x2); /* pin control register */
- write_codec(dev, 0xd, 0x0); /* digital mix control */
- SCSTATE->revid = read_codec(dev, 0xc) & 0xf;
- /*
- * print revisions
- */
- if (SCSTATE->crystal)
- printk(KERN_INFO "%s: Crystal CODEC ID %d, Chip revision %d, "
- " Chip ID %d\n", sm_drvname, (int)SCSTATE->revid,
- (int)SCSTATE->revv, (int)SCSTATE->revcid);
- else
- printk(KERN_INFO "%s: WSS revision %d, CODEC revision %d\n",
- sm_drvname, (int)SCSTATE->revwss,
- (int)SCSTATE->revid);
- return 0;
- codec_err:
- outb(0, WSS_CONFIG(dev->base_addr));
- printk(KERN_ERR "%s: no WSS soundcard found at address 0x%lx\n",
- sm_drvname, dev->base_addr);
- return -1;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void setup_dma_wss(struct net_device *dev, struct sm_state *sm, int send)
-{
- unsigned long flags;
- static const unsigned char codecmode[2] = { 0x0e, 0x0d };
- unsigned char oldcodecmode;
- long abrt;
- unsigned char fmt;
- unsigned int numsamps;
-
- send = !!send;
- fmt = SCSTATE->fmt[send];
- save_flags(flags);
- cli();
- /*
- * perform the final DMA sequence to disable the codec request
- */
- oldcodecmode = read_codec(dev, 9);
- write_codec(dev, 9, 0xc); /* disable codec */
- wss_ack_int(dev);
- if (read_codec(dev, 11) & 0x10) {
- dma_setup(sm, oldcodecmode & 1, dev->dma);
- abrt = 0;
- while ((read_codec(dev, 11) & 0x10) || ((++abrt) >= 0x10000));
- }
-#ifdef CS423X_HOTFIX
- if (read_codec(dev, 0x8) != fmt || SCSTATE->crystal)
- wss_set_codec_fmt(dev, sm, fmt, fmt, 0, 0);
-#else /* CS423X_HOTFIX */
- if (read_codec(dev, 0x8) != fmt)
- wss_set_codec_fmt(dev, sm, fmt, fmt, 0, 0);
-#endif /* CS423X_HOTFIX */
- numsamps = dma_setup(sm, send, dev->dma) - 1;
- write_codec(dev, 15, numsamps & 0xff);
- write_codec(dev, 14, numsamps >> 8);
- write_codec(dev, 9, codecmode[send]);
- restore_flags(flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-static void wss_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct net_device *dev = (struct net_device *)dev_id;
- struct sm_state *sm = (struct sm_state *)dev->priv;
- unsigned int curfrag;
- unsigned int nums;
-
- if (!dev || !sm || !sm->mode_rx || !sm->mode_tx ||
- sm->hdrv.magic != HDLCDRV_MAGIC)
- return;
- cli();
- wss_ack_int(dev);
- disable_dma(dev->dma);
- clear_dma_ff(dev->dma);
- nums = dma_ptr(sm, sm->dma.ptt_cnt > 0, dev->dma, &curfrag) - 1;
- write_codec(dev, 15, nums & 0xff);
- write_codec(dev, 14, nums >> 8);
- enable_dma(dev->dma);
- sm_int_freq(sm);
- sti();
- if (sm->dma.ptt_cnt <= 0) {
- dma_receive(sm, curfrag);
- hdlcdrv_arbitrate(dev, &sm->hdrv);
- if (hdlcdrv_ptt(&sm->hdrv)) {
- /* starting to transmit */
- disable_dma(dev->dma);
- hdlcdrv_transmitter(dev, &sm->hdrv); /* prefill HDLC buffer */
- dma_start_transmit(sm);
- setup_dma_wss(dev, sm, 1);
- dma_transmit(sm);
- }
- } else if (dma_end_transmit(sm, curfrag)) {
- /* stopping transmission */
- disable_dma(dev->dma);
- dma_init_receive(sm);
- setup_dma_wss(dev, sm, 0);
- } else
- dma_transmit(sm);
- sm_output_status(sm);
- hdlcdrv_transmitter(dev, &sm->hdrv);
- hdlcdrv_receiver(dev, &sm->hdrv);
-}
-
-/* --------------------------------------------------------------------- */
-
-static int wss_open(struct net_device *dev, struct sm_state *sm)
-{
- unsigned int dmasz, u;
-
- if (sizeof(sm->m) < sizeof(struct sc_state_wss)) {
- printk(KERN_ERR "sm wss: wss state too big: %d > %d\n",
- sizeof(struct sc_state_wss), sizeof(sm->m));
- return -ENODEV;
- }
- if (!dev || !sm || !sm->mode_rx || !sm->mode_tx)
- return -ENXIO;
- if (dev->base_addr <= 0 || dev->base_addr > 0x1000-WSS_EXTENT ||
- dev->irq < 2 || dev->irq > 15 || dev->dma > 3)
- return -ENXIO;
- if (check_region(dev->base_addr, WSS_EXTENT))
- return -EACCES;
- /*
- * check if a card is available
- */
- if (wss_init_codec(dev, sm, 0, 1, 1, 0, 0, -45, -45))
- return -ENODEV;
- /*
- * initialize some variables
- */
- dma_init_receive(sm);
- dmasz = (NUM_FRAGMENTS + 1) * sm->dma.ifragsz;
- u = NUM_FRAGMENTS * sm->dma.ofragsz;
- if (u > dmasz)
- dmasz = u;
- if (!(sm->dma.ibuf = sm->dma.obuf = kmalloc(dmasz, GFP_KERNEL | GFP_DMA)))
- return -ENOMEM;
- dma_init_transmit(sm);
- dma_init_receive(sm);
-
- memset(&sm->m, 0, sizeof(sm->m));
- memset(&sm->d, 0, sizeof(sm->d));
- if (sm->mode_tx->init)
- sm->mode_tx->init(sm);
- if (sm->mode_rx->init)
- sm->mode_rx->init(sm);
-
- if (request_dma(dev->dma, sm->hwdrv->hw_name)) {
- kfree(sm->dma.obuf);
- return -EBUSY;
- }
- if (request_irq(dev->irq, wss_interrupt, SA_INTERRUPT,
- sm->hwdrv->hw_name, dev)) {
- free_dma(dev->dma);
- kfree(sm->dma.obuf);
- return -EBUSY;
- }
- request_region(dev->base_addr, WSS_EXTENT, sm->hwdrv->hw_name);
- setup_dma_wss(dev, sm, 0);
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int wss_close(struct net_device *dev, struct sm_state *sm)
-{
- if (!dev || !sm)
- return -EINVAL;
- /*
- * disable interrupts
- */
- disable_dma(dev->dma);
- write_codec(dev, 9, 0xc); /* disable codec */
- free_irq(dev->irq, dev);
- free_dma(dev->dma);
- release_region(dev->base_addr, WSS_EXTENT);
- kfree(sm->dma.obuf);
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int wss_sethw(struct net_device *dev, struct sm_state *sm, char *mode)
-{
- char *cp = strchr(mode, '.');
- const struct modem_tx_info **mtp = sm_modem_tx_table;
- const struct modem_rx_info **mrp;
- int i, j;
-
- if (!strcmp(mode, "off")) {
- sm->mode_tx = NULL;
- sm->mode_rx = NULL;
- return 0;
- }
- if (cp)
- *cp++ = '\0';
- else
- cp = mode;
- for (; *mtp; mtp++) {
- if ((*mtp)->loc_storage > sizeof(sm->m)) {
- printk(KERN_ERR "%s: insufficient storage for modulator %s (%d)\n",
- sm_drvname, (*mtp)->name, (*mtp)->loc_storage);
- continue;
- }
- if (!(*mtp)->name || strcmp((*mtp)->name, mode))
- continue;
- if ((i = wss_srate_index((*mtp)->srate)) < 0)
- continue;
- for (mrp = sm_modem_rx_table; *mrp; mrp++) {
- if ((*mrp)->loc_storage > sizeof(sm->d)) {
- printk(KERN_ERR "%s: insufficient storage for demodulator %s (%d)\n",
- sm_drvname, (*mrp)->name, (*mrp)->loc_storage);
- continue;
- }
- if ((*mrp)->name && !strcmp((*mrp)->name, cp) &&
- ((j = wss_srate_index((*mrp)->srate)) >= 0)) {
- sm->mode_tx = *mtp;
- sm->mode_rx = *mrp;
- SCSTATE->fmt[0] = j;
- SCSTATE->fmt[1] = i;
- sm->dma.ifragsz = (sm->mode_rx->srate + 50)/100;
- sm->dma.ofragsz = (sm->mode_tx->srate + 50)/100;
- if (sm->dma.ifragsz < sm->mode_rx->overlap)
- sm->dma.ifragsz = sm->mode_rx->overlap;
- /* prefer same data format if possible to minimize switching times */
- sm->dma.i16bit = sm->dma.o16bit = 2;
- if (sm->mode_rx->srate == sm->mode_tx->srate) {
- if (sm->mode_rx->demodulator_s16 && sm->mode_tx->modulator_s16)
- sm->dma.i16bit = sm->dma.o16bit = 1;
- else if (sm->mode_rx->demodulator_u8 && sm->mode_tx->modulator_u8)
- sm->dma.i16bit = sm->dma.o16bit = 0;
- }
- if (sm->dma.i16bit == 2) {
- if (sm->mode_rx->demodulator_s16)
- sm->dma.i16bit = 1;
- else if (sm->mode_rx->demodulator_u8)
- sm->dma.i16bit = 0;
- }
- if (sm->dma.o16bit == 2) {
- if (sm->mode_tx->modulator_s16)
- sm->dma.o16bit = 1;
- else if (sm->mode_tx->modulator_u8)
- sm->dma.o16bit = 0;
- }
- if (sm->dma.i16bit == 2 || sm->dma.o16bit == 2) {
- printk(KERN_INFO "%s: mode %s or %s unusable\n", sm_drvname,
- sm->mode_rx->name, sm->mode_tx->name);
- sm->mode_tx = NULL;
- sm->mode_rx = NULL;
- return -EINVAL;
- }
-#ifdef __BIG_ENDIAN
- /* big endian 16bit only works on crystal cards... */
- if (sm->dma.i16bit) {
- SCSTATE->fmt[0] |= 0xc0;
- sm->dma.ifragsz <<= 1;
- }
- if (sm->dma.o16bit) {
- SCSTATE->fmt[1] |= 0xc0;
- sm->dma.ofragsz <<= 1;
- }
-#else /* __BIG_ENDIAN */
- if (sm->dma.i16bit) {
- SCSTATE->fmt[0] |= 0x40;
- sm->dma.ifragsz <<= 1;
- }
- if (sm->dma.o16bit) {
- SCSTATE->fmt[1] |= 0x40;
- sm->dma.ofragsz <<= 1;
- }
-#endif /* __BIG_ENDIAN */
- return 0;
- }
- }
- }
- return -EINVAL;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int wss_ioctl(struct net_device *dev, struct sm_state *sm, struct ifreq *ifr,
- struct hdlcdrv_ioctl *hi, int cmd)
-{
- struct sm_ioctl bi;
- int i;
-
- if (cmd != SIOCDEVPRIVATE)
- return -ENOIOCTLCMD;
-
- if (hi->cmd == HDLCDRVCTL_MODEMPARMASK)
- return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ |
- HDLCDRV_PARMASK_DMA | HDLCDRV_PARMASK_SERIOBASE |
- HDLCDRV_PARMASK_PARIOBASE | HDLCDRV_PARMASK_MIDIIOBASE;
-
- if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
- return -EFAULT;
-
- switch (bi.cmd) {
- default:
- return -ENOIOCTLCMD;
-
- case SMCTL_GETMIXER:
- i = 0;
- bi.data.mix.sample_rate = sm->mode_rx->srate;
- bi.data.mix.bit_rate = sm->hdrv.par.bitrate;
- bi.data.mix.mixer_type = SCSTATE->crystal ?
- SM_MIXER_CRYSTAL : SM_MIXER_AD1848;
- if (((SCSTATE->crystal ? 0x2c0c20fflu: 0x20fflu)
- >> bi.data.mix.reg) & 1) {
- bi.data.mix.data = read_codec(dev, bi.data.mix.reg);
- i = 1;
- }
- if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
- return -EFAULT;
- return i;
-
- case SMCTL_SETMIXER:
- if (!capable(CAP_SYS_RAWIO))
- return -EACCES;
- if ((bi.data.mix.mixer_type != SM_MIXER_CRYSTAL ||
- !SCSTATE->crystal) &&
- (bi.data.mix.mixer_type != SM_MIXER_AD1848 ||
- bi.data.mix.reg >= 0x10))
- return -EINVAL;
- if (!((0x2c0c20fflu >> bi.data.mix.reg) & 1))
- return -EACCES;
- write_codec(dev, bi.data.mix.reg, bi.data.mix.data);
- return 0;
-
- }
- if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
- return -EFAULT;
- return 0;
-
-}
-
-/* --------------------------------------------------------------------- */
-
-const struct hardware_info sm_hw_wss = {
- "wss", sizeof(struct sc_state_wss),
- wss_open, wss_close, wss_ioctl, wss_sethw
-};
-
-/* --------------------------------------------------------------------- */
-
-static void setup_fdx_dma_wss(struct net_device *dev, struct sm_state *sm)
-{
- unsigned long flags;
- unsigned char oldcodecmode, codecdma;
- long abrt;
- unsigned int osamps, isamps;
-
- save_flags(flags);
- cli();
- /*
- * perform the final DMA sequence to disable the codec request
- */
- oldcodecmode = read_codec(dev, 9);
- write_codec(dev, 9, 0); /* disable codec DMA */
- wss_ack_int(dev);
- if ((codecdma = read_codec(dev, 11)) & 0x10) {
- dma_setup(sm, 1, dev->dma);
- dma_setup(sm, 0, sm->hdrv.ptt_out.dma2);
- abrt = 0;
- while (((codecdma = read_codec(dev, 11)) & 0x10) || ((++abrt) >= 0x10000));
- }
- wss_set_codec_fmt(dev, sm, SCSTATE->fmt[1], SCSTATE->fmt[0], 1, 1);
- osamps = dma_setup(sm, 1, dev->dma) - 1;
- isamps = dma_setup(sm, 0, sm->hdrv.ptt_out.dma2) - 1;
- write_codec(dev, 15, osamps & 0xff);
- write_codec(dev, 14, osamps >> 8);
- if (SCSTATE->crystal) {
- write_codec(dev, 31, isamps & 0xff);
- write_codec(dev, 30, isamps >> 8);
- }
- write_codec(dev, 9, 3);
- restore_flags(flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-static void wssfdx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct net_device *dev = (struct net_device *)dev_id;
- struct sm_state *sm = (struct sm_state *)dev->priv;
- unsigned long flags;
- unsigned char cry_int_src;
- unsigned icfrag, ocfrag, isamps, osamps;
-
- if (!dev || !sm || !sm->mode_rx || !sm->mode_tx ||
- sm->hdrv.magic != HDLCDRV_MAGIC)
- return;
- save_flags(flags);
- cli();
- if (SCSTATE->crystal) {
- /* Crystal has an essentially different interrupt handler! */
- cry_int_src = read_codec(dev, 0x18);
- wss_ack_int(dev);
- if (cry_int_src & 0x10) { /* playback interrupt */
- disable_dma(dev->dma);
- clear_dma_ff(dev->dma);
- osamps = dma_ptr(sm, 1, dev->dma, &ocfrag)-1;
- write_codec(dev, 15, osamps & 0xff);
- write_codec(dev, 14, osamps >> 8);
- enable_dma(dev->dma);
- }
- if (cry_int_src & 0x20) { /* capture interrupt */
- disable_dma(sm->hdrv.ptt_out.dma2);
- clear_dma_ff(sm->hdrv.ptt_out.dma2);
- isamps = dma_ptr(sm, 0, sm->hdrv.ptt_out.dma2, &icfrag)-1;
- write_codec(dev, 31, isamps & 0xff);
- write_codec(dev, 30, isamps >> 8);
- enable_dma(sm->hdrv.ptt_out.dma2);
- }
- restore_flags(flags);
- sm_int_freq(sm);
- sti();
- if (cry_int_src & 0x10) {
- if (dma_end_transmit(sm, ocfrag))
- dma_clear_transmit(sm);
- dma_transmit(sm);
- }
- if (cry_int_src & 0x20) {
- dma_receive(sm, icfrag);
- hdlcdrv_arbitrate(dev, &sm->hdrv);
- }
- sm_output_status(sm);
- hdlcdrv_transmitter(dev, &sm->hdrv);
- hdlcdrv_receiver(dev, &sm->hdrv);
- return;
- }
- wss_ack_int(dev);
- disable_dma(dev->dma);
- disable_dma(sm->hdrv.ptt_out.dma2);
- clear_dma_ff(dev->dma);
- clear_dma_ff(sm->hdrv.ptt_out.dma2);
- osamps = dma_ptr(sm, 1, dev->dma, &ocfrag)-1;
- isamps = dma_ptr(sm, 0, sm->hdrv.ptt_out.dma2, &icfrag)-1;
- write_codec(dev, 15, osamps & 0xff);
- write_codec(dev, 14, osamps >> 8);
- if (SCSTATE->crystal) {
- write_codec(dev, 31, isamps & 0xff);
- write_codec(dev, 30, isamps >> 8);
- }
- enable_dma(dev->dma);
- enable_dma(sm->hdrv.ptt_out.dma2);
- restore_flags(flags);
- sm_int_freq(sm);
- sti();
- if (dma_end_transmit(sm, ocfrag))
- dma_clear_transmit(sm);
- dma_transmit(sm);
- dma_receive(sm, icfrag);
- hdlcdrv_arbitrate(dev, &sm->hdrv);
- sm_output_status(sm);
- hdlcdrv_transmitter(dev, &sm->hdrv);
- hdlcdrv_receiver(dev, &sm->hdrv);
-}
-
-/* --------------------------------------------------------------------- */
-
-static int wssfdx_open(struct net_device *dev, struct sm_state *sm)
-{
- if (!dev || !sm || !sm->mode_rx || !sm->mode_tx)
- return -ENXIO;
- if (dev->base_addr <= 0 || dev->base_addr > 0x1000-WSS_EXTENT ||
- dev->irq < 2 || dev->irq > 15 || dev->dma > 3)
- return -ENXIO;
- if (check_region(dev->base_addr, WSS_EXTENT))
- return -EACCES;
- /*
- * check if a card is available
- */
- if (wss_init_codec(dev, sm, 1, 1, 1, 0, 0, -45, -45))
- return -ENODEV;
- /*
- * initialize some variables
- */
- if (!(sm->dma.ibuf = kmalloc(sm->dma.ifragsz * (NUM_FRAGMENTS+1), GFP_KERNEL | GFP_DMA)))
- return -ENOMEM;
- if (!(sm->dma.obuf = kmalloc(sm->dma.ofragsz * NUM_FRAGMENTS, GFP_KERNEL | GFP_DMA))) {
- kfree(sm->dma.ibuf);
- return -ENOMEM;
- }
- dma_init_transmit(sm);
- dma_init_receive(sm);
-
- memset(&sm->m, 0, sizeof(sm->m));
- memset(&sm->d, 0, sizeof(sm->d));
- if (sm->mode_tx->init)
- sm->mode_tx->init(sm);
- if (sm->mode_rx->init)
- sm->mode_rx->init(sm);
-
- if (request_dma(dev->dma, sm->hwdrv->hw_name)) {
- kfree(sm->dma.ibuf);
- kfree(sm->dma.obuf);
- return -EBUSY;
- }
- if (request_dma(sm->hdrv.ptt_out.dma2, sm->hwdrv->hw_name)) {
- kfree(sm->dma.ibuf);
- kfree(sm->dma.obuf);
- free_dma(dev->dma);
- return -EBUSY;
- }
- if (request_irq(dev->irq, wssfdx_interrupt, SA_INTERRUPT,
- sm->hwdrv->hw_name, dev)) {
- kfree(sm->dma.ibuf);
- kfree(sm->dma.obuf);
- free_dma(dev->dma);
- free_dma(sm->hdrv.ptt_out.dma2);
- return -EBUSY;
- }
- request_region(dev->base_addr, WSS_EXTENT, sm->hwdrv->hw_name);
- setup_fdx_dma_wss(dev, sm);
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int wssfdx_close(struct net_device *dev, struct sm_state *sm)
-{
- if (!dev || !sm)
- return -EINVAL;
- /*
- * disable interrupts
- */
- disable_dma(dev->dma);
- disable_dma(sm->hdrv.ptt_out.dma2);
- write_codec(dev, 9, 0xc); /* disable codec */
- free_irq(dev->irq, dev);
- free_dma(dev->dma);
- free_dma(sm->hdrv.ptt_out.dma2);
- release_region(dev->base_addr, WSS_EXTENT);
- kfree(sm->dma.ibuf);
- kfree(sm->dma.obuf);
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int wssfdx_sethw(struct net_device *dev, struct sm_state *sm, char *mode)
-{
- char *cp = strchr(mode, '.');
- const struct modem_tx_info **mtp = sm_modem_tx_table;
- const struct modem_rx_info **mrp;
- int i;
-
- if (!strcmp(mode, "off")) {
- sm->mode_tx = NULL;
- sm->mode_rx = NULL;
- return 0;
- }
- if (cp)
- *cp++ = '\0';
- else
- cp = mode;
- for (; *mtp; mtp++) {
- if ((*mtp)->loc_storage > sizeof(sm->m)) {
- printk(KERN_ERR "%s: insufficient storage for modulator %s (%d)\n",
- sm_drvname, (*mtp)->name, (*mtp)->loc_storage);
- continue;
- }
- if (!(*mtp)->name || strcmp((*mtp)->name, mode))
- continue;
- if ((i = wss_srate_index((*mtp)->srate)) < 0)
- continue;
- for (mrp = sm_modem_rx_table; *mrp; mrp++) {
- if ((*mrp)->loc_storage > sizeof(sm->d)) {
- printk(KERN_ERR "%s: insufficient storage for demodulator %s (%d)\n",
- sm_drvname, (*mrp)->name, (*mrp)->loc_storage);
- continue;
- }
- if ((*mrp)->name && !strcmp((*mrp)->name, cp) &&
- (*mtp)->srate == (*mrp)->srate) {
- sm->mode_tx = *mtp;
- sm->mode_rx = *mrp;
- SCSTATE->fmt[0] = SCSTATE->fmt[1] = i;
- sm->dma.ifragsz = sm->dma.ofragsz = (sm->mode_rx->srate + 50)/100;
- if (sm->dma.ifragsz < sm->mode_rx->overlap)
- sm->dma.ifragsz = sm->mode_rx->overlap;
- sm->dma.i16bit = sm->dma.o16bit = 2;
- if (sm->mode_rx->demodulator_s16) {
- sm->dma.i16bit = 1;
- sm->dma.ifragsz <<= 1;
-#ifdef __BIG_ENDIAN /* big endian 16bit only works on crystal cards... */
- SCSTATE->fmt[0] |= 0xc0;
-#else /* __BIG_ENDIAN */
- SCSTATE->fmt[0] |= 0x40;
-#endif /* __BIG_ENDIAN */
- } else if (sm->mode_rx->demodulator_u8)
- sm->dma.i16bit = 0;
- if (sm->mode_tx->modulator_s16) {
- sm->dma.o16bit = 1;
- sm->dma.ofragsz <<= 1;
-#ifdef __BIG_ENDIAN /* big endian 16bit only works on crystal cards... */
- SCSTATE->fmt[1] |= 0xc0;
-#else /* __BIG_ENDIAN */
- SCSTATE->fmt[1] |= 0x40;
-#endif /* __BIG_ENDIAN */
- } else if (sm->mode_tx->modulator_u8)
- sm->dma.o16bit = 0;
- if (sm->dma.i16bit == 2 || sm->dma.o16bit == 2) {
- printk(KERN_INFO "%s: mode %s or %s unusable\n", sm_drvname,
- sm->mode_rx->name, sm->mode_tx->name);
- sm->mode_tx = NULL;
- sm->mode_rx = NULL;
- return -EINVAL;
- }
- return 0;
- }
- }
- }
- return -EINVAL;
-}
-
-/* --------------------------------------------------------------------- */
-
-static int wssfdx_ioctl(struct net_device *dev, struct sm_state *sm, struct ifreq *ifr,
- struct hdlcdrv_ioctl *hi, int cmd)
-{
- if (cmd != SIOCDEVPRIVATE)
- return -ENOIOCTLCMD;
-
- if (hi->cmd == HDLCDRVCTL_MODEMPARMASK)
- return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ |
- HDLCDRV_PARMASK_DMA | HDLCDRV_PARMASK_DMA2 |
- HDLCDRV_PARMASK_SERIOBASE | HDLCDRV_PARMASK_PARIOBASE |
- HDLCDRV_PARMASK_MIDIIOBASE;
-
- return wss_ioctl(dev, sm, ifr, hi, cmd);
-}
-
-/* --------------------------------------------------------------------- */
-
-const struct hardware_info sm_hw_wssfdx = {
- "wssfdx", sizeof(struct sc_state_wss),
- wssfdx_open, wssfdx_close, wssfdx_ioctl, wssfdx_sethw
-};
-
-/* --------------------------------------------------------------------- */
-
-#undef SCSTATE
diff --git a/drivers/net/hamradio/soundmodem/smdma.h b/drivers/net/hamradio/soundmodem/smdma.h
deleted file mode 100644
index 9e48713116ae..000000000000
--- a/drivers/net/hamradio/soundmodem/smdma.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*****************************************************************************/
-
-/*
- * smdma.h -- soundcard radio modem driver dma buffer routines.
- *
- * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Please note that the GPL allows you to use the driver, NOT the radio.
- * In order to use the radio, you need a license from the communications
- * authority of your country.
- *
- */
-
-#ifndef _SMDMA_H
-#define _SMDMA_H
-
-/* ---------------------------------------------------------------------- */
-
-#include "sm.h"
-
-/* ---------------------------------------------------------------------- */
-
-#define DMA_MODE_AUTOINIT 0x10
-#define NUM_FRAGMENTS 4
-
-/*
- * NOTE: make sure that hdlcdrv_hdlcbuffer contains enough space
- * for the modulator to fill the whole DMA buffer without underrun
- * at the highest possible baud rate, otherwise the TX state machine will
- * not work correctly. That is (9k6 FSK): HDLCDRV_HDLCBUFFER > 6*NUM_FRAGMENTS
- */
-
-/* --------------------------------------------------------------------- */
-/*
- * ===================== DMA buffer management ===========================
- */
-
-/*
- * returns the number of samples per fragment
- */
-static __inline__ unsigned int dma_setup(struct sm_state *sm, int send, unsigned int dmanr)
-{
- if (send) {
- disable_dma(dmanr);
- clear_dma_ff(dmanr);
- set_dma_mode(dmanr, DMA_MODE_WRITE | DMA_MODE_AUTOINIT);
- set_dma_addr(dmanr, virt_to_bus(sm->dma.obuf));
- set_dma_count(dmanr, sm->dma.ofragsz * NUM_FRAGMENTS);
- enable_dma(dmanr);
- if (sm->dma.o16bit)
- return sm->dma.ofragsz/2;
- return sm->dma.ofragsz;
- } else {
- disable_dma(dmanr);
- clear_dma_ff(dmanr);
- set_dma_mode(dmanr, DMA_MODE_READ | DMA_MODE_AUTOINIT);
- set_dma_addr(dmanr, virt_to_bus(sm->dma.ibuf));
- set_dma_count(dmanr, sm->dma.ifragsz * NUM_FRAGMENTS);
- enable_dma(dmanr);
- if (sm->dma.i16bit)
- return sm->dma.ifragsz/2;
- return sm->dma.ifragsz;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static __inline__ unsigned int dma_ptr(struct sm_state *sm, int send, unsigned int dmanr,
- unsigned int *curfrag)
-{
- unsigned int dmaptr, sz, frg, offs;
-
- dmaptr = get_dma_residue(dmanr);
- if (send) {
- sz = sm->dma.ofragsz * NUM_FRAGMENTS;
- if (dmaptr == 0 || dmaptr > sz)
- dmaptr = sz;
- dmaptr--;
- frg = dmaptr / sm->dma.ofragsz;
- offs = (dmaptr % sm->dma.ofragsz) + 1;
- *curfrag = NUM_FRAGMENTS - 1 - frg;
-#ifdef SM_DEBUG
- if (!sm->debug_vals.dma_residue || offs < sm->debug_vals.dma_residue)
- sm->debug_vals.dma_residue = offs;
-#endif /* SM_DEBUG */
- if (sm->dma.o16bit)
- return offs/2;
- return offs;
- } else {
- sz = sm->dma.ifragsz * NUM_FRAGMENTS;
- if (dmaptr == 0 || dmaptr > sz)
- dmaptr = sz;
- dmaptr--;
- frg = dmaptr / sm->dma.ifragsz;
- offs = (dmaptr % sm->dma.ifragsz) + 1;
- *curfrag = NUM_FRAGMENTS - 1 - frg;
-#ifdef SM_DEBUG
- if (!sm->debug_vals.dma_residue || offs < sm->debug_vals.dma_residue)
- sm->debug_vals.dma_residue = offs;
-#endif /* SM_DEBUG */
- if (sm->dma.i16bit)
- return offs/2;
- return offs;
- }
-}
-
-/* --------------------------------------------------------------------- */
-
-static __inline__ int dma_end_transmit(struct sm_state *sm, unsigned int curfrag)
-{
- unsigned int diff = (NUM_FRAGMENTS + curfrag - sm->dma.ofragptr) % NUM_FRAGMENTS;
-
- sm->dma.ofragptr = curfrag;
- if (sm->dma.ptt_cnt <= 0) {
- sm->dma.ptt_cnt = 0;
- return 0;
- }
- sm->dma.ptt_cnt -= diff;
- if (sm->dma.ptt_cnt <= 0) {
- sm->dma.ptt_cnt = 0;
- return -1;
- }
- return 0;
-}
-
-static __inline__ void dma_transmit(struct sm_state *sm)
-{
- void *p;
-
- while (sm->dma.ptt_cnt < NUM_FRAGMENTS && hdlcdrv_ptt(&sm->hdrv)) {
- p = (unsigned char *)sm->dma.obuf + sm->dma.ofragsz *
- ((sm->dma.ofragptr + sm->dma.ptt_cnt) % NUM_FRAGMENTS);
- if (sm->dma.o16bit) {
- time_exec(sm->debug_vals.mod_cyc,
- sm->mode_tx->modulator_s16(sm, p, sm->dma.ofragsz/2));
- } else {
- time_exec(sm->debug_vals.mod_cyc,
- sm->mode_tx->modulator_u8(sm, p, sm->dma.ofragsz));
- }
- sm->dma.ptt_cnt++;
- }
-}
-
-static __inline__ void dma_init_transmit(struct sm_state *sm)
-{
- sm->dma.ofragptr = 0;
- sm->dma.ptt_cnt = 0;
-}
-
-static __inline__ void dma_start_transmit(struct sm_state *sm)
-{
- sm->dma.ofragptr = 0;
- if (sm->dma.o16bit) {
- time_exec(sm->debug_vals.mod_cyc,
- sm->mode_tx->modulator_s16(sm, sm->dma.obuf, sm->dma.ofragsz/2));
- } else {
- time_exec(sm->debug_vals.mod_cyc,
- sm->mode_tx->modulator_u8(sm, sm->dma.obuf, sm->dma.ofragsz));
- }
- sm->dma.ptt_cnt = 1;
-}
-
-static __inline__ void dma_clear_transmit(struct sm_state *sm)
-{
- sm->dma.ptt_cnt = 0;
- memset(sm->dma.obuf, (sm->dma.o16bit) ? 0 : 0x80, sm->dma.ofragsz * NUM_FRAGMENTS);
-}
-
-/* --------------------------------------------------------------------- */
-
-static __inline__ void dma_receive(struct sm_state *sm, unsigned int curfrag)
-{
- void *p;
-
- while (sm->dma.ifragptr != curfrag) {
- if (sm->dma.ifragptr)
- p = (unsigned char *)sm->dma.ibuf +
- sm->dma.ifragsz * sm->dma.ifragptr;
- else {
- p = (unsigned char *)sm->dma.ibuf + NUM_FRAGMENTS * sm->dma.ifragsz;
- memcpy(p, sm->dma.ibuf, sm->dma.ifragsz);
- }
- if (sm->dma.o16bit) {
- time_exec(sm->debug_vals.demod_cyc,
- sm->mode_rx->demodulator_s16(sm, p, sm->dma.ifragsz/2));
- } else {
- time_exec(sm->debug_vals.demod_cyc,
- sm->mode_rx->demodulator_u8(sm, p, sm->dma.ifragsz));
- }
- sm->dma.ifragptr = (sm->dma.ifragptr + 1) % NUM_FRAGMENTS;
- }
-}
-
-static __inline__ void dma_init_receive(struct sm_state *sm)
-{
- sm->dma.ifragptr = 0;
-}
-
-/* --------------------------------------------------------------------- */
-#endif /* _SMDMA_H */
-
-
-
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index 51d1caed60f2..42ed8199d9eb 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -162,7 +162,7 @@ static int vlsi_proc_pdev(struct pci_dev *pdev, char *buf, int len)
return 0;
out += sprintf(out, "\n%s (vid/did: %04x/%04x)\n",
- pdev->name, (int)pdev->vendor, (int)pdev->device);
+ pdev->dev.name, (int)pdev->vendor, (int)pdev->device);
out += sprintf(out, "pci-power-state: %u\n", (unsigned) pdev->current_state);
out += sprintf(out, "resources: irq=%u / io=0x%04x / dma_mask=0x%016Lx\n",
pdev->irq, (unsigned)pci_resource_start(pdev, 0), (u64)pdev->dma_mask);
@@ -1517,7 +1517,7 @@ static void vlsi_tx_timeout(struct net_device *ndev)
if (vlsi_start_hw(idev))
printk(KERN_CRIT "%s: failed to restart hw - %s(%s) unusable!\n",
- __FUNCTION__, idev->pdev->name, ndev->name);
+ __FUNCTION__, idev->pdev->dev.name, ndev->name);
else
netif_start_queue(ndev);
}
@@ -1765,7 +1765,7 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pdev->current_state = 0; /* hw must be running now */
printk(KERN_INFO "%s: IrDA PCI controller %s detected\n",
- drivername, pdev->name);
+ drivername, pdev->dev.name);
if ( !pci_resource_start(pdev,0)
|| !(pci_resource_flags(pdev,0) & IORESOURCE_IO) ) {
@@ -1863,7 +1863,7 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev)
* ndev->destructor called (if present) when going to free
*/
- printk(KERN_INFO "%s: %s removed\n", drivername, pdev->name);
+ printk(KERN_INFO "%s: %s removed\n", drivername, pdev->dev.name);
}
#ifdef CONFIG_PM
@@ -1879,7 +1879,7 @@ static int vlsi_irda_save_state(struct pci_dev *pdev, u32 state)
{
if (state < 1 || state > 3 ) {
printk( KERN_ERR "%s - %s: invalid pm state request: %u\n",
- __FUNCTION__, pdev->name, state);
+ __FUNCTION__, pdev->dev.name, state);
return -1;
}
return 0;
@@ -1892,11 +1892,11 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, u32 state)
if (state < 1 || state > 3 ) {
printk( KERN_ERR "%s - %s: invalid pm state request: %u\n",
- __FUNCTION__, pdev->name, state);
+ __FUNCTION__, pdev->dev.name, state);
return 0;
}
if (!ndev) {
- printk(KERN_ERR "%s - %s: no netdevice \n", __FUNCTION__, pdev->name);
+ printk(KERN_ERR "%s - %s: no netdevice \n", __FUNCTION__, pdev->dev.name);
return 0;
}
idev = ndev->priv;
@@ -1908,7 +1908,7 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, u32 state)
}
else
printk(KERN_ERR "%s - %s: invalid suspend request %u -> %u\n",
- __FUNCTION__, pdev->name, pdev->current_state, state);
+ __FUNCTION__, pdev->dev.name, pdev->current_state, state);
up(&idev->sem);
return 0;
}
@@ -1935,14 +1935,14 @@ static int vlsi_irda_resume(struct pci_dev *pdev)
vlsi_irda_dev_t *idev;
if (!ndev) {
- printk(KERN_ERR "%s - %s: no netdevice \n", __FUNCTION__, pdev->name);
+ printk(KERN_ERR "%s - %s: no netdevice \n", __FUNCTION__, pdev->dev.name);
return 0;
}
idev = ndev->priv;
down(&idev->sem);
if (pdev->current_state == 0) {
up(&idev->sem);
- printk(KERN_ERR "%s - %s: already resumed\n", __FUNCTION__, pdev->name);
+ printk(KERN_ERR "%s - %s: already resumed\n", __FUNCTION__, pdev->dev.name);
return 0;
}
diff --git a/drivers/net/pcmcia/aironet4500_cs.c b/drivers/net/pcmcia/aironet4500_cs.c
index 3ab22e11441c..6f9038114274 100644
--- a/drivers/net/pcmcia/aironet4500_cs.c
+++ b/drivers/net/pcmcia/aironet4500_cs.c
@@ -39,11 +39,6 @@ DRV_NAME ".c v" DRV_VERSION " 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n";
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h>
-#if LINUX_VERSION_CODE < 0x20300
-#ifdef MODULE
-#include <pcmcia/k_compat.h>
-#endif
-#endif
#include <pcmcia/ds.h>
#include <asm/uaccess.h>
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index c01aa0baab96..e35cb8da5cdf 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -300,7 +300,8 @@ static dev_link_t *pcnet_attach(void)
memset(info, 0, sizeof(*info));
link = &info->link; dev = &info->dev;
link->priv = info;
-
+
+ init_timer(&link->release);
link->release.function = &pcnet_release;
link->release.data = (u_long)link;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index b9a8c3edaa56..d1c41d0b5bcd 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -357,6 +357,7 @@ static dev_link_t *smc91c92_attach(void)
memset(smc, 0, sizeof(struct smc_private));
link = &smc->link; dev = &smc->dev;
spin_lock_init(&smc->lock);
+ init_timer(&link->release);
link->release.function = &smc91c92_release;
link->release.data = (u_long)link;
link->io.NumPorts1 = 16;
diff --git a/drivers/net/sk98lin/h/skgehw.h b/drivers/net/sk98lin/h/skgehw.h
index fc97a511da89..ea59ee2e1c27 100644
--- a/drivers/net/sk98lin/h/skgehw.h
+++ b/drivers/net/sk98lin/h/skgehw.h
@@ -813,7 +813,7 @@ extern "C" {
/* Bit 31..12: reserved */
#define IS_IRQ_MST_ERR (1L<<11) /* Bit 11: IRQ master error */
/* PERR,RMABORT,RTABORT,DATAPERR */
-#define IS_IRQ_STAT (1L<<10) /* Bit 10: IRQ status execption */
+#define IS_IRQ_STAT (1L<<10) /* Bit 10: IRQ status exception */
/* RMABORT, RTABORT, DATAPERR */
#define IS_NO_STAT_M1 (1L<<9) /* Bit 9: No Rx Status from MAC1*/
#define IS_NO_STAT_M2 (1L<<8) /* Bit 8: No Rx Status from MAC2*/
diff --git a/drivers/net/skfp/h/skfbi.h b/drivers/net/skfp/h/skfbi.h
index 43ddc5561b84..7c7de57987f6 100644
--- a/drivers/net/skfp/h/skfbi.h
+++ b/drivers/net/skfp/h/skfbi.h
@@ -1308,7 +1308,7 @@
#define IS_I2C_READY (1L<<27) /* Bit 27: (ML) IRQ on end of I2C tx */
#define IS_IRQ_SW (1L<<26) /* Bit 26: (ML) SW forced IRQ */
#define IS_EXT_REG (1L<<25) /* Bit 25: (ML) IRQ from external reg*/
-#define IS_IRQ_STAT (1L<<24) /* Bit 24: IRQ status execption */
+#define IS_IRQ_STAT (1L<<24) /* Bit 24: IRQ status exception */
/* PERR, RMABORT, RTABORT DATAPERR */
#define IS_IRQ_MST_ERR (1L<<23) /* Bit 23: IRQ master error */
/* RMABORT, RTABORT, DATAPERR */
@@ -1360,7 +1360,7 @@
#define IRQ_I2C_READY (1L<<27) /* Bit 27: (ML) IRQ on end of I2C tx */
#define IRQ_SW (1L<<26) /* Bit 26: (ML) SW forced IRQ */
#define IRQ_EXT_REG (1L<<25) /* Bit 25: (ML) IRQ from external reg*/
-#define IRQ_STAT (1L<<24) /* Bit 24: IRQ status execption */
+#define IRQ_STAT (1L<<24) /* Bit 24: IRQ status exception */
/* PERR, RMABORT, RTABORT DATAPERR */
#define IRQ_MST_ERR (1L<<23) /* Bit 23: IRQ master error */
/* RMABORT, RTABORT, DATAPERR */
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 4bf23c2f838e..1c5589d89a82 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -261,7 +261,7 @@ static int sl_realloc_bufs(struct slip *sl, int mtu)
if (xbuff == NULL || rbuff == NULL) {
#endif
if (mtu >= sl->mtu) {
- printk("%s: unable to grow slip buffers, MTU change cancelled.\n",
+ printk(KERN_WARNING "%s: unable to grow slip buffers, MTU change cancelled.\n",
dev->name);
err = -ENOBUFS;
}
@@ -348,7 +348,7 @@ sl_bump(struct slip *sl)
if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) {
/* ignore compressed packets when CSLIP is off */
if (!(sl->mode & SL_MODE_CSLIP)) {
- printk("%s: compressed packet ignored\n", sl->dev->name);
+ printk(KERN_WARNING "%s: compressed packet ignored\n", sl->dev->name);
return;
}
/* make sure we've reserved enough space for uncompress to use */
@@ -365,7 +365,7 @@ sl_bump(struct slip *sl)
/* turn on header compression */
sl->mode |= SL_MODE_CSLIP;
sl->mode &= ~SL_MODE_ADAPTIVE;
- printk("%s: header compression turned on\n", sl->dev->name);
+ printk(KERN_INFO "%s: header compression turned on\n", sl->dev->name);
}
sl->rbuff[0] &= 0x4f;
if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) {
@@ -379,7 +379,7 @@ sl_bump(struct slip *sl)
skb = dev_alloc_skb(count);
if (skb == NULL) {
- printk("%s: memory squeeze, dropping packet.\n", sl->dev->name);
+ printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name);
sl->rx_dropped++;
return;
}
@@ -400,7 +400,7 @@ sl_encaps(struct slip *sl, unsigned char *icp, int len)
int actual, count;
if (len > sl->mtu) { /* Sigh, shouldn't occur BUT ... */
- printk ("%s: truncating oversized transmit packet!\n", sl->dev->name);
+ printk(KERN_WARNING "%s: truncating oversized transmit packet!\n", sl->dev->name);
sl->tx_dropped++;
sl_unlock(sl);
return;
@@ -487,7 +487,7 @@ static void sl_tx_timeout(struct net_device *dev)
/* 20 sec timeout not reached */
goto out;
}
- printk("%s: transmit timed out, %s?\n", dev->name,
+ printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
(sl->tty->driver.chars_in_buffer(sl->tty) || sl->xleft) ?
"bad line quality" : "driver error");
sl->xleft = 0;
@@ -510,7 +510,7 @@ sl_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock(&sl->lock);
if (!netif_running(dev)) {
spin_unlock(&sl->lock);
- printk("%s: xmit call when iface is down\n", dev->name);
+ printk(KERN_WARNING "%s: xmit call when iface is down\n", dev->name);
dev_kfree_skb(skb);
return 0;
}
@@ -1332,7 +1332,7 @@ int __init slip_init_ctrl_dev(void)
".\n",
SLIP_VERSION, slip_maxdev );
#if defined(SL_INCLUDE_CSLIP) && !defined(MODULE)
- printk("CSLIP: code copyright 1989 Regents of the University of California.\n");
+ printk(KERN_INFO "CSLIP: code copyright 1989 Regents of the University of California.\n");
#endif
#ifdef CONFIG_SLIP_SMART
printk(KERN_INFO "SLIP linefill/keepalive option.\n");
@@ -1341,7 +1341,7 @@ int __init slip_init_ctrl_dev(void)
slip_ctrls = (slip_ctrl_t **) kmalloc(sizeof(void*)*slip_maxdev, GFP_KERNEL);
if (slip_ctrls == NULL)
{
- printk("SLIP: Can't allocate slip_ctrls[] array! Uaargh! (-> No SLIP available)\n");
+ printk(KERN_ERR "SLIP: Can't allocate slip_ctrls[] array! Uaargh! (-> No SLIP available)\n");
return -ENOMEM;
}
@@ -1364,7 +1364,7 @@ int __init slip_init_ctrl_dev(void)
sl_ldisc.receive_room = slip_receive_room;
sl_ldisc.write_wakeup = slip_write_wakeup;
if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0) {
- printk("SLIP: can't register line discipline (err = %d)\n", status);
+ printk(KERN_ERR "SLIP: can't register line discipline (err = %d)\n", status);
}
@@ -1418,7 +1418,7 @@ cleanup_module(void)
if (slc) {
unregister_netdev(&slc->dev);
if (slc->ctrl.tty) {
- printk("%s: tty discipline is still running\n", slc->dev.name);
+ printk(KERN_ERR "%s: tty discipline is still running\n", slc->dev.name);
/* Pin module forever */
MOD_INC_USE_COUNT;
busy++;
@@ -1436,7 +1436,7 @@ cleanup_module(void)
}
if ((i = tty_register_ldisc(N_SLIP, NULL)))
{
- printk("SLIP: can't unregister line discipline (err = %d)\n", i);
+ printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i);
}
}
#endif /* MODULE */
@@ -1498,7 +1498,7 @@ static void sl_keepalive(unsigned long sls)
/* keepalive still high :(, we must hangup */
if( sl->outfill ) /* outfill timer must be deleted too */
(void)del_timer(&sl->outfill_timer);
- printk("%s: no packets received during keepalive timeout, hangup.\n", sl->dev->name);
+ printk(KERN_DEBUG "%s: no packets received during keepalive timeout, hangup.\n", sl->dev->name);
tty_hangup(sl->tty); /* this must hangup tty & close slip */
/* I think we need not something else */
goto out;
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index fbfcb73738bb..f1e50a96ba8d 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -315,7 +315,7 @@ int __devinit xl_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->irq=pdev->irq;
dev->base_addr=pci_resource_start(pdev,0) ;
dev->init=NULL ; /* Must be null with new api, otherwise get called twice */
- xl_priv->xl_card_name = (char *)pdev->name ;
+ xl_priv->xl_card_name = (char *)pdev->dev.name ;
xl_priv->xl_mmio=ioremap(pci_resource_start(pdev,1), XL_IO_SPACE);
xl_priv->pdev = pdev ;
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
index 7b920a4f9237..7a0aef9c2898 100644
--- a/drivers/net/tokenring/olympic.c
+++ b/drivers/net/tokenring/olympic.c
@@ -230,7 +230,7 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device
dev->irq=pdev->irq;
dev->base_addr=pci_resource_start(pdev, 0);
dev->init=NULL; /* Must be NULL otherwise we get called twice */
- olympic_priv->olympic_card_name = (char *)pdev->name ;
+ olympic_priv->olympic_card_name = (char *)pdev->dev.name ;
olympic_priv->olympic_mmio = ioremap(pci_resource_start(pdev,1),256);
olympic_priv->olympic_lap = ioremap(pci_resource_start(pdev,2),2048);
olympic_priv->pdev = pdev ;
@@ -654,8 +654,8 @@ static int olympic_open(struct net_device *dev)
printk(" stat_ring[7]: %p\n", &(olympic_priv->olympic_rx_status_ring[7]) );
printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);
- printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr =
-%08x\n",olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ;
+ printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr = %08x\n",
+ olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ;
#endif
writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | i,olympic_mmio+RXENQ);
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index f46c7e9c82ad..41f1c3c0b583 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -284,9 +284,11 @@ static struct sv11_device *sv11_init(int iobase, int irq)
goto dmafail;
}
}
- save_flags(flags);
- cli();
-
+
+ /* Kill our private IRQ line the hostess can end up chattering
+ until the configuration is set */
+ disable_irq(irq);
+
/*
* Begin normal initialise
*/
@@ -294,7 +296,7 @@ static struct sv11_device *sv11_init(int iobase, int irq)
if(z8530_init(dev)!=0)
{
printk(KERN_ERR "Z8530 series device not found.\n");
- restore_flags(flags);
+ enable_irq(irq);
goto dmafail2;
}
z8530_channel_load(&dev->chanB, z8530_dead_port);
@@ -303,8 +305,8 @@ static struct sv11_device *sv11_init(int iobase, int irq)
else
z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream_85230);
- restore_flags(flags);
-
+ enable_irq(irq);
+
/*
* Now we can take the IRQ
@@ -399,7 +401,7 @@ static struct sv11_device *sv11_unit;
int init_module(void)
{
- printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.02.\n");
+ printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.03.\n");
printk(KERN_INFO "(c) Copyright 2001, Red Hat Inc.\n");
if((sv11_unit=sv11_init(io,irq))==NULL)
return -ENODEV;
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index 378478faac1e..1dd84621ac02 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -3688,3 +3688,9 @@ static void __exit cpc_cleanup_module(void)
module_init(cpc_init);
module_exit(cpc_cleanup_module);
+
+MODULE_DESCRIPTION("Cyclades-PC300 cards driver");
+MODULE_AUTHOR( "Author: Ivan Passos <ivan@cyclades.com>\r\n"
+ "Maintainer: Henrique Gobbi <henrique.gobbi@cyclades.com");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
index 51c0c7baab69..00d023289f4d 100644
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -302,9 +302,8 @@ static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, i
if(request_dma(dev->chanA.rxdma, "SeaLevel (RX)")!=0)
goto dmafail;
- save_flags(flags);
- cli();
-
+ disable_irq(irq);
+
/*
* Begin normal initialise
*/
@@ -312,7 +311,7 @@ static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, i
if(z8530_init(dev)!=0)
{
printk(KERN_ERR "Z8530 series device not found.\n");
- restore_flags(flags);
+ enable_irq(irq);
goto dmafail2;
}
if(dev->type==Z85C30)
@@ -330,7 +329,7 @@ static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, i
* Now we can take the IRQ
*/
- restore_flags(flags);
+ enable_irq(irq);
for(u=0; u<2; u++)
{
@@ -446,7 +445,7 @@ static struct slvl_board *slvl_unit;
int init_module(void)
{
- printk(KERN_INFO "SeaLevel Z85230 Synchronous Driver v 0.01.\n");
+ printk(KERN_INFO "SeaLevel Z85230 Synchronous Driver v 0.02.\n");
printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n");
if((slvl_unit=slvl_init(io,irq, txdma, rxdma, slow))==NULL)
return -ENODEV;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6ad18c0eebbd..5c7a4c036755 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -729,6 +729,7 @@ device_initcall(pci_init);
__setup("pci=", pci_setup);
#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
+/* FIXME: Some boxes have multiple ISA bridges! */
struct pci_dev *isa_bridge;
EXPORT_SYMBOL(isa_bridge);
#endif
diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids
index 9103ec2160f9..123d4a292d28 100644
--- a/drivers/pci/pci.ids
+++ b/drivers/pci/pci.ids
@@ -497,8 +497,8 @@
1011 500b DE500B Fast Ethernet
1014 0001 10/100 EtherJet Cardbus
1025 0315 ALN315 Fast Ethernet
- 1033 800c PC-9821-CS01
- 1033 800d PC-9821NR-B06
+ 1033 800c PC-9821-CS01 100BASE-TX Interface Card
+ 1033 800d PC-9821NR-B06 100BASE-TX Interface Card
108d 0016 Rapidfire 2327 10/100 Ethernet
108d 0017 GoCard 2250 Ethernet 10/100 Cardbus
10b8 2005 SMC8032DT Extreme Ethernet 10/100
@@ -1049,17 +1049,21 @@
0003 ATM Controller
0004 R4000 PCI Bridge
0005 PCI to 486-like bus Bridge
- 0006 GUI Accelerator
+ 0006 PC-9800 Graphic Accelerator
0007 PCI to UX-Bus Bridge
- 0008 GUI Accelerator
- 0009 GUI Accelerator for W98
+ 0008 PC-9800 Graphic Accelerator
+ 0009 PCI to PC9800 Core-Graph Bridge
+ 0016 PCI to VL Bridge
001a [Nile II]
0021 Vrc4373 [Nile I]
0029 PowerVR PCX1
002a PowerVR 3D
+ 002c Star Alpha 2
+ 002d PCI to C-bus Bridge
0035 USB
1179 0001 USB
12ee 7000 Root Hub
+ 003b PCI to C-bus Bridge
003e NAPCCARD Cardbus Controller
0046 PowerVR PCX2 [midas]
005a Vrc5074 [Nile 4]
@@ -3489,7 +3493,7 @@
5811 FW323
dead 0800 FireWire Host Bus Adapter
11c2 Sand Microelectronics
-11c3 NEC Corp
+11c3 NEC Corporation
11c4 Document Technologies, Inc
11c5 Shiva Corporation
11c6 Dainippon Screen Mfg. Co. Ltd
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index e0bf3ec134be..c03c9eb68d03 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -212,6 +212,19 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, unsi
}
/*
+ * ATI Northbridge setups MCE the processor if you even
+ * read somewhere between 0x3b0->0x3bb or read 0x3d3
+ */
+
+static void __devinit quirk_ati_exploding_mce(struct pci_dev *dev)
+{
+ printk(KERN_INFO "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb.\n");
+ /* Mae rhaid in i beidio a edrych ar y lleoliad I/O hyn */
+ request_region(0x3b0, 0x0C, "RadeonIGP");
+ request_region(0x3d3, 0x01, "RadeonIGP");
+}
+
+/*
* Let's make the southbridge information explicit instead
* of having to worry about people probing the ACPI areas,
* for example.. (Yes, it happens, and if you read the wrong
@@ -313,6 +326,35 @@ static void __devinit quirk_via_ioapic(struct pci_dev *dev)
pci_write_config_byte (dev, 0x58, tmp);
}
+/*
+ * The AMD io apic can hang the box when an apic irq is masked.
+ * We check all revs >= B0 (yet not in the pre production!) as the bug
+ * is currently marked NoFix
+ *
+ * We have multiple reports of hangs with this chipset that went away with
+ * noapic specified. For the moment we assume its the errata. We may be wrong
+ * of course. However the advice is demonstrably good even if so..
+ */
+
+static void __devinit quirk_amd_ioapic(struct pci_dev *dev)
+{
+ u8 rev;
+
+ pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
+ if(rev >= 0x02)
+ {
+ printk(KERN_WARNING "I/O APIC: AMD Errata #22 may be present. In the event of instability try\n");
+ printk(KERN_WARNING " : booting with the \"noapic\" option.\n");
+ }
+}
+
+static void __init quirk_ioapic_rmw(struct pci_dev *dev)
+{
+ if (dev->devfn == 0 && dev->bus->number == 0)
+ sis_apic_bug = 1;
+}
+
+
#endif /* CONFIG_X86_IO_APIC */
@@ -412,28 +454,6 @@ static void __devinit quirk_cardbus_legacy(struct pci_dev *dev)
}
/*
- * The AMD io apic can hang the box when an apic irq is masked.
- * We check all revs >= B0 (yet not in the pre production!) as the bug
- * is currently marked NoFix
- *
- * We have multiple reports of hangs with this chipset that went away with
- * noapic specified. For the moment we assume its the errata. We may be wrong
- * of course. However the advice is demonstrably good even if so..
- */
-
-static void __devinit quirk_amd_ioapic(struct pci_dev *dev)
-{
- u8 rev;
-
- pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
- if(rev >= 0x02)
- {
- printk(KERN_WARNING "I/O APIC: AMD Errata #22 may be present. In the event of instability try\n");
- printk(KERN_WARNING " : booting with the \"noapic\" option.\n");
- }
-}
-
-/*
* Following the PCI ordering rules is optional on the AMD762. I'm not
* sure what the designers were smoking but let's not inhale...
*
@@ -477,6 +497,24 @@ static void __devinit quirk_transparent_bridge(struct pci_dev *dev)
}
/*
+ * Common misconfiguration of the MediaGX/Geode PCI master that will
+ * reduce PCI bandwidth from 70MB/s to 25MB/s. See the GXM/GXLV/GX1
+ * datasheets found at http://www.national.com/ds/GX for info on what
+ * these bits do. <christer@weinigel.se>
+ */
+
+static void __init quirk_mediagx_master(struct pci_dev *dev)
+{
+ u8 reg;
+ pci_read_config_byte(dev, 0x41, &reg);
+ if (reg & 2) {
+ reg &= ~2;
+ printk(KERN_INFO "PCI: Fixup for MediaGX/Geode Slave Disconnect Boundary (0x41=0x%02x)\n", reg);
+ pci_write_config_byte(dev, 0x41, reg);
+ }
+}
+
+/*
* The main table of quirks.
*/
@@ -491,6 +529,7 @@ static struct pci_fixup pci_fixups[] __devinitdata = {
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_isa_dma_hangs },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, quirk_isa_dma_hangs },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, quirk_isa_dma_hangs },
+ { PCI_FIXUP_FINAL, PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_1, quirk_isa_dma_hangs },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, quirk_triton },
@@ -521,6 +560,8 @@ static struct pci_fixup pci_fixups[] __devinitdata = {
#ifdef CONFIG_X86_IO_APIC
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic },
+ { PCI_FIXUP_FINAL, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic },
+ { PCI_FIXUP_FINAL, PCI_VENDOR_ID_SIS, PCI_ANY_ID, quirk_ioapic_rmw },
#endif
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi },
@@ -528,8 +569,8 @@ static struct pci_fixup pci_fixups[] __devinitdata = {
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irqpic },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_6, quirk_via_irqpic },
- { PCI_FIXUP_FINAL, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic },
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering },
+ { PCI_FIXUP_FINAL, PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_IGP, quirk_ati_exploding_mce },
/*
* i82380FB mobile docking controller: its PCI-to-PCI bridge
* is subtractive decoding (transparent), and does indicate this
@@ -538,6 +579,9 @@ static struct pci_fixup pci_fixups[] __devinitdata = {
*/
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82380FB, quirk_transparent_bridge },
+ { PCI_FIXUP_FINAL, PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master },
+
+
{ 0 }
};
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index a903dab30d7d..35879fa89885 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -164,7 +164,7 @@ static int __init pnp_init(void)
return bus_register(&pnp_bus_type);
}
-core_initcall(pnp_init);
+subsys_initcall(pnp_init);
EXPORT_SYMBOL(pnp_protocol_register);
EXPORT_SYMBOL(pnp_protocol_unregister);
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 0425e1583f1a..c11d807ba271 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -1167,7 +1167,7 @@ int __init isapnp_init(void)
return 0;
}
-subsys_initcall(isapnp_init);
+device_initcall(isapnp_init);
/* format is: noisapnp */
diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c
index c0cb0f9e2137..c5c4c8117d32 100644
--- a/drivers/pnp/system.c
+++ b/drivers/pnp/system.c
@@ -120,4 +120,4 @@ static int __init pnp_system_init(void)
return pnp_register_driver(&system_pnp_driver);
}
-core_initcall(pnp_system_init);
+subsys_initcall(pnp_system_init);
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index 0b1a4be156e7..72153cc82754 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -95,7 +95,7 @@ const unsigned short base_addrs[BPP_NO] = { 0x278, 0x378, 0x3bc };
/*
* These are for data access.
* Control lines accesses are hidden in set_bits() and get_bits().
- * The exeption is the probe procedure, which is system-dependent.
+ * The exception is the probe procedure, which is system-dependent.
*/
#define bpp_outb_p(data, base) outb_p((data), (base))
#define bpp_inb(base) inb(base)
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index ccc6132e05e5..faf4ddf39caf 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -189,6 +189,7 @@ MODULE_LICENSE("GPL");
#include <linux/smp.h>
#include <linux/reboot.h>
#include <linux/spinlock.h>
+#include <linux/interrupt.h>
#include <asm/errno.h>
#include <asm/io.h>
diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c
index 9a3529bc8e74..0f905a0abde9 100644
--- a/drivers/scsi/dmx3191d.c
+++ b/drivers/scsi/dmx3191d.c
@@ -31,6 +31,7 @@
#include <linux/signal.h>
#include <linux/stat.h>
#include <linux/version.h>
+#include <linux/interrupt.h>
#include <linux/delay.h>
#include "scsi.h"
diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c
index eccabd9ab3ed..701934d4268e 100644
--- a/drivers/scsi/dtc.c
+++ b/drivers/scsi/dtc.c
@@ -78,15 +78,16 @@
#include <linux/sched.h>
#include <linux/blk.h>
#include <linux/delay.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
#include <asm/io.h>
#include "scsi.h"
#include "hosts.h"
#include "dtc.h"
#define AUTOPROBE_IRQ
#include "NCR5380.h"
-#include <linux/stat.h>
-#include <linux/string.h>
-#include <linux/init.h>
#define DTC_PUBLIC_RELEASE 2
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index c98a81122d3c..63fd5b3d4bf6 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -464,6 +464,7 @@ MODULE_AUTHOR("Dario Ballabio");
#endif
+#include <linux/config.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -474,18 +475,18 @@ MODULE_AUTHOR("Dario Ballabio");
#include <asm/byteorder.h>
#include <linux/proc_fs.h>
#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include <asm/dma.h>
-#include <asm/irq.h>
-#include "eata.h"
+#include <linux/interrupt.h>
#include <linux/stat.h>
-#include <linux/config.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ctype.h>
#include <linux/spinlock.h>
#include <scsi/scsicam.h>
+#include "scsi.h"
+#include "hosts.h"
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include "eata.h"
#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
#error "Adjust your <asm/byteorder.h> defines"
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c
index 167725ef2839..5607cdd572c9 100644
--- a/drivers/scsi/eata_pio.c
+++ b/drivers/scsi/eata_pio.c
@@ -58,6 +58,7 @@
#include <linux/in.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
+#include <linux/interrupt.h>
#include <asm/io.h>
#include "eata_pio.h"
#include "eata_dma_proc.h"
@@ -805,13 +806,13 @@ static void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
u32 base, x;
while ((dev = pci_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, dev)) != NULL) {
- DBG(DBG_PROBE && DBG_PCI, printk("eata_pio: find_PCI, HBA at %s\n", dev->name));
+ DBG(DBG_PROBE && DBG_PCI, printk("eata_pio: find_PCI, HBA at %s\n", dev->dev.name));
if (pci_enable_device(dev))
continue;
pci_set_master(dev);
base = pci_resource_flags(dev, 0);
if (base & IORESOURCE_MEM) {
- printk("eata_pio: invalid base address of device %s\n", dev->name);
+ printk("eata_pio: invalid base address of device %s\n", dev->dev.name);
continue;
}
base = pci_resource_start(dev, 0);
diff --git a/drivers/scsi/i60uscsi.c b/drivers/scsi/i60uscsi.c
index 93314082560a..d2874dd72f69 100644
--- a/drivers/scsi/i60uscsi.c
+++ b/drivers/scsi/i60uscsi.c
@@ -566,10 +566,10 @@ int orc_reset_scsi_bus(ORC_HCS * pHCB)
ORC_WR(pHCB->HCS_Base + ORC_HCTRL, SCSIRST);
if (waitSCSIRSTdone(pHCB) == FALSE) {
spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
- return (SCSI_RESET_ERROR);
+ return FAILED;
} else {
spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
- return (SCSI_RESET_SUCCESS);
+ return SUCCESS;
}
}
@@ -581,7 +581,7 @@ int orc_reset_scsi_bus(ORC_HCS * pHCB)
Output : None.
Return : pSRB - Pointer to SCSI request block.
*****************************************************************************/
-int orc_device_reset(ORC_HCS * pHCB, Scsi_Cmnd *SCpnt, unsigned int target, unsigned int ResetFlags)
+int orc_device_reset(ORC_HCS * pHCB, Scsi_Cmnd *SCpnt, unsigned int target)
{ /* I need Host Control Block Information */
ORC_SCB *pScb;
ESCB *pVirEscb;
@@ -608,11 +608,11 @@ int orc_device_reset(ORC_HCS * pHCB, Scsi_Cmnd *SCpnt, unsigned int target, unsi
if (i == ORC_MAXQUEUE) {
printk("Unable to Reset - No SCB Found\n");
spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
- return (SCSI_RESET_NOT_RUNNING);
+ return FAILED;
}
if ((pScb = orc_alloc_scb(pHCB)) == NULL) {
spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
- return (SCSI_RESET_NOT_RUNNING);
+ return FAILED;
}
pScb->SCB_Opcode = ORC_BUSDEVRST;
pScb->SCB_Target = target;
@@ -626,12 +626,10 @@ int orc_device_reset(ORC_HCS * pHCB, Scsi_Cmnd *SCpnt, unsigned int target, unsi
pScb->SCB_SGLen = 0;
pVirEscb->SCB_Srb = 0;
- if (ResetFlags & SCSI_RESET_SYNCHRONOUS) {
- pVirEscb->SCB_Srb = SCpnt;
- }
+ pVirEscb->SCB_Srb = SCpnt;
orc_exec_scb(pHCB, pScb); /* Start execute SCB */
spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
- return SCSI_RESET_PENDING;
+ return SUCCESS;
}
@@ -838,21 +836,21 @@ int orc_abort_srb(ORC_HCS * hcsp, Scsi_Cmnd *SCpnt)
if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == SCpnt)) {
if (pVirScb->SCB_TagMsg == 0) {
spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
- return (SCSI_ABORT_BUSY);
+ return FAILED;
} else {
if (abort_SCB(hcsp, pVirScb)) {
pVirEscb->SCB_Srb = NULL;
spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
- return (SCSI_ABORT_SUCCESS);
+ return SUCCESS;
} else {
spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
- return (SCSI_ABORT_NOT_RUNNING);
+ return FAILED;
}
}
}
}
spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
- return (SCSI_ABORT_NOT_RUNNING);
+ return FAILED;
}
/***********************************************************************
diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
index 4a1f9be57dc8..c0f1d5675592 100644
--- a/drivers/scsi/in2000.c
+++ b/drivers/scsi/in2000.c
@@ -1885,14 +1885,14 @@ static u32 bios_tab[] in2000__INITDATA = {
0
};
-static const unsigned short base_tab[] in2000__INITDATA = {
+static unsigned short base_tab[] in2000__INITDATA = {
0x220,
0x200,
0x110,
0x100,
};
-static const int int_tab[] in2000__INITDATA = {
+static int int_tab[] in2000__INITDATA = {
15,
14,
11,
diff --git a/drivers/scsi/inia100.c b/drivers/scsi/inia100.c
index 553782833f48..80039be482dc 100644
--- a/drivers/scsi/inia100.c
+++ b/drivers/scsi/inia100.c
@@ -126,7 +126,7 @@ extern void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp);
extern void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp);
extern void orc_release_dma(ORC_HCS * hcsp, Scsi_Cmnd * cmnd);
extern void orc_interrupt(ORC_HCS * hcsp);
-extern int orc_device_reset(ORC_HCS * pHCB, Scsi_Cmnd *SCpnt, unsigned int target, unsigned int ResetFlags);
+extern int orc_device_reset(ORC_HCS * pHCB, Scsi_Cmnd *SCpnt, unsigned int target);
extern int orc_reset_scsi_bus(ORC_HCS * pHCB);
extern int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb);
extern int orc_abort_srb(ORC_HCS * hcsp, Scsi_Cmnd *SCpnt);
@@ -514,7 +514,7 @@ static void inia100BuildSCB(ORC_HCS * pHCB, ORC_SCB * pSCB, Scsi_Cmnd * SCpnt)
Output : None.
Return : pSRB - Pointer to SCSI request block.
*****************************************************************************/
-int inia100_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int inia100_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
{
register ORC_SCB *pSCB;
ORC_HCS *pHCB; /* Point to Host adapter control block */
@@ -541,7 +541,7 @@ int inia100_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
Output : None.
Return : pSRB - Pointer to SCSI request block.
*****************************************************************************/
-int inia100_abort(Scsi_Cmnd * SCpnt)
+static int inia100_abort(Scsi_Cmnd * SCpnt)
{
ORC_HCS *hcsp;
@@ -557,15 +557,25 @@ int inia100_abort(Scsi_Cmnd * SCpnt)
Output : None.
Return : pSRB - Pointer to SCSI request block.
*****************************************************************************/
-int inia100_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
+static int inia100_bus_reset(Scsi_Cmnd * SCpnt)
{ /* I need Host Control Block Information */
ORC_HCS *pHCB;
pHCB = (ORC_HCS *) SCpnt->host->hostdata;
+ return orc_reset_scsi_bus(pHCB);
+}
- if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET))
- return orc_reset_scsi_bus(pHCB);
- else
- return orc_device_reset(pHCB, SCpnt, SCpnt->target, reset_flags);
+/*****************************************************************************
+ Function name : inia100_device_reset
+ Description : Reset the device
+ Input : pHCB - Pointer to host adapter structure
+ Output : None.
+ Return : pSRB - Pointer to SCSI request block.
+*****************************************************************************/
+static int inia100_device_reset(Scsi_Cmnd * SCpnt)
+{ /* I need Host Control Block Information */
+ ORC_HCS *pHCB;
+ pHCB = (ORC_HCS *) SCpnt->host->hostdata;
+ return orc_device_reset(pHCB, SCpnt, SCpnt->target);
}
@@ -648,41 +658,6 @@ void inia100SCBPost(BYTE * pHcb, BYTE * pScb)
return;
}
-/*****************************************************************************
- Function name : inia100_biosparam
- Description : Return the "logical geometry"
- Input : pHCB - Pointer to host adapter structure
- Output : None.
- Return : pSRB - Pointer to SCSI request block.
-*****************************************************************************/
-int inia100_biosparam(struct scsi_device *sdev, struct block_device *bdev,
- sector_t capacity, int *info_array)
-{
- ORC_HCS *pHcb; /* Point to Host adapter control block */
- ORC_TCS *pTcb;
-
- pHcb = (ORC_HCS *) sdev->host->hostdata;
- pTcb = &pHcb->HCS_Tcs[sdev->id];
-
- if (pTcb->TCS_DrvHead) {
- info_array[0] = pTcb->TCS_DrvHead;
- info_array[1] = pTcb->TCS_DrvSector;
- info_array[2] = (unsigned long)capacity / pTcb->TCS_DrvHead / pTcb->TCS_DrvSector;
- } else {
- if (pTcb->TCS_DrvFlags & TCF_DRV_255_63) {
- info_array[0] = 255;
- info_array[1] = 63;
- info_array[2] = (unsigned long)capacity / 255 / 63;
- } else {
- info_array[0] = 64;
- info_array[1] = 32;
- info_array[2] = capacity >> 11;
- }
- }
- return 0;
-}
-
-
/*
* Interrupt handler (main routine of the driver)
*/
@@ -710,7 +685,7 @@ static void inia100_panic(char *msg)
/*
* Release ressources
*/
-int inia100_release(struct Scsi_Host *hreg)
+static int inia100_release(struct Scsi_Host *hreg)
{
ORC_HCS *pHCB = (ORC_HCS *)hreg->hostdata;
diff --git a/drivers/scsi/inia100.h b/drivers/scsi/inia100.h
index fe1d752db023..0fe77ff6097e 100644
--- a/drivers/scsi/inia100.h
+++ b/drivers/scsi/inia100.h
@@ -75,14 +75,12 @@
#include <linux/types.h>
#include <linux/pci.h>
-extern int inia100_detect(Scsi_Host_Template *);
-extern int inia100_release(struct Scsi_Host *);
-extern int inia100_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
-extern int inia100_abort(Scsi_Cmnd *);
-extern int inia100_reset(Scsi_Cmnd *, unsigned int);
-
-extern int inia100_biosparam(struct scsi_device *, struct block_device *,
- sector_t, int *);
+static int inia100_detect(Scsi_Host_Template *);
+static int inia100_release(struct Scsi_Host *);
+static int inia100_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
+static int inia100_abort(Scsi_Cmnd *);
+static int inia100_device_reset(Scsi_Cmnd *);
+static int inia100_bus_reset(Scsi_Cmnd *);
#define inia100_REVID "Initio INI-A100U2W SCSI device driver; Revision: 1.02d"
@@ -92,8 +90,9 @@ extern int inia100_biosparam(struct scsi_device *, struct block_device *,
detect: inia100_detect, \
release: inia100_release, \
queuecommand: inia100_queue, \
- abort: inia100_abort, \
- reset: inia100_reset, \
+ eh_abort_handler:inia100_abort, \
+ eh_bus_reset_handler: inia100_bus_reset, \
+ eh_device_reset_handler:inia100_device_reset, \
can_queue: 1, \
this_id: 1, \
sg_tablesize: SG_ALL, \
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 04820584f42f..8bafa2164c6c 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -856,7 +856,7 @@ ips_detect(Scsi_Host_Template *SHT) {
ips_name, ips_next_controller, mem_addr, mem_len);
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
- if (check_mem_region(mem_addr, mem_len)) {
+ if (!request_mem_region(mem_addr, mem_len, "ips")) {
/* Couldn't allocate io space */
printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n",
ips_name, ips_next_controller, io_addr, io_len);
@@ -866,7 +866,6 @@ ips_detect(Scsi_Host_Template *SHT) {
continue;
}
- request_mem_region(mem_addr, mem_len, "ips");
#endif
base = mem_addr & PAGE_MASK;
@@ -884,7 +883,7 @@ ips_detect(Scsi_Host_Template *SHT) {
DEBUG_VAR(1, "(%s%d) detect, IO region %x, size: %d",
ips_name, ips_next_controller, io_addr, io_len);
- if (check_region(io_addr, io_len)) {
+ if (!request_region(io_addr, io_len, "ips")) {
/* Couldn't allocate io space */
printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n",
ips_name, ips_next_controller, io_addr, io_len);
@@ -894,7 +893,6 @@ ips_detect(Scsi_Host_Template *SHT) {
continue;
}
- request_region(io_addr, io_len, "ips");
}
/* get planer status */
@@ -7329,12 +7327,11 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
uint32_t base;
uint32_t offs;
- if (check_mem_region(mem_addr, mem_len)) {
+ if (!request_mem_region(mem_addr, mem_len, "ips")) {
printk(KERN_WARNING "Couldn't allocate IO Memory space %x len %d.\n", mem_addr, mem_len);
return -1;
}
- request_mem_region(mem_addr, mem_len, "ips");
base = mem_addr & PAGE_MASK;
offs = mem_addr - base;
ioremap_ptr = ioremap(base, PAGE_SIZE);
@@ -7346,11 +7343,10 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
/* setup I/O mapped area (if applicable) */
if (io_addr) {
- if (check_region(io_addr, io_len)) {
+ if (!request_region(io_addr, io_len, "ips")) {
printk(KERN_WARNING "Couldn't allocate IO space %x len %d.\n", io_addr, io_len);
return -1;
}
- request_region(io_addr, io_len, "ips");
}
/* get the revision ID */
diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c
index 34ae7eb89440..91c3f884441f 100644
--- a/drivers/scsi/pas16.c
+++ b/drivers/scsi/pas16.c
@@ -119,14 +119,16 @@
#include <asm/io.h>
#include <linux/blk.h>
#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/stat.h>
+#include <linux/init.h>
+
#include "scsi.h"
#include "hosts.h"
#include "pas16.h"
#define AUTOPROBE_IRQ
#include "NCR5380.h"
-#include <linux/stat.h>
-#include <linux/init.h>
static int pas_maxi = 0;
static int pas_wmaxi = 0;
diff --git a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
index 48aca580b34e..62b4a4ca6c7e 100644
--- a/drivers/scsi/scsi.h
+++ b/drivers/scsi/scsi.h
@@ -496,9 +496,11 @@ extern void scsi_proc_host_add(struct Scsi_Host *);
extern void scsi_proc_host_rm(struct Scsi_Host *);
extern struct proc_dir_entry *proc_scsi;
+extern void proc_print_scsidevice(Scsi_Device * sdev, char *buffer, int *size, int len);
#else
-static inline int scsi_init_procfs(void) { return 0; };
-static inline void scsi_exit_procfs(void) { };
+static inline int scsi_init_procfs(void) { return 0; }
+static inline void scsi_exit_procfs(void) { ; }
+static inline void proc_print_scsidevice(Scsi_Device * sdev, char *buffer, int *size, int len) { ; }
static inline void scsi_proc_host_add(struct Scsi_Host *);
static inline void scsi_proc_host_rm(struct Scsi_Host *);
diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c
index 26de433f36e1..cb8b7b78afe7 100644
--- a/drivers/scsi/t128.c
+++ b/drivers/scsi/t128.c
@@ -111,15 +111,17 @@
#include <linux/sched.h>
#include <asm/io.h>
#include <linux/blk.h>
+#include <linux/interrupt.h>
+#include <linux/stat.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+
#include "scsi.h"
#include "hosts.h"
#include "t128.h"
#define AUTOPROBE_IRQ
#include "NCR5380.h"
-#include <linux/stat.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/delay.h>
static struct override {
unsigned long address;
@@ -143,7 +145,7 @@ static struct base {
#define NO_BASES (sizeof (bases) / sizeof (struct base))
-static const struct signature {
+static struct signature {
const char *string;
int offset;
} signatures[] __initdata = {
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
index f081216dd914..c40297cc8ec0 100644
--- a/drivers/scsi/ultrastor.c
+++ b/drivers/scsi/ultrastor.c
@@ -1047,7 +1047,7 @@ static void ultrastor_interrupt(int irq, void *dev_id, struct pt_regs *regs)
printk("Ux4F interrupt: bad MSCP address %x\n", (unsigned int) mscp);
/* A command has been lost. Reset and report an error
for all commands. */
- ultrastor_reset(NULL, 0);
+ ultrastor_host_reset(dev_id);
return;
}
#endif
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
new file mode 100644
index 000000000000..7d7eb391df40
--- /dev/null
+++ b/drivers/video/68328fb.c
@@ -0,0 +1,986 @@
+/*
+ * linux/arch/m68knommu/console/68328fb.c -- Low level implementation of the
+ * mc68328 LCD frame buffer device
+ *
+ * Copyright (C) 1998,1999 Kenneth Albanowski <kjahds@kjahds.com>,
+ * The Silver Hammer Group, Ltd.
+ *
+ *
+ * This file is based on the Amiga CyberVision frame buffer device (Cyberfb.c):
+ *
+ * Copyright (C) 1996 Martin Apel
+ * Geert Uytterhoeven
+ *
+ *
+ * This file is based on the Amiga frame buffer device (amifb.c):
+ *
+ * Copyright (C) 1995 Geert Uytterhoeven
+ *
+ *
+ * History:
+ * - 17 Feb 98: Original version by Kenneth Albanowski <kjahds@kjahds.com>
+ *
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/config.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <linux/fb.h>
+#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+
+
+#define arraysize(x) (sizeof(x)/sizeof(*(x)))
+
+struct mc68328_fb_par {
+ int xres;
+ int yres;
+ int bpp;
+};
+
+static struct mc68328_fb_par current_par;
+
+static int current_par_valid = 0;
+static int currcon = 0;
+
+static struct display disp[MAX_NR_CONSOLES];
+static struct fb_info fb_info;
+
+static int node; /* node of the /dev/fb?current file */
+
+
+ /*
+ * Switch for Chipset Independency
+ */
+
+static struct fb_hwswitch {
+
+ /* Initialisation */
+
+ int (*init)(void);
+
+ /* Display Control */
+
+ int (*encode_fix)(struct fb_fix_screeninfo *fix, struct mc68328_fb_par *par);
+ int (*decode_var)(struct fb_var_screeninfo *var, struct mc68328_fb_par *par);
+ int (*encode_var)(struct fb_var_screeninfo *var, struct mc68328_fb_par *par);
+ int (*getcolreg)(u_int regno, u_int *red, u_int *green, u_int *blue,
+ u_int *transp);
+ int (*setcolreg)(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp);
+ void (*blank)(int blank);
+} *fbhw;
+
+
+ /*
+ * Frame Buffer Name
+ */
+
+static char mc68328_fb_name[16] = "mc68328";
+
+
+ /*
+ * mc68328vision Graphics Board
+ */
+
+#define CYBER8_WIDTH 1152
+#define CYBER8_HEIGHT 886
+#define CYBER8_PIXCLOCK 12500 /* ++Geert: Just a guess */
+
+#define CYBER16_WIDTH 800
+#define CYBER16_HEIGHT 600
+#define CYBER16_PIXCLOCK 25000 /* ++Geert: Just a guess */
+
+#define PALM_WIDTH 160
+#define PALM_HEIGHT 160
+
+
+/*static int mc68328Key = 0;
+static u_char mc68328_colour_table [256][4];*/
+static unsigned long mc68328Mem;
+static unsigned long mc68328Size;
+
+
+ /*
+ * Predefined Video Mode Names
+ */
+
+static char *mc68328_fb_modenames[] = {
+
+ /*
+ * Autodetect (Default) Video Mode
+ */
+
+ "default",
+
+ /*
+ * Predefined Video Modes
+ */
+
+ "Palm", /* Palm Pilot devices, 1.0 and higher */
+ "Palm Grey", /* Palm Pilot devices, 1.0 and higher */
+
+ /*
+ * Dummy Video Modes
+ */
+
+ "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
+ "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
+ "dummy", "dummy", "dummy", "dummy",
+
+ /*
+ * User Defined Video Modes
+ *
+ * This doesn't work yet!!
+ */
+
+ "user0", "user1", "user2", "user3", "user4", "user5", "user6", "user7"
+};
+
+
+ /*
+ * Predefined Video Mode Definitions
+ */
+
+static struct fb_var_screeninfo mc68328_fb_predefined[] = {
+
+ /*
+ * Autodetect (Default) Video Mode
+ */
+
+ { 0, },
+
+ /*
+ * Predefined Video Modes
+ */
+
+ {
+ /* Palm */
+ PALM_WIDTH, PALM_HEIGHT, PALM_WIDTH, PALM_HEIGHT,
+ 0, 0,
+ 1, -1,
+ {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 0, 0},
+ 0, 0,
+ -1, -1, /* phys height, width */
+ FB_ACCEL_NONE,
+ 0, 0, 0, 0, 0, 0, 0, /* timing */
+ 0, /* sync */
+ FB_VMODE_NONINTERLACED
+ },
+ {
+ /* Palm Grey */
+ PALM_WIDTH, PALM_HEIGHT, PALM_WIDTH, PALM_HEIGHT,
+ 0, 0,
+ 2, -1,
+ {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0},
+ 0, 0,
+ -1, -1, /* phys height, width */
+ FB_ACCEL_NONE,
+ 0, 0, 0, 0, 0, 0, 0, /* timing */
+ 0, /* sync */
+ FB_VMODE_NONINTERLACED
+ },
+
+ /*
+ * Dummy Video Modes
+ */
+
+ { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, },
+ { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, },
+ { 0, }, { 0, },
+
+ /*
+ * User Defined Video Modes
+ */
+
+ { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }
+};
+
+
+#define NUM_TOTAL_MODES arraysize(mc68328_fb_predefined)
+#define NUM_PREDEF_MODES (3)
+
+
+static int mc68328fb_inverse = 0;
+static int mc68328fb_mode = 0;
+static int mc68328fbCursorMode = 0;
+
+
+ /*
+ * Some default modes
+ */
+
+#define PALM_DEFMODE (1)
+#define CYBER16_DEFMODE (2)
+
+
+ /*
+ * Interface used by the world
+ */
+
+static int mc68328_fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
+static int mc68328_fb_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int mc68328_fb_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int mc68328_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int mc68328_fb_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int mc68328_fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info);
+
+
+ /*
+ * Interface to the low level console driver
+ */
+
+int mc68328_fb_init(void);
+static int mc68328fb_switch(int con, struct fb_info *info);
+static int mc68328fb_updatevar(int con);
+static void mc68328fb_blank(int blank);
+
+
+ /*
+ * Accelerated Functions used by the low level console driver
+ */
+
+void mc68328_WaitQueue(u_short fifo);
+void mc68328_WaitBlit(void);
+void mc68328_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty,
+ u_short width, u_short height, u_short mode);
+void mc68328_RectFill(u_short x, u_short y, u_short width, u_short height,
+ u_short mode, u_short color);
+void mc68328_MoveCursor(u_short x, u_short y);
+
+
+ /*
+ * Hardware Specific Routines
+ */
+
+static int mc68328_init(void);
+static int mc68328_encode_fix(struct fb_fix_screeninfo *fix,
+ struct mc68328_fb_par *par);
+static int mc68328_decode_var(struct fb_var_screeninfo *var,
+ struct mc68328_fb_par *par);
+static int mc68328_encode_var(struct fb_var_screeninfo *var,
+ struct mc68328_fb_par *par);
+static int mc68328_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+ u_int *transp);
+static int mc68328_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp);
+static void mc68328_blank(int blank);
+
+
+ /*
+ * Internal routines
+ */
+
+static void mc68328_fb_get_par(struct mc68328_fb_par *par);
+static void mc68328_fb_set_par(struct mc68328_fb_par *par);
+static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
+static struct fb_cmap *get_default_colormap(int bpp);
+static void memcpy_fs(int fsfromto, void *to, void *from, int len);
+static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto);
+static int alloc_cmap(struct fb_cmap *cmap, int len, int transp);
+static void mc68328_fb_set_disp(int con, struct fb_info *info);
+static int get_video_mode(const char *name);
+
+
+/* -------------------- Hardware specific routines -------------------------- */
+
+
+ /*
+ * Initialization
+ *
+ * Set the default video mode for this chipset. If a video mode was
+ * specified on the command line, it will override the default mode.
+ */
+
+static int mc68328_init(void)
+{
+ /*int i;
+ char size;
+ volatile u_long *CursorBase;
+ unsigned long board_addr;
+ struct ConfigDev *cd;*/
+
+ if (mc68328fb_mode == -1)
+ mc68328fb_mode = PALM_DEFMODE;
+
+ mc68328Mem = (*(volatile unsigned long*)0xFFFFFA00);
+ /*kernel_map (board_addr + 0x01400000, 0x00400000,*/
+ mc68328Size = 160*160/8;
+
+ return (0);
+}
+
+
+ /*
+ * This function should fill in the `fix' structure based on the
+ * values in the `par' structure.
+ */
+
+static int mc68328_encode_fix(struct fb_fix_screeninfo *fix,
+ struct mc68328_fb_par *par)
+{
+ int i;
+
+ strcpy(fix->id, mc68328_fb_name);
+ fix->smem_start = mc68328Mem;
+ fix->smem_len = mc68328Size;
+
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->type_aux = 0;
+ if (par->bpp == 1)
+ fix->visual = FB_VISUAL_MONO01;
+ else
+ fix->visual = FB_VISUAL_DIRECTCOLOR;
+
+ fix->xpanstep = 0;
+ fix->ypanstep = 0;
+ fix->ywrapstep = 0;
+
+ for (i = 0; i < arraysize(fix->reserved); i++)
+ fix->reserved[i] = 0;
+
+ fix->accel = FB_ACCEL_NONE;
+
+ return(0);
+}
+
+
+ /*
+ * Get the video params out of `var'. If a value doesn't fit, round
+ * it up, if it's too big, return -EINVAL.
+ */
+
+static int mc68328_decode_var(struct fb_var_screeninfo *var,
+ struct mc68328_fb_par *par)
+{
+ par->xres = PALM_WIDTH;
+ par->yres = PALM_HEIGHT;
+ par->bpp = 1;
+ return(0);
+}
+
+
+ /*
+ * Fill the `var' structure based on the values in `par' and maybe
+ * other values read out of the hardware.
+ */
+
+static int mc68328_encode_var(struct fb_var_screeninfo *var,
+ struct mc68328_fb_par *par)
+{
+ int i;
+
+ var->xres = par->xres;
+ var->yres = par->yres;
+ var->xres_virtual = par->xres;
+ var->yres_virtual = par->yres;
+ var->xoffset = 0;
+ var->yoffset = 0;
+
+ var->bits_per_pixel = par->bpp;
+ var->grayscale = -1;
+
+ var->red.offset = 0;
+ var->red.length = par->bpp;
+ var->red.msb_right = 0;
+ var->blue = var->green = var->red;
+
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ var->transp.msb_right = 0;
+
+ var->nonstd = 0;
+ var->activate = 0;
+
+ var->height = -1;
+ var->width = -1;
+ var->vmode = FB_VMODE_NONINTERLACED;
+
+ /* Dummy values */
+
+ var->pixclock = 0;
+ var->sync = 0;
+ var->left_margin = 0;
+ var->right_margin = 0;
+ var->upper_margin = 0;
+ var->lower_margin = 0;
+ var->hsync_len = 0;
+ var->vsync_len = 0;
+
+ for (i = 0; i < arraysize(var->reserved); i++)
+ var->reserved[i] = 0;
+
+ return(0);
+}
+
+
+ /*
+ * Set a single color register. The values supplied are already
+ * rounded down to the hardware's capabilities (according to the
+ * entries in the var structure). Return != 0 for invalid regno.
+ */
+
+static int mc68328_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp)
+{
+ return 1;
+#if 0
+if (regno > 255)
+ return (1);
+
+*(mc68328Regs + 0x3c8) = (char)regno;
+mc68328_colour_table [regno][0] = red & 0xff;
+mc68328_colour_table [regno][1] = green & 0xff;
+mc68328_colour_table [regno][2] = blue & 0xff;
+mc68328_colour_table [regno][3] = transp;
+
+*(mc68328Regs + 0x3c9) = (red & 0xff) >> 2;
+*(mc68328Regs + 0x3c9) = (green & 0xff) >> 2;
+*(mc68328Regs + 0x3c9) = (blue & 0xff) >> 2;
+
+return (0);
+#endif
+}
+
+
+ /*
+ * Read a single color register and split it into
+ * colors/transparent. Return != 0 for invalid regno.
+ */
+
+static int mc68328_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+ u_int *transp)
+{
+ return 1;
+#if 0
+if (regno >= 256)
+ return (1);
+*red = mc68328_colour_table [regno][0];
+*green = mc68328_colour_table [regno][1];
+*blue = mc68328_colour_table [regno][2];
+*transp = mc68328_colour_table [regno][3];
+return (0);
+#endif
+}
+
+
+ /*
+ * (Un)Blank the screen
+ */
+
+void mc68328_blank(int blank)
+{
+#if 0
+ if (blank)
+ (*(volatile unsigned char*)0xFFFFFA27) &= ~128;
+ else
+ (*(volatile unsigned char*)0xFFFFFA27) |= 128;
+#endif
+}
+
+
+/**************************************************************
+ * We are waiting for "fifo" FIFO-slots empty
+ */
+void mc68328_WaitQueue (u_short fifo)
+{
+}
+
+/**************************************************************
+ * We are waiting for Hardware (Graphics Engine) not busy
+ */
+void mc68328_WaitBlit (void)
+{
+}
+
+/**************************************************************
+ * BitBLT - Through the Plane
+ */
+void mc68328_BitBLT (u_short curx, u_short cury, u_short destx, u_short desty,
+ u_short width, u_short height, u_short mode)
+{
+#if 0
+u_short blitcmd = S3_BITBLT;
+
+/* Set drawing direction */
+/* -Y, X maj, -X (default) */
+if (curx > destx)
+ blitcmd |= 0x0020; /* Drawing direction +X */
+else
+ {
+ curx += (width - 1);
+ destx += (width - 1);
+ }
+
+if (cury > desty)
+ blitcmd |= 0x0080; /* Drawing direction +Y */
+else
+ {
+ cury += (height - 1);
+ desty += (height - 1);
+ }
+
+mc68328_WaitQueue (0x8000);
+
+*((u_short volatile *)(mc68328Regs + S3_PIXEL_CNTL)) = 0xa000;
+*((u_short volatile *)(mc68328Regs + S3_FRGD_MIX)) = (0x0060 | mode);
+
+*((u_short volatile *)(mc68328Regs + S3_CUR_X)) = curx;
+*((u_short volatile *)(mc68328Regs + S3_CUR_Y)) = cury;
+
+*((u_short volatile *)(mc68328Regs + S3_DESTX_DIASTP)) = destx;
+*((u_short volatile *)(mc68328Regs + S3_DESTY_AXSTP)) = desty;
+
+*((u_short volatile *)(mc68328Regs + S3_MIN_AXIS_PCNT)) = height - 1;
+*((u_short volatile *)(mc68328Regs + S3_MAJ_AXIS_PCNT)) = width - 1;
+
+*((u_short volatile *)(mc68328Regs + S3_CMD)) = blitcmd;
+#endif
+}
+
+/**************************************************************
+ * Rectangle Fill Solid
+ */
+void mc68328_RectFill (u_short x, u_short y, u_short width, u_short height,
+ u_short mode, u_short color)
+{
+#if 0
+u_short blitcmd = S3_FILLEDRECT;
+
+mc68328_WaitQueue (0x8000);
+
+*((u_short volatile *)(mc68328Regs + S3_PIXEL_CNTL)) = 0xa000;
+*((u_short volatile *)(mc68328Regs + S3_FRGD_MIX)) = (0x0020 | mode);
+
+*((u_short volatile *)(mc68328Regs + S3_MULT_MISC)) = 0xe000;
+*((u_short volatile *)(mc68328Regs + S3_FRGD_COLOR)) = color;
+
+*((u_short volatile *)(mc68328Regs + S3_CUR_X)) = x;
+*((u_short volatile *)(mc68328Regs + S3_CUR_Y)) = y;
+
+*((u_short volatile *)(mc68328Regs + S3_MIN_AXIS_PCNT)) = height - 1;
+*((u_short volatile *)(mc68328Regs + S3_MAJ_AXIS_PCNT)) = width - 1;
+
+*((u_short volatile *)(mc68328Regs + S3_CMD)) = blitcmd;
+#endif
+}
+
+
+/**************************************************************
+ * Move cursor to x, y
+ */
+void mc68328_MoveCursor (u_short x, u_short y)
+{
+ (*(volatile unsigned short*)0xFFFFFA18) = (mc68328fbCursorMode << 14) | x;
+ (*(volatile unsigned short*)0xFFFFFA1A) = y;
+#if 0
+*(mc68328Regs + S3_CRTC_ADR) = 0x39;
+*(mc68328Regs + S3_CRTC_DATA) = 0xa0;
+
+*(mc68328Regs + S3_CRTC_ADR) = S3_HWGC_ORGX_H;
+*(mc68328Regs + S3_CRTC_DATA) = (char)((x & 0x0700) >> 8);
+*(mc68328Regs + S3_CRTC_ADR) = S3_HWGC_ORGX_L;
+*(mc68328Regs + S3_CRTC_DATA) = (char)(x & 0x00ff);
+
+*(mc68328Regs + S3_CRTC_ADR) = S3_HWGC_ORGY_H;
+*(mc68328Regs + S3_CRTC_DATA) = (char)((y & 0x0700) >> 8);
+*(mc68328Regs + S3_CRTC_ADR) = S3_HWGC_ORGY_L;
+*(mc68328Regs + S3_CRTC_DATA) = (char)(y & 0x00ff);
+#endif
+}
+
+
+/* -------------------- Interfaces to hardware functions -------------------- */
+
+
+static struct fb_hwswitch mc68328_switch = {
+ mc68328_init, mc68328_encode_fix, mc68328_decode_var, mc68328_encode_var,
+ mc68328_getcolreg, mc68328_setcolreg, mc68328_blank
+};
+
+
+/* -------------------- Generic routines ------------------------------------ */
+
+
+ /*
+ * Fill the hardware's `par' structure.
+ */
+
+static void mc68328_fb_get_par(struct mc68328_fb_par *par)
+{
+ if (current_par_valid)
+ *par = current_par;
+ else
+ fbhw->decode_var(&mc68328_fb_predefined[mc68328fb_mode], par);
+}
+
+
+static void mc68328_fb_set_par(struct mc68328_fb_par *par)
+{
+ current_par = *par;
+ current_par_valid = 1;
+}
+
+
+static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
+{
+ int err, activate;
+ struct mc68328_fb_par par;
+
+ if ((err = fbhw->decode_var(var, &par)))
+ return(err);
+ activate = var->activate;
+ if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
+ mc68328_fb_set_par(&par);
+ fbhw->encode_var(var, &par);
+ var->activate = activate;
+ return(0);
+}
+
+
+ /*
+ * Default Colormaps
+ */
+
+static u_short red16[] =
+ { 0xc000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0x0000,
+ 0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff};
+static u_short green16[] =
+ { 0xc000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0x0000,
+ 0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff};
+static u_short blue16[] =
+ { 0xc000, 0x0000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0x0000,
+ 0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff};
+
+
+static struct fb_cmap default_16_colors =
+ { 0, 16, red16, green16, blue16, NULL };
+
+
+static struct fb_cmap *get_default_colormap(int bpp)
+{
+ return(&default_16_colors);
+}
+
+
+#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7fff-(val))>>16)
+#define CNVT_FROMHW(val,width) (((width) ? ((((val)<<16)-(val)) / \
+ ((1<<(width))-1)) : 0))
+
+
+static void memcpy_fs(int fsfromto, void *to, void *from, int len)
+{
+ switch (fsfromto) {
+ case 0:
+ memcpy(to, from, len);
+ return;
+ case 1:
+ copy_from_user(to, from, len);
+ return;
+ case 2:
+ copy_to_user(to, from, len);
+ return;
+ }
+}
+
+
+static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
+{
+ int size;
+ int tooff = 0, fromoff = 0;
+
+ if (to->start > from->start)
+ fromoff = to->start-from->start;
+ else
+ tooff = from->start-to->start;
+ size = to->len-tooff;
+ if (size > from->len-fromoff)
+ size = from->len-fromoff;
+ if (size < 0)
+ return;
+ size *= sizeof(u_short);
+ memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
+ memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
+ memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
+ if (from->transp && to->transp)
+ memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size);
+}
+
+
+static int alloc_cmap(struct fb_cmap *cmap, int len, int transp)
+{
+ int size = len*sizeof(u_short);
+
+ if (cmap->len != len) {
+ if (cmap->red)
+ kfree(cmap->red);
+ if (cmap->green)
+ kfree(cmap->green);
+ if (cmap->blue)
+ kfree(cmap->blue);
+ if (cmap->transp)
+ kfree(cmap->transp);
+ cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
+ cmap->len = 0;
+ if (!len)
+ return(0);
+ if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
+ return(-1);
+ if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
+ return(-1);
+ if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
+ return(-1);
+ if (transp) {
+ if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
+ return(-1);
+ } else
+ cmap->transp = NULL;
+ }
+ cmap->start = 0;
+ cmap->len = len;
+ copy_cmap(get_default_colormap(len), cmap, 0);
+ return(0);
+}
+
+
+ /*
+ * Get the Fixed Part of the Display
+ */
+
+static int mc68328_fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
+{
+ struct mc68328_fb_par par;
+ int error = 0;
+
+ if (con == -1)
+ mc68328_fb_get_par(&par);
+ else
+ error = fbhw->decode_var(&disp[con].var, &par);
+ return(error ? error : fbhw->encode_fix(fix, &par));
+}
+
+
+ /*
+ * Get the User Defined Part of the Display
+ */
+
+static int mc68328_fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+ struct mc68328_fb_par par;
+ int error = 0;
+
+ if (con == -1) {
+ mc68328_fb_get_par(&par);
+ error = fbhw->encode_var(var, &par);
+ } else
+ *var = disp[con].var;
+ return(error);
+}
+
+
+static void mc68328_fb_set_disp(int con, struct fb_info *info)
+{
+ struct fb_fix_screeninfo fix;
+
+ mc68328_fb_get_fix(&fix, con, info);
+ if (con == -1)
+ con = 0;
+ info->screen_base = (u_char *)fix.smem_start;
+ disp[con].visual = fix.visual;
+ disp[con].type = fix.type;
+ disp[con].type_aux = fix.type_aux;
+ disp[con].ypanstep = fix.ypanstep;
+ disp[con].ywrapstep = fix.ywrapstep;
+ disp[con].can_soft_blank = 1;
+ disp[con].inverse = mc68328fb_inverse;
+}
+
+
+ /*
+ * Set the User Defined Part of the Display
+ */
+
+static int mc68328_fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+ int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+
+ if ((err = do_fb_set_var(var, con == currcon)))
+ return(err);
+ if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+ oldxres = disp[con].var.xres;
+ oldyres = disp[con].var.yres;
+ oldvxres = disp[con].var.xres_virtual;
+ oldvyres = disp[con].var.yres_virtual;
+ oldbpp = disp[con].var.bits_per_pixel;
+ disp[con].var = *var;
+ if (oldxres != var->xres || oldyres != var->yres ||
+ oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
+ oldbpp != var->bits_per_pixel) {
+ mc68328_fb_set_disp(con, info);
+ (*fb_info.changevar)(con);
+ alloc_cmap(&disp[con].cmap, 0, 0);
+ do_install_cmap(con, info);
+ }
+ }
+ var->activate = 0;
+ return(0);
+}
+
+
+ /*
+ * Get the Colormap
+ */
+
+static int mc68328_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
+{
+ if (con == currcon) /* current console? */
+ return(fb_get_cmap(cmap, kspc, fbhw->getcolreg, info));
+ else if (disp[con].cmap.len) /* non default colormap? */
+ copy_cmap(&disp[con].cmap, cmap, kspc ? 0 : 2);
+ else
+ copy_cmap(get_default_colormap(disp[con].var.bits_per_pixel), cmap,
+ kspc ? 0 : 2);
+ return(0);
+}
+
+
+
+ /*
+ * Pan or Wrap the Display
+ *
+ * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ */
+
+static int mc68328_fb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+ return(-EINVAL);
+}
+
+
+ /*
+ * mc68328 Frame Buffer Specific ioctls
+ */
+
+static int mc68328_fb_ioctl(struct inode *inode, struct file *file,
+ u_int cmd, u_long arg, int con, struct fb_info *info)
+{
+ return(-EINVAL);
+}
+
+
+static struct fb_ops mc68328_fb_ops = {
+ owner: THIS_MODULE,
+ fb_get_fix: mc68328_fb_get_fix,
+ fb_get_var: mc68328_fb_get_var,
+ fb_set_var: mc68328_fb_set_var,
+ fb_get_cmap: mc68328_fb_get_cmap,
+ fb_set_cmap: gen_set_cmap,
+ fb_pan_display: mc68328_fb_pan_display,
+ fb_ioctl: mc68328_fb_ioctl,
+};
+
+
+ /*
+ * Initialization
+ */
+
+int __init mc68328_fb_init(void)
+{
+ int err;
+ struct mc68328_fb_par par;
+
+ fbhw = &mc68328_switch;
+
+ err = register_framebuffer(&fb_info);
+ if (err < 0)
+ panic("Cannot register frame buffer\n");
+
+ fbhw->init();
+ fbhw->decode_var(&mc68328_fb_predefined[mc68328fb_mode], &par);
+ fbhw->encode_var(&mc68328_fb_predefined[0], &par);
+
+ strcpy(fb_info.modename, mc68328_fb_name);
+ fb_info.disp = disp;
+ fb_info.switch_con = &mc68328fb_switch;
+ fb_info.updatevar = &mc68328fb_updatevar;
+
+ do_fb_set_var(&mc68328_fb_predefined[0], 1);
+ mc68328_fb_get_var(&disp[0].var, -1, &fb_info);
+ mc68328_fb_set_disp(-1, &fb_info);
+ do_install_cmap(0, &fb_info);
+ return(0);
+}
+
+
+static int mc68328fb_switch(int con, struct fb_info *info)
+{
+ /* Do we have to save the colormap? */
+ if (disp[currcon].cmap.len)
+ fb_get_cmap(&disp[currcon].cmap, 1, &disp[currcon].var, info);
+
+ do_fb_set_var(&disp[con].var, 1);
+ currcon = con;
+ /* Install new colormap */
+ do_install_cmap(con, info);
+ return(0);
+}
+
+
+ /*
+ * Update the `var' structure (called by fbcon.c)
+ *
+ * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
+ * Since it's called by a kernel driver, no range checking is done.
+ */
+
+static int mc68328fb_updatevar(int con)
+{
+ return(0);
+}
+
+
+ /*
+ * Blank the display.
+ */
+
+static void mc68328fb_blank(int blank)
+{
+ fbhw->blank(blank);
+}
+
+
+ /*
+ * Get a Video Mode
+ */
+
+static int get_video_mode(const char *name)
+{
+ int i;
+
+ for (i = 1; i < NUM_PREDEF_MODES; i++)
+ if (!strcmp(name, mc68328_fb_modenames[i]))
+ return(i);
+ return(0);
+}
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index e96f540178b7..a80ecae5e07f 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -22,6 +22,7 @@
#include <linux/selection.h>
#include <linux/ioport.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <asm/io.h>
@@ -81,22 +82,33 @@ struct vga16fb_par {
/* --------------------------------------------------------------------- */
static struct fb_var_screeninfo vga16fb_defined = {
- 640,480,640,480,/* W,H, W, H (virtual) load xres,xres_virtual*/
- 0,0, /* virtual -> visible no offset */
- 4, /* depth -> load bits_per_pixel */
- 0, /* greyscale ? */
- {0,0,0}, /* R */
- {0,0,0}, /* G */
- {0,0,0}, /* B */
- {0,0,0}, /* transparency */
- 0, /* standard pixel format */
- FB_ACTIVATE_NOW,
- -1,-1,
- 0,
- 39721, 48, 16, 39, 8,
- 96, 2, 0, /* No sync info */
- FB_VMODE_NONINTERLACED,
- {0,0,0,0,0,0}
+ .xres = 640,
+ .yres = 480,
+ .xres_virtual = 640,
+ .yres_virtual = 480,
+ .bits_per_pixel = 4,
+ .activate = FB_ACTIVATE_NOW,
+ .height = -1,
+ .width = -1,
+ .pixclock = 39721,
+ .left_margin = 48,
+ .right_margin = 16,
+ .upper_margin = 39,
+ .lower_margin = 8,
+ .hsync_len = 96,
+ .vsync_len = 2,
+ .vmode = FB_VMODE_NONINTERLACED,
+};
+
+static struct fb_fix_screeninfo vga16fb_fix __initdata = {
+ .id = "VGA16 VGA",
+ .smem_start = VGA_FB_PHYS,
+ .smem_len = VGA_FB_PHYS_LEN,
+ .type = FB_TYPE_VGA_PLANES,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .xpanstep = 8,
+ .ypanstep = 1,
+ .line_length = 640 / 8,
};
static struct display disp;
@@ -121,69 +133,22 @@ static void vga16fb_pan_var(struct fb_info *info, struct fb_var_screeninfo *var)
#endif
}
-static int vga16fb_update_var(int con, struct fb_info *info)
-{
- vga16fb_pan_var(info, &fb_display[con].var);
- return 0;
-}
-
-static int vga16fb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
-{
- struct display *p;
-
- if (con < 0)
- p = &disp;
- else
- p = fb_display + con;
-
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- strcpy(fix->id,"VGA16 VGA");
-
- fix->smem_start = VGA_FB_PHYS;
- fix->smem_len = VGA_FB_PHYS_LEN;
- fix->type = FB_TYPE_VGA_PLANES;
- fix->visual = FB_VISUAL_PSEUDOCOLOR;
- fix->xpanstep = 8;
- fix->ypanstep = 1;
- fix->ywrapstep = 0;
- fix->line_length = p->var.xres_virtual / 8;
- return 0;
-}
-
-static int vga16fb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- if(con==-1)
- memcpy(var, &vga16fb_defined, sizeof(struct fb_var_screeninfo));
- else
- *var=fb_display[con].var;
- return 0;
-}
-
static void vga16fb_set_disp(int con, struct vga16fb_info *info)
{
- struct fb_fix_screeninfo fix;
- struct display *display;
+ struct display *display = (con < 0) ? info->fb_info.disp : (fb_display + con);
- if (con < 0)
- display = &disp;
- else
- display = fb_display + con;
-
-
- vga16fb_get_fix(&fix, con, &info->fb_info);
-
- display->visual = fix.visual;
- display->type = fix.type;
- display->type_aux = fix.type_aux;
- display->ypanstep = fix.ypanstep;
- display->ywrapstep = fix.ywrapstep;
- display->line_length = fix.line_length;
- display->next_line = fix.line_length;
display->can_soft_blank = 1;
+ display->dispsw_data = NULL;
+ display->var = info->fb_info.var;
display->inverse = 0;
+ /*
+ * If we are setting all the virtual consoles, also set
+ * the defaults used to create new consoles.
+ */
+ if (con < 0 || info->fb_info.var.activate & FB_ACTIVATE_ALL)
+ info->fb_info.disp->var = info->fb_info.var;
+
if (info->isVGA)
display->dispsw = &fbcon_vga_planes;
else
@@ -500,13 +465,9 @@ static int vga16fb_set_var(struct fb_var_screeninfo *var, int con,
{
struct vga16fb_info *info = (struct vga16fb_info*)fb;
struct vga16fb_par par;
- struct display *display;
+ struct display *display = (con < 0) ? fb->disp : (fb_display + con);
int err;
- if (con < 0)
- display = fb->disp;
- else
- display = fb_display + con;
if ((err = vga16fb_decode_var(var, &par, info)) != 0)
return err;
vga16fb_encode_var(var, &par, info);
@@ -552,25 +513,6 @@ static void ega16_setpalette(int regno, unsigned red, unsigned green, unsigned b
outb_p(0x20, 0x3C0); /* unblank screen */
}
-static int vga16_getcolreg(unsigned regno, unsigned *red, unsigned *green,
- unsigned *blue, unsigned *transp,
- struct fb_info *fb_info)
-{
- /*
- * Read a single color register and split it into colors/transparent.
- * Return != 0 for invalid regno.
- */
-
- if (regno >= 16)
- return 1;
-
- *red = palette[regno].red;
- *green = palette[regno].green;
- *blue = palette[regno].blue;
- *transp = 0;
- return 0;
-}
-
static void vga16_setpalette(int regno, unsigned red, unsigned green, unsigned blue)
{
outb(regno, dac_reg);
@@ -615,19 +557,6 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,
return 0;
}
-static int vga16fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- if (con == info->currcon) /* current console? */
- return fb_get_cmap(cmap, kspc, vga16_getcolreg, info);
- else if (fb_display[con].cmap.len) /* non default colormap? */
- fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
- else
- fb_copy_cmap(fb_default_cmap(16),
- cmap, kspc ? 0 : 2);
- return 0;
-}
-
static int vga16fb_pan_display(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
@@ -811,10 +740,8 @@ static int vga16fb_blank(int blank, struct fb_info *fb_info)
static struct fb_ops vga16fb_ops = {
.owner = THIS_MODULE,
- .fb_get_fix = vga16fb_get_fix,
- .fb_get_var = vga16fb_get_var,
.fb_set_var = vga16fb_set_var,
- .fb_get_cmap = vga16fb_get_cmap,
+ .fb_get_cmap = gen_get_cmap,
.fb_set_cmap = gen_set_cmap,
.fb_setcolreg = vga16fb_setcolreg,
.fb_pan_display =vga16fb_pan_display,
@@ -839,27 +766,6 @@ int vga16fb_setup(char *options)
return 0;
}
-static int vga16fb_switch(int con, struct fb_info *fb)
-{
- struct vga16fb_par par;
- struct vga16fb_info *info = (struct vga16fb_info*)fb;
-
- /* Do we have to save the colormap? */
- if (fb_display[fb->currcon].cmap.len)
- fb_get_cmap(&fb_display[fb->currcon].cmap, 1, vga16_getcolreg,
- fb);
-
- fb->currcon = con;
- vga16fb_decode_var(&fb_display[con].var, &par, info);
- vga16fb_set_par(&par, info);
- vga16fb_set_disp(con, info);
-
- /* Install new colormap */
- do_install_cmap(con, fb);
-/* vga16fb_update_var(con, fb); */
- return 1;
-}
-
int __init vga16fb_init(void)
{
int i,j;
@@ -895,19 +801,22 @@ int __init vga16fb_init(void)
disp.var = vga16fb_defined;
- /* name should not depend on EGA/VGA */
- strcpy(vga16fb.fb_info.modename, "VGA16 VGA");
+ strcpy(vga16fb.fb_info.modename, vga16fb_fix.id);
vga16fb.fb_info.changevar = NULL;
vga16fb.fb_info.node = NODEV;
+ vga16fb.fb_info.var = vga16fb_defined;
+ vga16fb.fb_info.fix = vga16fb_fix;
vga16fb.fb_info.fbops = &vga16fb_ops;
vga16fb.fb_info.screen_base = vga16fb.video_vbase;
vga16fb.fb_info.disp=&disp;
vga16fb.fb_info.currcon = -1;
- vga16fb.fb_info.switch_con=&vga16fb_switch;
- vga16fb.fb_info.updatevar=&vga16fb_update_var;
+ vga16fb.fb_info.switch_con=&gen_switch;
+ vga16fb.fb_info.updatevar=&gen_update_var;
vga16fb.fb_info.flags=FBINFO_FLAG_DEFAULT;
vga16fb_set_disp(-1, &vga16fb);
+ fb_alloc_cmap(&vga16fb.fb_info.cmap, 16, 0);
+
if (register_framebuffer(&vga16fb.fb_info)<0) {
iounmap(vga16fb.video_vbase);
return -EINVAL;
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index ca32f9246891..5b08b3ca0074 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -575,6 +575,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
} else {
INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc, server);
INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc, server);
+ init_timer(&server->timeout_tm);
server->timeout_tm.data = (unsigned long)server;
server->timeout_tm.function = ncpdgram_timeout_call;
}
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 450dd174d3ea..00e80906b170 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -126,9 +126,9 @@ static const char *task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
- "Z (zombie)", /* 4 */
"T (stopped)", /* 8 */
- "W (paging)" /* 16 */
+ "Z (zombie)", /* 4 */
+ "X (dead)" /* 16 */
};
static inline const char * get_task_state(struct task_struct *tsk)
diff --git a/include/asm-i386/io_apic.h b/include/asm-i386/io_apic.h
index e26ea03e7347..500053c36f82 100644
--- a/include/asm-i386/io_apic.h
+++ b/include/asm-i386/io_apic.h
@@ -120,9 +120,14 @@ static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned i
/*
* Re-write a value: to be used for read-modify-write
* cycles where the read already set up the index register.
+ *
+ * Older SiS APIC requires we rewrite the index regiser
*/
-static inline void io_apic_modify(unsigned int apic, unsigned int value)
+extern int sis_apic_bug;
+static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
{
+ if (sis_apic_bug)
+ *IO_APIC_BASE(apic) = reg;
*(IO_APIC_BASE(apic)+4) = value;
}
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 360efe8de768..ec17e06a6df0 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -221,6 +221,9 @@ static inline void clear_in_cr4 (unsigned long mask)
/*
* NSC/Cyrix CPU configuration register indexes
*/
+
+#define CX86_PCR0 0x20
+#define CX86_GCR 0xb8
#define CX86_CCR0 0xc0
#define CX86_CCR1 0xc1
#define CX86_CCR2 0xc2
@@ -229,6 +232,7 @@ static inline void clear_in_cr4 (unsigned long mask)
#define CX86_CCR5 0xe9
#define CX86_CCR6 0xea
#define CX86_CCR7 0xeb
+#define CX86_PCR1 0xf0
#define CX86_DIR0 0xfe
#define CX86_DIR1 0xff
#define CX86_ARR_BASE 0xc4
diff --git a/include/linux/dvb/ca.h b/include/linux/dvb/ca.h
index b7ce90ec3618..a0bdd645c745 100644
--- a/include/linux/dvb/ca.h
+++ b/include/linux/dvb/ca.h
@@ -26,7 +26,7 @@
/* slot interface types and info */
-typedef struct ca_slot_info_s {
+typedef struct ca_slot_info {
int num; /* slot number */
int type; /* CA interface this slot supports */
@@ -43,7 +43,7 @@ typedef struct ca_slot_info_s {
/* descrambler types and info */
-typedef struct ca_descr_info_s {
+typedef struct ca_descr_info {
unsigned int num; /* number of available descramblers (keys) */
unsigned int type; /* type of supported scrambling system */
#define CA_ECD 1
@@ -51,29 +51,29 @@ typedef struct ca_descr_info_s {
#define CA_DSS 4
} ca_descr_info_t;
-typedef struct ca_cap_s {
+typedef struct ca_caps {
unsigned int slot_num; /* total number of CA card and module slots */
unsigned int slot_type; /* OR of all supported types */
unsigned int descr_num; /* total number of descrambler slots (keys) */
unsigned int descr_type; /* OR of all supported types */
-} ca_cap_t;
+} ca_caps_t;
/* a message to/from a CI-CAM */
-typedef struct ca_msg_s {
+typedef struct ca_msg {
unsigned int index;
unsigned int type;
unsigned int length;
unsigned char msg[256];
} ca_msg_t;
-typedef struct ca_descr_s {
+typedef struct ca_descr {
unsigned int index;
unsigned int parity;
unsigned char cw[8];
} ca_descr_t;
#define CA_RESET _IO('o', 128)
-#define CA_GET_CAP _IOR('o', 129, ca_cap_t)
+#define CA_GET_CAP _IOR('o', 129, ca_caps_t)
#define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t)
#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t)
#define CA_GET_MSG _IOR('o', 132, ca_msg_t)
diff --git a/include/linux/dvb/osd.h b/include/linux/dvb/osd.h
index 143c8296f895..760ccff6c75c 100644
--- a/include/linux/dvb/osd.h
+++ b/include/linux/dvb/osd.h
@@ -26,7 +26,7 @@
typedef enum {
// All functions return -2 on "not open"
- OSD_Close = 1, // ()
+ OSD_Close=1, // ()
// Disables OSD and releases the buffers
// returns 0 on success
OSD_Open, // (x0,y0,x1,y1,BitPerPixel[2/4/8](color&0x0F),mix[0..15](color&0xF0))
@@ -108,3 +108,4 @@ typedef struct osd_cmd_s {
#define OSD_SEND_CMD _IOW('o', 160, osd_cmd_t)
#endif
+
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 4d1b4c56c7a0..c4fdbf756d52 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -299,9 +299,9 @@ typedef enum { ide_unknown, ide_generic, ide_pci,
typedef struct ide_io_ops_s {
/* insert io operations here! */
- void (*OUTB)(u8 addr, ide_ioreg_t port);
- void (*OUTW)(u16 addr, ide_ioreg_t port);
- void (*OUTL)(u32 addr, ide_ioreg_t port);
+ void (*OUTB)(u8 value, ide_ioreg_t port);
+ void (*OUTW)(u16 value, ide_ioreg_t port);
+ void (*OUTL)(u32 value, ide_ioreg_t port);
void (*OUTSW)(ide_ioreg_t port, void *addr, u32 count);
void (*OUTSL)(ide_ioreg_t port, void *addr, u32 count);
@@ -740,6 +740,7 @@ typedef struct ide_drive_s {
u8 nice1; /* give potential excess bandwidth */
unsigned present : 1; /* drive is physically present */
+ unsigned dead : 1; /* device ejected hint */
unsigned noprobe : 1; /* from: hdx=noprobe */
unsigned removable : 1; /* 1 if need to do check_media_change */
unsigned is_flash : 1; /* 1 if probed as flash */
@@ -756,6 +757,7 @@ typedef struct ide_drive_s {
unsigned remap_0_to_1 : 2; /* 0=remap if ezdrive, 1=remap, 2=noremap */
unsigned ata_flash : 1; /* 1=present, 0=default */
unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */
+ unsigned vdma : 1; /* 1=doing PIO over DMA 0=doing normal DMA */
unsigned queue_setup : 1;
unsigned addressing; /* : 3;
* 0=28-bit
@@ -1189,9 +1191,7 @@ typedef struct ide_driver_s {
unsigned supports_dma : 1;
unsigned supports_dsc_overlap : 1;
int (*cleanup)(ide_drive_t *);
- int (*standby)(ide_drive_t *);
- int (*suspend)(ide_drive_t *);
- int (*resume)(ide_drive_t *);
+ int (*shutdown)(ide_drive_t *);
int (*flushcache)(ide_drive_t *);
ide_startstop_t (*do_request)(ide_drive_t *, struct request *, sector_t);
int (*end_request)(ide_drive_t *, int, int);
@@ -1599,6 +1599,8 @@ extern int ideprobe_init(void);
extern void ide_scan_pcibus(int scan_direction) __init;
extern int ide_pci_register_driver(struct pci_driver *driver);
extern void ide_pci_unregister_driver(struct pci_driver *driver);
+extern void ide_pci_setup_ports(struct pci_dev *dev, struct ide_pci_device_s *d, int autodma, int pciirq, ata_index_t *index);
+extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d);
extern void default_hwif_iops(ide_hwif_t *);
extern void default_hwif_mmiops(ide_hwif_t *);
@@ -1647,6 +1649,7 @@ typedef struct ide_pci_device_s {
u16 device;
char *name;
void (*init_setup)(struct pci_dev *, struct ide_pci_device_s *);
+ void (*init_setup_dma)(struct pci_dev *, struct ide_pci_device_s *, ide_hwif_t *);
unsigned int (*init_chipset)(struct pci_dev *, const char *);
void (*init_iops)(ide_hwif_t *);
void (*init_hwif)(ide_hwif_t *);
@@ -1657,6 +1660,7 @@ typedef struct ide_pci_device_s {
u8 bootable;
unsigned int extra;
struct ide_pci_device_s *next;
+ u8 isa_ports; /* Uses ISA control ports not PCI ones */
} ide_pci_device_t;
extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
@@ -1664,6 +1668,8 @@ extern void ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, ide_pci_de
#define BAD_DMA_DRIVE 0
#define GOOD_DMA_DRIVE 1
+
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
extern int ide_build_dmatable(ide_drive_t *, struct request *);
extern void ide_destroy_dmatable(ide_drive_t *);
extern ide_startstop_t ide_dma_intr(ide_drive_t *);
@@ -1708,6 +1714,10 @@ static inline int __ide_dma_queued_off(ide_drive_t *drive)
}
#endif
+#else
+static inline void ide_release_dma(ide_hwif_t *) {;}
+#endif
+
extern void hwif_unregister(ide_hwif_t *);
extern void export_ide_init_queue(ide_drive_t *);
@@ -1730,6 +1740,7 @@ extern u8 ide_rate_filter(u8 mode, u8 speed);
extern int ide_dma_enable(ide_drive_t *drive);
extern char *ide_xfer_verbose(u8 xfer_rate);
extern void ide_toggle_bounce(ide_drive_t *drive, int on);
+extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate);
extern spinlock_t ide_lock;
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index f8890c70fa89..584b9f55b7e3 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -165,6 +165,7 @@
#define PCI_DEVICE_ID_LSI_53C1010_33 0x0020
#define PCI_DEVICE_ID_LSI_53C1010_66 0x0021
#define PCI_DEVICE_ID_LSI_53C1030 0x0030
+#define PCI_DEVICE_ID_LSI_1030_53C1035 0x0032
#define PCI_DEVICE_ID_LSI_53C1035 0x0040
#define PCI_DEVICE_ID_NCR_53C875J 0x008f
#define PCI_DEVICE_ID_LSI_FC909 0x0621
@@ -172,6 +173,8 @@
#define PCI_DEVICE_ID_LSI_FC929_LAN 0x0623
#define PCI_DEVICE_ID_LSI_FC919 0x0624
#define PCI_DEVICE_ID_LSI_FC919_LAN 0x0625
+#define PCI_DEVICE_ID_LSI_FC929X 0x0626
+#define PCI_DEVICE_ID_LSI_FC919X 0x0628
#define PCI_DEVICE_ID_NCR_YELLOWFIN 0x0701
#define PCI_DEVICE_ID_LSI_61C102 0x0901
#define PCI_DEVICE_ID_LSI_63C815 0x1000
@@ -265,6 +268,8 @@
#define PCI_DEVICE_ID_ATI_RADEON_RB 0x5145
#define PCI_DEVICE_ID_ATI_RADEON_RC 0x5146
#define PCI_DEVICE_ID_ATI_RADEON_RD 0x5147
+/* RadeonIGP */
+#define PCI_DEVICE_ID_ATI_RADEON_IGP 0xCAB0
#define PCI_VENDOR_ID_VLSI 0x1004
#define PCI_DEVICE_ID_VLSI_82C592 0x0005
@@ -456,14 +461,31 @@
#define PCI_DEVICE_ID_MIRO_36050 0x5601
#define PCI_VENDOR_ID_NEC 0x1033
-#define PCI_DEVICE_ID_NEC_PCX2 0x0046
+#define PCI_DEVICE_ID_NEC_CBUS_1 0x0001 /* PCI-Cbus Bridge */
+#define PCI_DEVICE_ID_NEC_LOCAL 0x0002 /* Local Bridge */
+#define PCI_DEVICE_ID_NEC_ATM 0x0003 /* ATM LAN Controller */
+#define PCI_DEVICE_ID_NEC_R4000 0x0004 /* R4000 Bridge */
+#define PCI_DEVICE_ID_NEC_486 0x0005 /* 486 Like Peripheral Bus Bridge */
+#define PCI_DEVICE_ID_NEC_ACCEL_1 0x0006 /* Graphic Accelerator */
+#define PCI_DEVICE_ID_NEC_UXBUS 0x0007 /* UX-Bus Bridge */
+#define PCI_DEVICE_ID_NEC_ACCEL_2 0x0008 /* Graphic Accelerator */
+#define PCI_DEVICE_ID_NEC_GRAPH 0x0009 /* PCI-CoreGraph Bridge */
+#define PCI_DEVICE_ID_NEC_VL 0x0016 /* PCI-VL Bridge */
+#define PCI_DEVICE_ID_NEC_STARALPHA2 0x002c /* STAR ALPHA2 */
+#define PCI_DEVICE_ID_NEC_CBUS_2 0x002d /* PCI-Cbus Bridge */
+#define PCI_DEVICE_ID_NEC_USB 0x0035 /* PCI-USB Host */
+#define PCI_DEVICE_ID_NEC_CBUS_3 0x003b
+#define PCI_DEVICE_ID_NEC_PCX2 0x0046 /* PowerVR */
#define PCI_DEVICE_ID_NEC_NILE4 0x005a
#define PCI_DEVICE_ID_NEC_VRC5476 0x009b
#define PCI_DEVICE_ID_NEC_VRC5477_AC97 0x00a6
+#define PCI_DEVICE_ID_NEC_PC9821CS01 0x800c /* PC-9821-CS01 */
+#define PCI_DEVICE_ID_NEC_PC9821NRB06 0x800d /* PC-9821NR-B06 */
#define PCI_VENDOR_ID_FD 0x1036
#define PCI_DEVICE_ID_FD_36C70 0x0000
+#define PCI_VENDOR_ID_SIS 0x1039
#define PCI_VENDOR_ID_SI 0x1039
#define PCI_DEVICE_ID_SI_5591_AGP 0x0001
#define PCI_DEVICE_ID_SI_6202 0x0002
@@ -1238,6 +1260,8 @@
#define PCI_DEVICE_ID_ATT_L56XMF 0x0440
#define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480
+#define PCI_VENDOR_ID_NEC2 0x11c3 /* NEC (2nd) */
+
#define PCI_VENDOR_ID_SPECIALIX 0x11cb
#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000
#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000
@@ -1883,4 +1907,3 @@
#define PCI_VENDOR_ID_HINT 0x3388
#define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013
-
diff --git a/include/linux/serio.h b/include/linux/serio.h
index b0690405229d..2e45f82a554d 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -97,6 +97,7 @@ static __inline__ void serio_cleanup(struct serio *serio)
#define SERIO_8042 0x01000000UL
#define SERIO_RS232 0x02000000UL
#define SERIO_HIL_MLC 0x03000000UL
+#define SERIO_PC9800 0x04000000UL
#define SERIO_PROTO 0xFFUL
#define SERIO_MSC 0x01
diff --git a/include/linux/soundmodem.h b/include/linux/soundmodem.h
deleted file mode 100644
index 10d0799d6e1c..000000000000
--- a/include/linux/soundmodem.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * The Linux soundcard driver for 1200 baud and 9600 baud packet radio
- * (C) 1996-1998 by Thomas Sailer, HB9JNX/AE4WA
- */
-
-#ifndef _SOUNDMODEM_H
-#define _SOUNDMODEM_H
-
-/* -------------------------------------------------------------------- */
-/*
- * structs for the IOCTL commands
- */
-
-struct sm_debug_data {
- unsigned int int_rate;
- unsigned int mod_cycles;
- unsigned int demod_cycles;
- unsigned int dma_residue;
-};
-
-struct sm_diag_data {
- unsigned int mode;
- unsigned int flags;
- unsigned int samplesperbit;
- unsigned int datalen;
- short *data;
-};
-
-struct sm_mixer_data {
- unsigned int mixer_type;
- unsigned int sample_rate;
- unsigned int bit_rate;
- unsigned int reg;
- unsigned int data;
-};
-
-struct sm_config {
- int hardware;
- int mode;
-};
-
-struct sm_ioctl {
- int cmd;
- union {
- struct sm_config cfg;
- struct sm_diag_data diag;
- struct sm_mixer_data mix;
- struct sm_debug_data dbg;
- } data;
-};
-
-/* -------------------------------------------------------------------- */
-
-/*
- * diagnose modes
- */
-#define SM_DIAGMODE_OFF 0
-#define SM_DIAGMODE_INPUT 1
-#define SM_DIAGMODE_DEMOD 2
-#define SM_DIAGMODE_CONSTELLATION 3
-
-/*
- * diagnose flags
- */
-#define SM_DIAGFLAG_DCDGATE (1<<0)
-#define SM_DIAGFLAG_VALID (1<<1)
-
-/*
- * mixer types
- */
-#define SM_MIXER_INVALID 0
-#define SM_MIXER_AD1848 0x10
-#define SM_MIXER_CRYSTAL 0x11
-#define SM_MIXER_CT1335 0x20
-#define SM_MIXER_CT1345 0x21
-#define SM_MIXER_CT1745 0x22
-
-/*
- * ioctl values
- */
-#define SMCTL_DIAGNOSE 0x82
-#define SMCTL_GETMIXER 0x83
-#define SMCTL_SETMIXER 0x84
-#define SMCTL_GETDEBUG 0x85
-
-/* -------------------------------------------------------------------- */
-
-#endif /* _SOUNDMODEM_H */
-
-/* --------------------------------------------------------------------- */
diff --git a/include/net/irda/vlsi_ir.h b/include/net/irda/vlsi_ir.h
index 32d30cbc0920..3ce8cd6cd1e7 100644
--- a/include/net/irda/vlsi_ir.h
+++ b/include/net/irda/vlsi_ir.h
@@ -27,26 +27,6 @@
#ifndef IRDA_VLSI_FIR_H
#define IRDA_VLSI_FIR_H
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,4)
-#ifdef CONFIG_PROC_FS
-/* PDE() introduced in 2.5.4 */
-#define PDE(inode) ((inode)->u.generic_ip)
-#endif
-#endif
-
-/*
- * #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,xx)
- *
- * missing pci-dma api call to give streaming dma buffer back to hw
- * patch floating on lkml - probably present in 2.5.26 or later
- * otherwise defining it as noop is ok, since the vlsi-ir is only
- * used on two oldish x86-based notebooks which are cache-coherent
- */
-#define pci_dma_prep_single(dev, addr, size, direction) /* nothing */
-/*
- * #endif
- */
-
/* ================================================================ */
/* non-standard PCI registers */
diff --git a/net/atm/common.c b/net/atm/common.c
index 1b6bb3d67ab1..ad5275892d3d 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -287,7 +287,7 @@ int atm_connect_vcc(struct atm_vcc *vcc,int itf,short vpi,int vci)
if (vpi != ATM_VPI_UNSPEC && vci != ATM_VCI_UNSPEC)
clear_bit(ATM_VF_PARTIAL,&vcc->flags);
else if (test_bit(ATM_VF_PARTIAL,&vcc->flags)) return -EINVAL;
- printk(KERN_DEBUG "atm_connect (TX: cl %d,bw %d-%d,sdu %d; "
+ DPRINTK("atm_connect (TX: cl %d,bw %d-%d,sdu %d; "
"RX: cl %d,bw %d-%d,sdu %d,AAL %s%d)\n",
vcc->qos.txtp.traffic_class,vcc->qos.txtp.min_pcr,
vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu,
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c
index e4b00d683981..d248d667ef5d 100644
--- a/net/wanrouter/wanmain.c
+++ b/net/wanrouter/wanmain.c
@@ -124,14 +124,6 @@ static void dbg_kfree(void * v, int line) {
*/
/*
- * Kernel loadable module interface.
- */
-#ifdef MODULE
-int init_module (void);
-void cleanup_module (void);
-#endif
-
-/*
* WAN device IOCTL handlers
*/
diff --git a/scripts/lxdialog/util.c b/scripts/lxdialog/util.c
index b3a7af9d2dda..e7bce9be69c3 100644
--- a/scripts/lxdialog/util.c
+++ b/scripts/lxdialog/util.c
@@ -348,7 +348,7 @@ first_alpha(const char *string, const char *exempt)
c = tolower(string[i]);
if (strchr("<[(", c)) ++in_paren;
- if (strchr(">])", c)) --in_paren;
+ if (strchr(">])", c) && in_paren > 0) --in_paren;
if ((! in_paren) && isalpha(c) &&
strchr(exempt, c) == 0)
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 8adcb35dc29f..47f04d83d745 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -156,7 +156,7 @@ config SOUND_ES1370
1274:5000. Since Ensoniq was bought by Creative Labs,
Sound Blaster 64/PCI models are either ES1370 or ES1371 based.
This driver differs slightly from OSS/Free, so PLEASE READ
- <file:Documentation/sound/es1370>.
+ <file:Documentation/sound/oss/es1370>.
config SOUND_ES1371
tristate "Creative Ensoniq AudioPCI 97 (ES1371)"
@@ -180,7 +180,7 @@ config SOUND_ESSSOLO1
Solo1 chip without removing your computer's cover, use
lspci -n and look for the PCI ID 125D:1969. This driver
differs slightly from OSS/Free, so PLEASE READ
- <file:Documentation/sound/solo1>.
+ <file:Documentation/sound/oss/solo1>.
config SOUND_MAESTRO
tristate "ESS Maestro, Maestro2, Maestro2E driver"
@@ -188,7 +188,7 @@ config SOUND_MAESTRO
help
Say Y or M if you have a sound system driven by ESS's Maestro line
of PCI sound chips. These include the Maestro 1, Maestro 2, and
- Maestro 2E. See <file:Documentation/sound/Maestro> for more
+ Maestro 2E. See <file:Documentation/sound/oss/Maestro> for more
details.
config SOUND_MAESTRO3
@@ -221,7 +221,7 @@ config SOUND_SONICVIBES
SonicVibes chip without removing your computer's cover, use
lspci -n and look for the PCI ID 5333:CA00. This driver
differs slightly from OSS/Free, so PLEASE READ
- <file:Documentation/sound/sonicvibes>.
+ <file:Documentation/sound/oss/sonicvibes>.
config SOUND_VWSND
tristate "SGI Visual Workstation Sound"
@@ -229,7 +229,7 @@ config SOUND_VWSND
help
Say Y or M if you have an SGI Visual Workstation and you want to be
able to use its on-board audio. Read
- <file:Documentation/sound/vwsnd> for more info on this driver's
+ <file:Documentation/sound/oss/vwsnd> for more info on this driver's
capabilities.
config SOUND_VRC5477
@@ -284,7 +284,7 @@ config SOUND_MSNDCLAS
Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or
Monterey (not for the Pinnacle or Fiji).
- See <file:Documentation/sound/MultiSound> for important information
+ See <file:Documentation/sound/oss/MultiSound> for important information
about this driver. Note that it has been discontinued, but the
Voyetra Turtle Beach knowledge base entry for it is still available
at <http://www.voyetra-turtle-beach.com/site/kb_ftp/790.asp>.
@@ -293,7 +293,7 @@ comment "Compiled-in MSND Classic support requires firmware during compilation."
depends on SOUND_PRIME && SOUND_MSNDCLAS=y
config MSNDCLAS_HAVE_BOOT
- bool
+ bool "Have MSNDINIT.BIN firmware file"
depends on SOUND_MSNDCLAS=y
default y
@@ -305,7 +305,7 @@ config MSNDCLAS_INIT_FILE
The MultiSound cards have two firmware files which are required for
operation, and are not currently included. These files can be
obtained from Turtle Beach. See
- <file:Documentation/sound/MultiSound> for information on how to
+ <file:Documentation/sound/oss/MultiSound> for information on how to
obtain this.
config MSNDCLAS_PERM_FILE
@@ -316,7 +316,7 @@ config MSNDCLAS_PERM_FILE
The MultiSound cards have two firmware files which are required for
operation, and are not currently included. These files can be
obtained from Turtle Beach. See
- <file:Documentation/sound/MultiSound> for information on how to
+ <file:Documentation/sound/oss/MultiSound> for information on how to
obtain this.
config MSNDCLAS_IRQ
@@ -346,7 +346,7 @@ config SOUND_MSNDPIN
depends on SOUND_PRIME!=n && SOUND
help
Say M here if you have a Turtle Beach MultiSound Pinnacle or Fiji.
- See <file:Documentation/sound/MultiSound> for important information
+ See <file:Documentation/sound/oss/MultiSound> for important information
about this driver. Note that it has been discontinued, but the
Voyetra Turtle Beach knowledge base entry for it is still available
at <http://www.voyetra-turtle-beach.com/site/kb_ftp/600.asp>.
@@ -355,7 +355,7 @@ comment "Compiled-in MSND Pinnacle support requires firmware during compilation.
depends on SOUND_PRIME && SOUND_MSNDPIN=y
config MSNDPIN_HAVE_BOOT
- bool
+ bool "Have PNDSPINI.BIN firmware file"
depends on SOUND_MSNDPIN=y
default y
@@ -367,7 +367,7 @@ config MSNDPIN_INIT_FILE
The MultiSound cards have two firmware files which are required
for operation, and are not currently included. These files can be
obtained from Turtle Beach. See
- <file:Documentation/sound/MultiSound> for information on how to
+ <file:Documentation/sound/oss/MultiSound> for information on how to
obtain this.
config MSNDPIN_PERM_FILE
@@ -378,7 +378,7 @@ config MSNDPIN_PERM_FILE
The MultiSound cards have two firmware files which are required for
operation, and are not currently included. These files can be
obtained from Turtle Beach. See
- <file:Documentation/sound/MultiSound> for information on how to
+ <file:Documentation/sound/oss/MultiSound> for information on how to
obtain this.
config MSNDPIN_IRQ
@@ -412,7 +412,7 @@ config MSNDPIN_DIGITAL
If you have the S/PDIF daughter board for the Pinnacle or Fiji,
answer Y here; otherwise, say N. If you have this, you will be able
to play and record from the S/PDIF port (digital signal). See
- <file:Documentation/sound/MultiSound> for information on how to make
+ <file:Documentation/sound/oss/MultiSound> for information on how to make
use of this capability.
config MSNDPIN_NONPNP
@@ -613,7 +613,7 @@ config SOUND_CS4232
"cs4232=<io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>" to the kernel
command line.
- See <file:Documentation/sound/CS4232> for more information on
+ See <file:Documentation/sound/oss/CS4232> for more information on
configuring this card.
config SOUND_SSCAPE
@@ -633,7 +633,7 @@ config SOUND_GUS
depends on SOUND_OSS
help
Say Y here for any type of Gravis Ultrasound card, including the GUS
- or GUS MAX. See also <file:Documentation/sound/ultrasound> for more
+ or GUS MAX. See also <file:Documentation/sound/oss/ultrasound> for more
information on configuring this card with modules.
If you compile the driver into the kernel, you have to add
@@ -706,7 +706,7 @@ config SOUND_MSS
synthesizers (OPL2, OPL3 and OPL4), 6850 UART MIDI Interface.
For cards having native support in VoxWare, consult the card
- specific instructions in <file:Documentation/sound/README.OSS>.
+ specific instructions in <file:Documentation/sound/oss/README.OSS>.
Some drivers have their own MSS support and saying Y to this option
will cause a conflict.
@@ -724,7 +724,7 @@ config SOUND_MPU401
will cause a conflict. Also, enabling MPU401 on a system that
doesn't really have a MPU401 could cause some trouble. If your card
was in the list of supported cards, look at the card specific
- instructions in the <file:Documentation/sound/README.OSS> file. It
+ instructions in the <file:Documentation/sound/oss/README.OSS> file. It
is safe to answer Y if you have a true MPU401 MIDI interface card.
If you compile the driver into the kernel, you have to add
@@ -740,7 +740,7 @@ config SOUND_NM256
laptops. It includes support for an AC97-compatible mixer and an
apparently proprietary sound engine.
- See <file:Documentation/sound/NM256> for further information.
+ See <file:Documentation/sound/oss/NM256> for further information.
config SOUND_MAD16
tristate "OPTi MAD16 and/or Mozart based cards"
@@ -759,8 +759,8 @@ config SOUND_MAD16
"mad16=<io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>" to the
kernel command line.
- See also <file:Documentation/sound/Opti> and
- <file:Documentation/sound/MAD16> for more information on setting
+ See also <file:Documentation/sound/oss/Opti> and
+ <file:Documentation/sound/oss/MAD16> for more information on setting
these cards up as modules.
config MAD16_OLDCARD
@@ -778,7 +778,7 @@ config SOUND_PAS
Answer Y only if you have a Pro Audio Spectrum 16, ProAudio Studio
16 or Logitech SoundMan 16 sound card. Answer N if you have some
other card made by Media Vision or Logitech since those are not
- PAS16 compatible. Please read <file:Documentation/sound/PAS16>.
+ PAS16 compatible. Please read <file:Documentation/sound/oss/PAS16>.
It is not necessary to add Sound Blaster support separately; it
is included in PAS support.
@@ -801,7 +801,7 @@ config SOUND_PSS
ADSP-16 or some other card based on the PSS chipset (AD1848 codec +
ADSP-2115 DSP chip + Echo ESC614 ASIC CHIP). For more information on
how to compile it into the kernel or as a module see the file
- <file:Documentation/sound/PSS>.
+ <file:Documentation/sound/oss/PSS>.
If you compile the driver into the kernel, you have to add
"pss=<io>,<mssio>,<mssirq>,<mssdma>,<mpuio>,<mpuirq>" to the kernel
@@ -818,7 +818,7 @@ config PSS_MIXER
If you said M to "PSS support" above, you may enable or disable this
PSS mixer with the module parameter pss_mixer. For more information
- see the file <file:Documentation/sound/PSS>.
+ see the file <file:Documentation/sound/oss/PSS>.
config PSS_HAVE_BOOT
bool "Have DSPxxx.LD firmware file"
@@ -845,16 +845,16 @@ config SOUND_SB
SM Games). For an unknown card you may answer Y if the card claims
to be Sound Blaster-compatible.
- Please read the file <file:Documentation/sound/Soundblaster>.
+ Please read the file <file:Documentation/sound/oss/Soundblaster>.
You should also say Y here for cards based on the Avance Logic
- ALS-007 and ALS-1X0 chips (read <file:Documentation/sound/ALS>) and
+ ALS-007 and ALS-1X0 chips (read <file:Documentation/sound/oss/ALS>) and
for cards based on ESS chips (read
- <file:Documentation/sound/ESS1868> and
- <file:Documentation/sound/ESS>). If you have an SB AWE 32 or SB AWE
+ <file:Documentation/sound/oss/ESS1868> and
+ <file:Documentation/sound/oss/ESS>). If you have an SB AWE 32 or SB AWE
64, say Y here and also to "AWE32 synth" below and read
- <file:Documentation/sound/INSTALL.awe>. If you have an IBM Mwave
- card, say Y here and read <file:Documentation/sound/mwave>.
+ <file:Documentation/sound/oss/INSTALL.awe>. If you have an IBM Mwave
+ card, say Y here and read <file:Documentation/sound/oss/mwave>.
If you compile the driver into the kernel and don't want to use
isapnp, you have to add "sb=<io>,<irq>,<dma>,<dma2>" to the kernel
@@ -868,8 +868,8 @@ config SOUND_AWE32_SYNTH
depends on SOUND_OSS
help
Say Y here if you have a Sound Blaster SB32, AWE32-PnP, SB AWE64 or
- similar sound card. See <file:Documentation/sound/README.awe>,
- <file:Documentation/sound/AWE32> and the Soundblaster-AWE
+ similar sound card. See <file:Documentation/sound/oss/README.awe>,
+ <file:Documentation/sound/oss/AWE32> and the Soundblaster-AWE
mini-HOWTO, available from <http://www.linuxdoc.org/docs.html#howto>
for more info.
@@ -878,8 +878,8 @@ config SOUND_WAVEFRONT
depends on SOUND_OSS && m
help
Answer Y or M if you have a Tropez Plus, Tropez or Maui sound card
- and read the files <file:Documentation/sound/Wavefront> and
- <file:Documentation/sound/Tropez+>.
+ and read the files <file:Documentation/sound/oss/Wavefront> and
+ <file:Documentation/sound/oss/Tropez+>.
config SOUND_MAUI
tristate "Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers"
@@ -916,7 +916,7 @@ config SOUND_YM3812
cards may have software (TSR) FM emulation. Enabling FM support with
these cards may cause trouble (I don't currently know of any such
cards, however). Please read the file
- <file:Documentation/sound/OPL3> if your card has an OPL3 chip.
+ <file:Documentation/sound/oss/OPL3> if your card has an OPL3 chip.
If you compile the driver into the kernel, you have to add
"opl3=<io>" to the kernel command line.
@@ -929,7 +929,7 @@ config SOUND_OPL3SA1
help
Say Y or M if you have a Yamaha OPL3-SA1 sound chip, which is
usually built into motherboards. Read
- <file:Documentation/sound/OPL3-SA> for details.
+ <file:Documentation/sound/oss/OPL3-SA> for details.
If you compile the driver into the kernel, you have to add
"opl3sa=<io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>" to the kernel
@@ -941,7 +941,7 @@ config SOUND_OPL3SA2
help
Say Y or M if you have a card based on one of these Yamaha sound
chipsets or the "SAx", which is actually a SA3. Read
- <file:Documentation/sound/OPL3-SA2> for more information on
+ <file:Documentation/sound/oss/OPL3-SA2> for more information on
configuring these cards.
If you compile the driver into the kernel and do not also
@@ -989,9 +989,9 @@ config SOUND_AEDSP16
accordingly. You should say Y to one and only one of these two
questions.
- Read the <file:Documentation/sound/README.OSS> file and the head of
+ Read the <file:Documentation/sound/oss/README.OSS> file and the head of
<file:drivers/sound/aedsp16.c> as well as
- <file:Documentation/sound/AudioExcelDSP16> to get more information
+ <file:Documentation/sound/oss/AudioExcelDSP16> to get more information
about this driver and its configuration.
config SC6600
diff --git a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c
index 839a66312121..7a5995c090f0 100644
--- a/sound/oss/i810_audio.c
+++ b/sound/oss/i810_audio.c
@@ -2090,14 +2090,14 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
#if defined(DEBUG) || defined(DEBUG_MMAP)
printk("SNDCTL_DSP_SETTRIGGER 0x%x\n", val);
#endif
- if( !(val & PCM_ENABLE_INPUT) && dmabuf->enable == ADC_RUNNING) {
+ if((file->f_mode & FMODE_READ) && !(val & PCM_ENABLE_INPUT) && dmabuf->enable == ADC_RUNNING) {
stop_adc(state);
}
- if( !(val & PCM_ENABLE_OUTPUT) && dmabuf->enable == DAC_RUNNING) {
+ if((file->f_mode & FMODE_WRITE) && !(val & PCM_ENABLE_OUTPUT) && dmabuf->enable == DAC_RUNNING) {
stop_dac(state);
}
dmabuf->trigger = val;
- if(val & PCM_ENABLE_OUTPUT && !(dmabuf->enable & DAC_RUNNING)) {
+ if((file->f_mode & FMODE_WRITE) && (val & PCM_ENABLE_OUTPUT) && !(dmabuf->enable & DAC_RUNNING)) {
if (!dmabuf->write_channel) {
dmabuf->ready = 0;
dmabuf->write_channel = state->card->alloc_pcm_channel(state->card);
@@ -2118,7 +2118,7 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
} else
start_dac(state);
}
- if(val & PCM_ENABLE_INPUT && !(dmabuf->enable & ADC_RUNNING)) {
+ if((file->f_mode & FMODE_READ) && (val & PCM_ENABLE_INPUT) && !(dmabuf->enable & ADC_RUNNING)) {
if (!dmabuf->read_channel) {
dmabuf->ready = 0;
dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card);
@@ -3134,6 +3134,7 @@ static int __init i810_init_module (void)
printk(KERN_INFO "Intel 810 + AC97 Audio, version "
DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
+ printk(KERN_WARNING "This driver is deprecated, please use the ALSA drivers.\n");
if (!pci_register_driver(&i810_pci_driver)) {
pci_unregister_driver(&i810_pci_driver);
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index cbd27855b7ff..3386309de70e 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -2109,7 +2109,7 @@ static void cs4281_suspend(cs4281_t *chip)
snd_cs4281_pokeBA0(chip, BA0_HICR, BA0_HICR_CHGM);
/* remember the status registers */
- for (i = 0; number_of(saved_regs); i++)
+ for (i = 0; i < number_of(saved_regs); i++)
if (saved_regs[i])
chip->suspend_regs[i] = snd_cs4281_peekBA0(chip, saved_regs[i]);
@@ -2153,7 +2153,7 @@ static void cs4281_resume(cs4281_t *chip)
snd_cs4281_chip_init(chip, 0);
/* restore the status registers */
- for (i = 0; number_of(saved_regs); i++)
+ for (i = 0; i < number_of(saved_regs); i++)
if (saved_regs[i])
snd_cs4281_pokeBA0(chip, saved_regs[i], chip->suspend_regs[i]);
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 272c6f3770e6..182491f8cb27 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -1027,6 +1027,7 @@ static int snd_cs46xx_capture_trigger(snd_pcm_substream_t * substream,
return result;
}
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
static int _cs46xx_adjust_sample_rate (cs46xx_t *chip, cs46xx_pcm_t *cpcm,
int sample_rate)
{
@@ -1055,7 +1056,6 @@ static int _cs46xx_adjust_sample_rate (cs46xx_t *chip, cs46xx_pcm_t *cpcm,
cpcm->hw_addr,
cpcm->pcm_channel->pcm_channel_id)) == NULL) {
snd_printk(KERN_ERR "cs46xx: failed to re-create virtual PCM channel\n");
- up (&chip->spos_mutex);
return -ENXIO;
}
@@ -1065,6 +1065,8 @@ static int _cs46xx_adjust_sample_rate (cs46xx_t *chip, cs46xx_pcm_t *cpcm,
return 0;
}
+#endif
+
static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream,
snd_pcm_hw_params_t * hw_params)
{
@@ -1087,6 +1089,7 @@ static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream,
if (cpcm->pcm_channel->pcm_channel_id != DSP_IEC958_CHANNEL ||
!(chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_AC3_MODE)) {
if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) {
+ up (&chip->spos_mutex);
return -ENXIO;
}
}