diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-01 15:26:52 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-01 15:26:52 -0400 |
| commit | 3498d13b8090c0b0ef911409fbc503a7c4cca6ef (patch) | |
| tree | 254ca00276e863d9fba25707690c66b2a04c49e9 | |
| parent | def7cb8cd4e3258db88050eaaca5438bcc3dafca (diff) | |
| parent | 0c57dfcc6c1d037243c2f8fbf62eab3633326ec0 (diff) | |
Merge tag 'tty-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull TTY changes from Greg Kroah-Hartman:
"As we skipped the merge window for 3.6-rc1 for the tty tree,
everything is now settled down and working properly, so we are ready
for 3.7-rc1. Here's the patchset, it's big, but the large changes are
removing a firmware file and adding a staging tty driver (it depended
on the tty core changes, so it's going through this tree instead of
the staging tree.)
All of these patches have been in the linux-next tree for a while.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
Fix up more-or-less trivial conflicts in
- drivers/char/pcmcia/synclink_cs.c:
tty NULL dereference fix vs tty_port_cts_enabled() helper function
- drivers/staging/{Kconfig,Makefile}:
add-add conflict (dgrp driver added close to other staging drivers)
- drivers/staging/ipack/devices/ipoctal.c:
"split ipoctal_channel from iopctal" vs "TTY: use tty_port_register_device"
* tag 'tty-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (235 commits)
tty/serial: Add kgdb_nmi driver
tty/serial/amba-pl011: Quiesce interrupts in poll_get_char
tty/serial/amba-pl011: Implement poll_init callback
tty/serial/core: Introduce poll_init callback
kdb: Turn KGDB_KDB=n stubs into static inlines
kdb: Implement disable_nmi command
kernel/debug: Mask KGDB NMI upon entry
serial: pl011: handle corruption at high clock speeds
serial: sccnxp: Make 'default' choice in switch last
serial: sccnxp: Remove mask termios caps for SW flow control
serial: sccnxp: Report actual baudrate back to core
serial: samsung: Add poll_get_char & poll_put_char
Powerpc 8xx CPM_UART setting MAXIDL register proportionaly to baud rate
Powerpc 8xx CPM_UART maxidl should not depend on fifo size
Powerpc 8xx CPM_UART too many interrupts
Powerpc 8xx CPM_UART desynchronisation
serial: set correct baud_base for EXSYS EX-41092 Dual 16950
serial: omap: fix the reciever line error case
8250: blacklist Winbond CIR port
8250_pnp: do pnp probe before legacy probe
...
201 files changed, 18056 insertions, 8963 deletions
diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty index b138b663bf54..0c430150d929 100644 --- a/Documentation/ABI/testing/sysfs-tty +++ b/Documentation/ABI/testing/sysfs-tty | |||
| @@ -17,3 +17,12 @@ Description: | |||
| 17 | device, like 'tty1'. | 17 | device, like 'tty1'. |
| 18 | The file supports poll() to detect virtual | 18 | The file supports poll() to detect virtual |
| 19 | console switches. | 19 | console switches. |
| 20 | |||
| 21 | What: /sys/class/tty/ttyS0/uartclk | ||
| 22 | Date: Sep 2012 | ||
| 23 | Contact: Tomas Hlavacek <tmshlvck@gmail.com> | ||
| 24 | Description: | ||
| 25 | Shows the current uartclk value associated with the | ||
| 26 | UART port in serial_core, that is bound to TTY like ttyS0. | ||
| 27 | uartclk = 16 * baud_base | ||
| 28 | |||
diff --git a/Documentation/devicetree/bindings/tty/serial/nxp-lpc32xx-hsuart.txt b/Documentation/devicetree/bindings/tty/serial/nxp-lpc32xx-hsuart.txt new file mode 100644 index 000000000000..0d439dfc1aa5 --- /dev/null +++ b/Documentation/devicetree/bindings/tty/serial/nxp-lpc32xx-hsuart.txt | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | * NXP LPC32xx SoC High Speed UART | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: Should be "nxp,lpc3220-hsuart" | ||
| 5 | - reg: Should contain registers location and length | ||
| 6 | - interrupts: Should contain interrupt | ||
| 7 | |||
| 8 | Example: | ||
| 9 | |||
| 10 | uart1: serial@40014000 { | ||
| 11 | compatible = "nxp,lpc3220-hsuart"; | ||
| 12 | reg = <0x40014000 0x1000>; | ||
| 13 | interrupts = <26 0>; | ||
| 14 | }; | ||
diff --git a/Documentation/devicetree/bindings/tty/serial/of-serial.txt b/Documentation/devicetree/bindings/tty/serial/of-serial.txt index 0847fdeee11a..ba385f2e0ddc 100644 --- a/Documentation/devicetree/bindings/tty/serial/of-serial.txt +++ b/Documentation/devicetree/bindings/tty/serial/of-serial.txt | |||
| @@ -25,6 +25,8 @@ Optional properties: | |||
| 25 | accesses to the UART (e.g. TI davinci). | 25 | accesses to the UART (e.g. TI davinci). |
| 26 | - used-by-rtas : set to indicate that the port is in use by the OpenFirmware | 26 | - used-by-rtas : set to indicate that the port is in use by the OpenFirmware |
| 27 | RTAS and should not be registered. | 27 | RTAS and should not be registered. |
| 28 | - no-loopback-test: set to indicate that the port does not implements loopback | ||
| 29 | test mode | ||
| 28 | 30 | ||
| 29 | Example: | 31 | Example: |
| 30 | 32 | ||
diff --git a/Documentation/serial/00-INDEX b/Documentation/serial/00-INDEX index e09468ad3cb1..f7b0c7dc25ef 100644 --- a/Documentation/serial/00-INDEX +++ b/Documentation/serial/00-INDEX | |||
| @@ -2,8 +2,6 @@ | |||
| 2 | - this file. | 2 | - this file. |
| 3 | README.cycladesZ | 3 | README.cycladesZ |
| 4 | - info on Cyclades-Z firmware loading. | 4 | - info on Cyclades-Z firmware loading. |
| 5 | computone.txt | ||
| 6 | - info on Computone Intelliport II/Plus Multiport Serial Driver. | ||
| 7 | digiepca.txt | 5 | digiepca.txt |
| 8 | - info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards. | 6 | - info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards. |
| 9 | hayes-esp.txt | 7 | hayes-esp.txt |
diff --git a/Documentation/serial/computone.txt b/Documentation/serial/computone.txt deleted file mode 100644 index a6a1158ea2ba..000000000000 --- a/Documentation/serial/computone.txt +++ /dev/null | |||
| @@ -1,520 +0,0 @@ | |||
| 1 | NOTE: This is an unmaintained driver. It is not guaranteed to work due to | ||
| 2 | changes made in the tty layer in 2.6. If you wish to take over maintenance of | ||
| 3 | this driver, contact Michael Warfield <mhw@wittsend.com>. | ||
| 4 | |||
| 5 | Changelog: | ||
| 6 | ---------- | ||
| 7 | 11-01-2001: Original Document | ||
| 8 | |||
| 9 | 10-29-2004: Minor misspelling & format fix, update status of driver. | ||
| 10 | James Nelson <james4765@gmail.com> | ||
| 11 | |||
| 12 | Computone Intelliport II/Plus Multiport Serial Driver | ||
| 13 | ----------------------------------------------------- | ||
| 14 | |||
| 15 | Release Notes For Linux Kernel 2.2 and higher. | ||
| 16 | These notes are for the drivers which have already been integrated into the | ||
| 17 | kernel and have been tested on Linux kernels 2.0, 2.2, 2.3, and 2.4. | ||
| 18 | |||
| 19 | Version: 1.2.14 | ||
| 20 | Date: 11/01/2001 | ||
| 21 | Historical Author: Andrew Manison <amanison@america.net> | ||
| 22 | Primary Author: Doug McNash | ||
| 23 | |||
| 24 | This file assumes that you are using the Computone drivers which are | ||
| 25 | integrated into the kernel sources. For updating the drivers or installing | ||
| 26 | drivers into kernels which do not already have Computone drivers, please | ||
| 27 | refer to the instructions in the README.computone file in the driver patch. | ||
| 28 | |||
| 29 | |||
| 30 | 1. INTRODUCTION | ||
| 31 | |||
| 32 | This driver supports the entire family of Intelliport II/Plus controllers | ||
| 33 | with the exception of the MicroChannel controllers. It does not support | ||
| 34 | products previous to the Intelliport II. | ||
| 35 | |||
| 36 | This driver was developed on the v2.0.x Linux tree and has been tested up | ||
| 37 | to v2.4.14; it will probably not work with earlier v1.X kernels,. | ||
| 38 | |||
| 39 | |||
| 40 | 2. QUICK INSTALLATION | ||
| 41 | |||
| 42 | Hardware - If you have an ISA card, find a free interrupt and io port. | ||
| 43 | List those in use with `cat /proc/interrupts` and | ||
| 44 | `cat /proc/ioports`. Set the card dip switches to a free | ||
| 45 | address. You may need to configure your BIOS to reserve an | ||
| 46 | irq for an ISA card. PCI and EISA parameters are set | ||
| 47 | automagically. Insert card into computer with the power off | ||
| 48 | before or after drivers installation. | ||
| 49 | |||
| 50 | Note the hardware address from the Computone ISA cards installed into | ||
| 51 | the system. These are required for editing ip2.c or editing | ||
| 52 | /etc/modprobe.d/*.conf, or for specification on the modprobe | ||
| 53 | command line. | ||
| 54 | |||
| 55 | Note that the /etc/modules.conf should be used for older (pre-2.6) | ||
| 56 | kernels. | ||
| 57 | |||
| 58 | Software - | ||
| 59 | |||
| 60 | Module installation: | ||
| 61 | |||
| 62 | a) Determine free irq/address to use if any (configure BIOS if need be) | ||
| 63 | b) Run "make config" or "make menuconfig" or "make xconfig" | ||
| 64 | Select (m) module for CONFIG_COMPUTONE under character | ||
| 65 | devices. CONFIG_PCI and CONFIG_MODULES also may need to be set. | ||
| 66 | c) Set address on ISA cards then: | ||
| 67 | edit /usr/src/linux/drivers/char/ip2.c if needed | ||
| 68 | or | ||
| 69 | edit config file in /etc/modprobe.d/ if needed (module). | ||
| 70 | or both to match this setting. | ||
| 71 | d) Run "make modules" | ||
| 72 | e) Run "make modules_install" | ||
| 73 | f) Run "/sbin/depmod -a" | ||
| 74 | g) install driver using `modprobe ip2 <options>` (options listed below) | ||
| 75 | h) run ip2mkdev (either the script below or the binary version) | ||
| 76 | |||
| 77 | |||
| 78 | Kernel installation: | ||
| 79 | |||
| 80 | a) Determine free irq/address to use if any (configure BIOS if need be) | ||
| 81 | b) Run "make config" or "make menuconfig" or "make xconfig" | ||
| 82 | Select (y) kernel for CONFIG_COMPUTONE under character | ||
| 83 | devices. CONFIG_PCI may need to be set if you have PCI bus. | ||
| 84 | c) Set address on ISA cards then: | ||
| 85 | edit /usr/src/linux/drivers/char/ip2.c | ||
| 86 | (Optional - may be specified on kernel command line now) | ||
| 87 | d) Run "make zImage" or whatever target you prefer. | ||
| 88 | e) mv /usr/src/linux/arch/x86/boot/zImage to /boot. | ||
| 89 | f) Add new config for this kernel into /etc/lilo.conf, run "lilo" | ||
| 90 | or copy to a floppy disk and boot from that floppy disk. | ||
| 91 | g) Reboot using this kernel | ||
| 92 | h) run ip2mkdev (either the script below or the binary version) | ||
| 93 | |||
| 94 | Kernel command line options: | ||
| 95 | |||
| 96 | When compiling the driver into the kernel, io and irq may be | ||
| 97 | compiled into the driver by editing ip2.c and setting the values for | ||
| 98 | io and irq in the appropriate array. An alternative is to specify | ||
| 99 | a command line parameter to the kernel at boot up. | ||
| 100 | |||
| 101 | ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3 | ||
| 102 | |||
| 103 | Note that this order is very different from the specifications for the | ||
| 104 | modload parameters which have separate IRQ and IO specifiers. | ||
| 105 | |||
| 106 | The io port also selects PCI (1) and EISA (2) boards. | ||
| 107 | |||
| 108 | io=0 No board | ||
| 109 | io=1 PCI board | ||
| 110 | io=2 EISA board | ||
| 111 | else ISA board io address | ||
| 112 | |||
| 113 | You only need to specify the boards which are present. | ||
| 114 | |||
| 115 | Examples: | ||
| 116 | |||
| 117 | 2 PCI boards: | ||
| 118 | |||
| 119 | ip2=1,0,1,0 | ||
| 120 | |||
| 121 | 1 ISA board at 0x310 irq 5: | ||
| 122 | |||
| 123 | ip2=0x310,5 | ||
| 124 | |||
| 125 | This can be added to and "append" option in lilo.conf similar to this: | ||
| 126 | |||
| 127 | append="ip2=1,0,1,0" | ||
| 128 | |||
| 129 | |||
| 130 | 3. INSTALLATION | ||
| 131 | |||
| 132 | Previously, the driver sources were packaged with a set of patch files | ||
| 133 | to update the character drivers' makefile and configuration file, and other | ||
| 134 | kernel source files. A build script (ip2build) was included which applies | ||
| 135 | the patches if needed, and build any utilities needed. | ||
| 136 | What you receive may be a single patch file in conventional kernel | ||
| 137 | patch format build script. That form can also be applied by | ||
| 138 | running patch -p1 < ThePatchFile. Otherwise run ip2build. | ||
| 139 | |||
| 140 | The driver can be installed as a module (recommended) or built into the | ||
| 141 | kernel. This is selected as for other drivers through the `make config` | ||
| 142 | command from the root of the Linux source tree. If the driver is built | ||
| 143 | into the kernel you will need to edit the file ip2.c to match the boards | ||
| 144 | you are installing. See that file for instructions. If the driver is | ||
| 145 | installed as a module the configuration can also be specified on the | ||
| 146 | modprobe command line as follows: | ||
| 147 | |||
| 148 | modprobe ip2 irq=irq1,irq2,irq3,irq4 io=addr1,addr2,addr3,addr4 | ||
| 149 | |||
| 150 | where irqnum is one of the valid Intelliport II interrupts (3,4,5,7,10,11, | ||
| 151 | 12,15) and addr1-4 are the base addresses for up to four controllers. If | ||
| 152 | the irqs are not specified the driver uses the default in ip2.c (which | ||
| 153 | selects polled mode). If no base addresses are specified the defaults in | ||
| 154 | ip2.c are used. If you are autoloading the driver module with kerneld or | ||
| 155 | kmod the base addresses and interrupt number must also be set in ip2.c | ||
| 156 | and recompile or just insert and options line in /etc/modprobe.d/*.conf or both. | ||
| 157 | The options line is equivalent to the command line and takes precedence over | ||
| 158 | what is in ip2.c. | ||
| 159 | |||
| 160 | config sample to put /etc/modprobe.d/*.conf: | ||
| 161 | options ip2 io=1,0x328 irq=1,10 | ||
| 162 | alias char-major-71 ip2 | ||
| 163 | alias char-major-72 ip2 | ||
| 164 | alias char-major-73 ip2 | ||
| 165 | |||
| 166 | The equivalent in ip2.c: | ||
| 167 | |||
| 168 | static int io[IP2_MAX_BOARDS]= { 1, 0x328, 0, 0 }; | ||
| 169 | static int irq[IP2_MAX_BOARDS] = { 1, 10, -1, -1 }; | ||
| 170 | |||
| 171 | The equivalent for the kernel command line (in lilo.conf): | ||
| 172 | |||
| 173 | append="ip2=1,1,0x328,10" | ||
| 174 | |||
| 175 | |||
| 176 | Note: Both io and irq should be updated to reflect YOUR system. An "io" | ||
| 177 | address of 1 or 2 indicates a PCI or EISA card in the board table. | ||
| 178 | The PCI or EISA irq will be assigned automatically. | ||
| 179 | |||
| 180 | Specifying an invalid or in-use irq will default the driver into | ||
| 181 | running in polled mode for that card. If all irq entries are 0 then | ||
| 182 | all cards will operate in polled mode. | ||
| 183 | |||
| 184 | If you select the driver as part of the kernel run : | ||
| 185 | |||
| 186 | make zlilo (or whatever you do to create a bootable kernel) | ||
| 187 | |||
| 188 | If you selected a module run : | ||
| 189 | |||
| 190 | make modules && make modules_install | ||
| 191 | |||
| 192 | The utility ip2mkdev (see 5 and 7 below) creates all the device nodes | ||
| 193 | required by the driver. For a device to be created it must be configured | ||
| 194 | in the driver and the board must be installed. Only devices corresponding | ||
| 195 | to real IntelliPort II ports are created. With multiple boards and expansion | ||
| 196 | boxes this will leave gaps in the sequence of device names. ip2mkdev uses | ||
| 197 | Linux tty naming conventions: ttyF0 - ttyF255 for normal devices, and | ||
| 198 | cuf0 - cuf255 for callout devices. | ||
| 199 | |||
| 200 | |||
| 201 | 4. USING THE DRIVERS | ||
| 202 | |||
| 203 | As noted above, the driver implements the ports in accordance with Linux | ||
| 204 | conventions, and the devices should be interchangeable with the standard | ||
| 205 | serial devices. (This is a key point for problem reporting: please make | ||
| 206 | sure that what you are trying do works on the ttySx/cuax ports first; then | ||
| 207 | tell us what went wrong with the ip2 ports!) | ||
| 208 | |||
| 209 | Higher speeds can be obtained using the setserial utility which remaps | ||
| 210 | 38,400 bps (extb) to 57,600 bps, 115,200 bps, or a custom speed. | ||
| 211 | Intelliport II installations using the PowerPort expansion module can | ||
| 212 | use the custom speed setting to select the highest speeds: 153,600 bps, | ||
| 213 | 230,400 bps, 307,200 bps, 460,800bps and 921,600 bps. The base for | ||
| 214 | custom baud rate configuration is fixed at 921,600 for cards/expansion | ||
| 215 | modules with ST654's and 115200 for those with Cirrus CD1400's. This | ||
| 216 | corresponds to the maximum bit rates those chips are capable. | ||
| 217 | For example if the baud base is 921600 and the baud divisor is 18 then | ||
| 218 | the custom rate is 921600/18 = 51200 bps. See the setserial man page for | ||
| 219 | complete details. Of course if stty accepts the higher rates now you can | ||
| 220 | use that as well as the standard ioctls(). | ||
| 221 | |||
| 222 | |||
| 223 | 5. ip2mkdev and assorted utilities... | ||
| 224 | |||
| 225 | Several utilities, including the source for a binary ip2mkdev utility are | ||
| 226 | available under .../drivers/char/ip2. These can be build by changing to | ||
| 227 | that directory and typing "make" after the kernel has be built. If you do | ||
| 228 | not wish to compile the binary utilities, the shell script below can be | ||
| 229 | cut out and run as "ip2mkdev" to create the necessary device files. To | ||
| 230 | use the ip2mkdev script, you must have procfs enabled and the proc file | ||
| 231 | system mounted on /proc. | ||
| 232 | |||
| 233 | |||
| 234 | 6. NOTES | ||
| 235 | |||
| 236 | This is a release version of the driver, but it is impossible to test it | ||
| 237 | in all configurations of Linux. If there is any anomalous behaviour that | ||
| 238 | does not match the standard serial port's behaviour please let us know. | ||
| 239 | |||
| 240 | |||
| 241 | 7. ip2mkdev shell script | ||
| 242 | |||
| 243 | Previously, this script was simply attached here. It is now attached as a | ||
| 244 | shar archive to make it easier to extract the script from the documentation. | ||
| 245 | To create the ip2mkdev shell script change to a convenient directory (/tmp | ||
| 246 | works just fine) and run the following command: | ||
| 247 | |||
| 248 | unshar Documentation/serial/computone.txt | ||
| 249 | (This file) | ||
| 250 | |||
| 251 | You should now have a file ip2mkdev in your current working directory with | ||
| 252 | permissions set to execute. Running that script with then create the | ||
| 253 | necessary devices for the Computone boards, interfaces, and ports which | ||
| 254 | are present on you system at the time it is run. | ||
| 255 | |||
| 256 | |||
| 257 | #!/bin/sh | ||
| 258 | # This is a shell archive (produced by GNU sharutils 4.2.1). | ||
| 259 | # To extract the files from this archive, save it to some FILE, remove | ||
| 260 | # everything before the `!/bin/sh' line above, then type `sh FILE'. | ||
| 261 | # | ||
| 262 | # Made on 2001-10-29 10:32 EST by <mhw@alcove.wittsend.com>. | ||
| 263 | # Source directory was `/home2/src/tmp'. | ||
| 264 | # | ||
| 265 | # Existing files will *not* be overwritten unless `-c' is specified. | ||
| 266 | # | ||
| 267 | # This shar contains: | ||
| 268 | # length mode name | ||
| 269 | # ------ ---------- ------------------------------------------ | ||
| 270 | # 4251 -rwxr-xr-x ip2mkdev | ||
| 271 | # | ||
| 272 | save_IFS="${IFS}" | ||
| 273 | IFS="${IFS}:" | ||
| 274 | gettext_dir=FAILED | ||
| 275 | locale_dir=FAILED | ||
| 276 | first_param="$1" | ||
| 277 | for dir in $PATH | ||
| 278 | do | ||
| 279 | if test "$gettext_dir" = FAILED && test -f $dir/gettext \ | ||
| 280 | && ($dir/gettext --version >/dev/null 2>&1) | ||
| 281 | then | ||
| 282 | set `$dir/gettext --version 2>&1` | ||
| 283 | if test "$3" = GNU | ||
| 284 | then | ||
| 285 | gettext_dir=$dir | ||
| 286 | fi | ||
| 287 | fi | ||
| 288 | if test "$locale_dir" = FAILED && test -f $dir/shar \ | ||
| 289 | && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) | ||
| 290 | then | ||
| 291 | locale_dir=`$dir/shar --print-text-domain-dir` | ||
| 292 | fi | ||
| 293 | done | ||
| 294 | IFS="$save_IFS" | ||
| 295 | if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED | ||
| 296 | then | ||
| 297 | echo=echo | ||
| 298 | else | ||
| 299 | TEXTDOMAINDIR=$locale_dir | ||
| 300 | export TEXTDOMAINDIR | ||
| 301 | TEXTDOMAIN=sharutils | ||
| 302 | export TEXTDOMAIN | ||
| 303 | echo="$gettext_dir/gettext -s" | ||
| 304 | fi | ||
| 305 | if touch -am -t 200112312359.59 $$.touch >/dev/null 2>&1 && test ! -f 200112312359.59 -a -f $$.touch; then | ||
| 306 | shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"' | ||
| 307 | elif touch -am 123123592001.59 $$.touch >/dev/null 2>&1 && test ! -f 123123592001.59 -a ! -f 123123592001.5 -a -f $$.touch; then | ||
| 308 | shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"' | ||
| 309 | elif touch -am 1231235901 $$.touch >/dev/null 2>&1 && test ! -f 1231235901 -a -f $$.touch; then | ||
| 310 | shar_touch='touch -am $3$4$5$6$2 "$8"' | ||
| 311 | else | ||
| 312 | shar_touch=: | ||
| 313 | echo | ||
| 314 | $echo 'WARNING: not restoring timestamps. Consider getting and' | ||
| 315 | $echo "installing GNU \`touch', distributed in GNU File Utilities..." | ||
| 316 | echo | ||
| 317 | fi | ||
| 318 | rm -f 200112312359.59 123123592001.59 123123592001.5 1231235901 $$.touch | ||
| 319 | # | ||
| 320 | if mkdir _sh17581; then | ||
| 321 | $echo 'x -' 'creating lock directory' | ||
| 322 | else | ||
| 323 | $echo 'failed to create lock directory' | ||
| 324 | exit 1 | ||
| 325 | fi | ||
| 326 | # ============= ip2mkdev ============== | ||
| 327 | if test -f 'ip2mkdev' && test "$first_param" != -c; then | ||
| 328 | $echo 'x -' SKIPPING 'ip2mkdev' '(file already exists)' | ||
| 329 | else | ||
| 330 | $echo 'x -' extracting 'ip2mkdev' '(text)' | ||
| 331 | sed 's/^X//' << 'SHAR_EOF' > 'ip2mkdev' && | ||
| 332 | #!/bin/sh - | ||
| 333 | # | ||
| 334 | # ip2mkdev | ||
| 335 | # | ||
| 336 | # Make or remove devices as needed for Computone Intelliport drivers | ||
| 337 | # | ||
| 338 | # First rule! If the dev file exists and you need it, don't mess | ||
| 339 | # with it. That prevents us from screwing up open ttys, ownership | ||
| 340 | # and permissions on a running system! | ||
| 341 | # | ||
| 342 | # This script will NOT remove devices that no longer exist if their | ||
| 343 | # board or interface box has been removed. If you want to get rid | ||
| 344 | # of them, you can manually do an "rm -f /dev/ttyF* /dev/cuaf*" | ||
| 345 | # before running this script. Running this script will then recreate | ||
| 346 | # all the valid devices. | ||
| 347 | # | ||
| 348 | # Michael H. Warfield | ||
| 349 | # /\/\|=mhw=|\/\/ | ||
| 350 | # mhw@wittsend.com | ||
| 351 | # | ||
| 352 | # Updated 10/29/2000 for version 1.2.13 naming convention | ||
| 353 | # under devfs. /\/\|=mhw=|\/\/ | ||
| 354 | # | ||
| 355 | # Updated 03/09/2000 for devfs support in ip2 drivers. /\/\|=mhw=|\/\/ | ||
| 356 | # | ||
| 357 | X | ||
| 358 | if test -d /dev/ip2 ; then | ||
| 359 | # This is devfs mode... We don't do anything except create symlinks | ||
| 360 | # from the real devices to the old names! | ||
| 361 | X cd /dev | ||
| 362 | X echo "Creating symbolic links to devfs devices" | ||
| 363 | X for i in `ls ip2` ; do | ||
| 364 | X if test ! -L ip2$i ; then | ||
| 365 | X # Remove it incase it wasn't a symlink (old device) | ||
| 366 | X rm -f ip2$i | ||
| 367 | X ln -s ip2/$i ip2$i | ||
| 368 | X fi | ||
| 369 | X done | ||
| 370 | X for i in `( cd tts ; ls F* )` ; do | ||
| 371 | X if test ! -L tty$i ; then | ||
| 372 | X # Remove it incase it wasn't a symlink (old device) | ||
| 373 | X rm -f tty$i | ||
| 374 | X ln -s tts/$i tty$i | ||
| 375 | X fi | ||
| 376 | X done | ||
| 377 | X for i in `( cd cua ; ls F* )` ; do | ||
| 378 | X DEVNUMBER=`expr $i : 'F\(.*\)'` | ||
| 379 | X if test ! -L cuf$DEVNUMBER ; then | ||
| 380 | X # Remove it incase it wasn't a symlink (old device) | ||
| 381 | X rm -f cuf$DEVNUMBER | ||
| 382 | X ln -s cua/$i cuf$DEVNUMBER | ||
| 383 | X fi | ||
| 384 | X done | ||
| 385 | X exit 0 | ||
| 386 | fi | ||
| 387 | X | ||
| 388 | if test ! -f /proc/tty/drivers | ||
| 389 | then | ||
| 390 | X echo "\ | ||
| 391 | Unable to check driver status. | ||
| 392 | Make sure proc file system is mounted." | ||
| 393 | X | ||
| 394 | X exit 255 | ||
| 395 | fi | ||
| 396 | X | ||
| 397 | if test ! -f /proc/tty/driver/ip2 | ||
| 398 | then | ||
| 399 | X echo "\ | ||
| 400 | Unable to locate ip2 proc file. | ||
| 401 | Attempting to load driver" | ||
| 402 | X | ||
| 403 | X if /sbin/insmod ip2 | ||
| 404 | X then | ||
| 405 | X if test ! -f /proc/tty/driver/ip2 | ||
| 406 | X then | ||
| 407 | X echo "\ | ||
| 408 | Unable to locate ip2 proc file after loading driver. | ||
| 409 | Driver initialization failure or driver version error. | ||
| 410 | " | ||
| 411 | X exit 255 | ||
| 412 | X fi | ||
| 413 | X else | ||
| 414 | X echo "Unable to load ip2 driver." | ||
| 415 | X exit 255 | ||
| 416 | X fi | ||
| 417 | fi | ||
| 418 | X | ||
| 419 | # Ok... So we got the driver loaded and we can locate the procfs files. | ||
| 420 | # Next we need our major numbers. | ||
| 421 | X | ||
| 422 | TTYMAJOR=`sed -e '/^ip2/!d' -e '/\/dev\/tt/!d' -e 's/.*tt[^ ]*[ ]*\([0-9]*\)[ ]*.*/\1/' < /proc/tty/drivers` | ||
| 423 | CUAMAJOR=`sed -e '/^ip2/!d' -e '/\/dev\/cu/!d' -e 's/.*cu[^ ]*[ ]*\([0-9]*\)[ ]*.*/\1/' < /proc/tty/drivers` | ||
| 424 | BRDMAJOR=`sed -e '/^Driver: /!d' -e 's/.*IMajor=\([0-9]*\)[ ]*.*/\1/' < /proc/tty/driver/ip2` | ||
| 425 | X | ||
| 426 | echo "\ | ||
| 427 | TTYMAJOR = $TTYMAJOR | ||
| 428 | CUAMAJOR = $CUAMAJOR | ||
| 429 | BRDMAJOR = $BRDMAJOR | ||
| 430 | " | ||
| 431 | X | ||
| 432 | # Ok... Now we should know our major numbers, if appropriate... | ||
| 433 | # Now we need our boards and start the device loops. | ||
| 434 | X | ||
| 435 | grep '^Board [0-9]:' /proc/tty/driver/ip2 | while read token number type alltherest | ||
| 436 | do | ||
| 437 | X # The test for blank "type" will catch the stats lead-in lines | ||
| 438 | X # if they exist in the file | ||
| 439 | X if test "$type" = "vacant" -o "$type" = "Vacant" -o "$type" = "" | ||
| 440 | X then | ||
| 441 | X continue | ||
| 442 | X fi | ||
| 443 | X | ||
| 444 | X BOARDNO=`expr "$number" : '\([0-9]\):'` | ||
| 445 | X PORTS=`expr "$alltherest" : '.*ports=\([0-9]*\)' | tr ',' ' '` | ||
| 446 | X MINORS=`expr "$alltherest" : '.*minors=\([0-9,]*\)' | tr ',' ' '` | ||
| 447 | X | ||
| 448 | X if test "$BOARDNO" = "" -o "$PORTS" = "" | ||
| 449 | X then | ||
| 450 | # This may be a bug. We should at least get this much information | ||
| 451 | X echo "Unable to process board line" | ||
| 452 | X continue | ||
| 453 | X fi | ||
| 454 | X | ||
| 455 | X if test "$MINORS" = "" | ||
| 456 | X then | ||
| 457 | # Silently skip this one. This board seems to have no boxes | ||
| 458 | X continue | ||
| 459 | X fi | ||
| 460 | X | ||
| 461 | X echo "board $BOARDNO: $type ports = $PORTS; port numbers = $MINORS" | ||
| 462 | X | ||
| 463 | X if test "$BRDMAJOR" != "" | ||
| 464 | X then | ||
| 465 | X BRDMINOR=`expr $BOARDNO \* 4` | ||
| 466 | X STSMINOR=`expr $BRDMINOR + 1` | ||
| 467 | X if test ! -c /dev/ip2ipl$BOARDNO ; then | ||
| 468 | X mknod /dev/ip2ipl$BOARDNO c $BRDMAJOR $BRDMINOR | ||
| 469 | X fi | ||
| 470 | X if test ! -c /dev/ip2stat$BOARDNO ; then | ||
| 471 | X mknod /dev/ip2stat$BOARDNO c $BRDMAJOR $STSMINOR | ||
| 472 | X fi | ||
| 473 | X fi | ||
| 474 | X | ||
| 475 | X if test "$TTYMAJOR" != "" | ||
| 476 | X then | ||
| 477 | X PORTNO=$BOARDBASE | ||
| 478 | X | ||
| 479 | X for PORTNO in $MINORS | ||
| 480 | X do | ||
| 481 | X if test ! -c /dev/ttyF$PORTNO ; then | ||
| 482 | X # We got the hardware but no device - make it | ||
| 483 | X mknod /dev/ttyF$PORTNO c $TTYMAJOR $PORTNO | ||
| 484 | X fi | ||
| 485 | X done | ||
| 486 | X fi | ||
| 487 | X | ||
| 488 | X if test "$CUAMAJOR" != "" | ||
| 489 | X then | ||
| 490 | X PORTNO=$BOARDBASE | ||
| 491 | X | ||
| 492 | X for PORTNO in $MINORS | ||
| 493 | X do | ||
| 494 | X if test ! -c /dev/cuf$PORTNO ; then | ||
| 495 | X # We got the hardware but no device - make it | ||
| 496 | X mknod /dev/cuf$PORTNO c $CUAMAJOR $PORTNO | ||
| 497 | X fi | ||
| 498 | X done | ||
| 499 | X fi | ||
| 500 | done | ||
| 501 | X | ||
| 502 | Xexit 0 | ||
| 503 | SHAR_EOF | ||
| 504 | (set 20 01 10 29 10 32 01 'ip2mkdev'; eval "$shar_touch") && | ||
| 505 | chmod 0755 'ip2mkdev' || | ||
| 506 | $echo 'restore of' 'ip2mkdev' 'failed' | ||
| 507 | if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ | ||
| 508 | && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then | ||
| 509 | md5sum -c << SHAR_EOF >/dev/null 2>&1 \ | ||
| 510 | || $echo 'ip2mkdev:' 'MD5 check failed' | ||
| 511 | cb5717134509f38bad9fde6b1f79b4a4 ip2mkdev | ||
| 512 | SHAR_EOF | ||
| 513 | else | ||
| 514 | shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ip2mkdev'`" | ||
| 515 | test 4251 -eq "$shar_count" || | ||
| 516 | $echo 'ip2mkdev:' 'original size' '4251,' 'current size' "$shar_count!" | ||
| 517 | fi | ||
| 518 | fi | ||
| 519 | rm -fr _sh17581 | ||
| 520 | exit 0 | ||
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index 3ea809430eda..5d5865204a1d 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c | |||
| @@ -223,6 +223,7 @@ srmcons_init(void) | |||
| 223 | driver->subtype = SYSTEM_TYPE_SYSCONS; | 223 | driver->subtype = SYSTEM_TYPE_SYSCONS; |
| 224 | driver->init_termios = tty_std_termios; | 224 | driver->init_termios = tty_std_termios; |
| 225 | tty_set_operations(driver, &srmcons_ops); | 225 | tty_set_operations(driver, &srmcons_ops); |
| 226 | tty_port_link_device(&srmcons_singleton.port, driver, 0); | ||
| 226 | err = tty_register_driver(driver); | 227 | err = tty_register_driver(driver); |
| 227 | if (err) { | 228 | if (err) { |
| 228 | put_tty_driver(driver); | 229 | put_tty_driver(driver); |
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index c1b93c752d70..9e80d209d138 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
| @@ -81,8 +81,9 @@ static struct omap_uart_port_info omap_serial_default_info[] __initdata = { | |||
| 81 | }; | 81 | }; |
| 82 | 82 | ||
| 83 | #ifdef CONFIG_PM | 83 | #ifdef CONFIG_PM |
| 84 | static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) | 84 | static void omap_uart_enable_wakeup(struct device *dev, bool enable) |
| 85 | { | 85 | { |
| 86 | struct platform_device *pdev = to_platform_device(dev); | ||
| 86 | struct omap_device *od = to_omap_device(pdev); | 87 | struct omap_device *od = to_omap_device(pdev); |
| 87 | 88 | ||
| 88 | if (!od) | 89 | if (!od) |
| @@ -99,15 +100,17 @@ static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) | |||
| 99 | * in Smartidle Mode When Configured for DMA Operations. | 100 | * in Smartidle Mode When Configured for DMA Operations. |
| 100 | * WA: configure uart in force idle mode. | 101 | * WA: configure uart in force idle mode. |
| 101 | */ | 102 | */ |
| 102 | static void omap_uart_set_noidle(struct platform_device *pdev) | 103 | static void omap_uart_set_noidle(struct device *dev) |
| 103 | { | 104 | { |
| 105 | struct platform_device *pdev = to_platform_device(dev); | ||
| 104 | struct omap_device *od = to_omap_device(pdev); | 106 | struct omap_device *od = to_omap_device(pdev); |
| 105 | 107 | ||
| 106 | omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO); | 108 | omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO); |
| 107 | } | 109 | } |
| 108 | 110 | ||
| 109 | static void omap_uart_set_smartidle(struct platform_device *pdev) | 111 | static void omap_uart_set_smartidle(struct device *dev) |
| 110 | { | 112 | { |
| 113 | struct platform_device *pdev = to_platform_device(dev); | ||
| 111 | struct omap_device *od = to_omap_device(pdev); | 114 | struct omap_device *od = to_omap_device(pdev); |
| 112 | u8 idlemode; | 115 | u8 idlemode; |
| 113 | 116 | ||
| @@ -120,10 +123,10 @@ static void omap_uart_set_smartidle(struct platform_device *pdev) | |||
| 120 | } | 123 | } |
| 121 | 124 | ||
| 122 | #else | 125 | #else |
| 123 | static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) | 126 | static void omap_uart_enable_wakeup(struct device *dev, bool enable) |
| 124 | {} | 127 | {} |
| 125 | static void omap_uart_set_noidle(struct platform_device *pdev) {} | 128 | static void omap_uart_set_noidle(struct device *dev) {} |
| 126 | static void omap_uart_set_smartidle(struct platform_device *pdev) {} | 129 | static void omap_uart_set_smartidle(struct device *dev) {} |
| 127 | #endif /* CONFIG_PM */ | 130 | #endif /* CONFIG_PM */ |
| 128 | 131 | ||
| 129 | #ifdef CONFIG_OMAP_MUX | 132 | #ifdef CONFIG_OMAP_MUX |
| @@ -304,6 +307,9 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, | |||
| 304 | omap_up.dma_rx_timeout = info->dma_rx_timeout; | 307 | omap_up.dma_rx_timeout = info->dma_rx_timeout; |
| 305 | omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate; | 308 | omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate; |
| 306 | omap_up.autosuspend_timeout = info->autosuspend_timeout; | 309 | omap_up.autosuspend_timeout = info->autosuspend_timeout; |
| 310 | omap_up.DTR_gpio = info->DTR_gpio; | ||
| 311 | omap_up.DTR_inverted = info->DTR_inverted; | ||
| 312 | omap_up.DTR_present = info->DTR_present; | ||
| 307 | 313 | ||
| 308 | pdata = &omap_up; | 314 | pdata = &omap_up; |
| 309 | pdata_size = sizeof(struct omap_uart_port_info); | 315 | pdata_size = sizeof(struct omap_uart_port_info); |
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index a534d8880de1..1d2e3c6f8b59 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c | |||
| @@ -524,33 +524,12 @@ static struct stedma40_chan_cfg uart2_dma_cfg_tx = { | |||
| 524 | }; | 524 | }; |
| 525 | #endif | 525 | #endif |
| 526 | 526 | ||
| 527 | #define PRCC_K_SOFTRST_SET 0x18 | ||
| 528 | #define PRCC_K_SOFTRST_CLEAR 0x1C | ||
| 529 | static void ux500_uart0_reset(void) | ||
| 530 | { | ||
| 531 | void __iomem *prcc_rst_set, *prcc_rst_clr; | ||
| 532 | |||
| 533 | prcc_rst_set = (void __iomem *)IO_ADDRESS(U8500_CLKRST1_BASE + | ||
| 534 | PRCC_K_SOFTRST_SET); | ||
| 535 | prcc_rst_clr = (void __iomem *)IO_ADDRESS(U8500_CLKRST1_BASE + | ||
| 536 | PRCC_K_SOFTRST_CLEAR); | ||
| 537 | |||
| 538 | /* Activate soft reset PRCC_K_SOFTRST_CLEAR */ | ||
| 539 | writel((readl(prcc_rst_clr) | 0x1), prcc_rst_clr); | ||
| 540 | udelay(1); | ||
| 541 | |||
| 542 | /* Release soft reset PRCC_K_SOFTRST_SET */ | ||
| 543 | writel((readl(prcc_rst_set) | 0x1), prcc_rst_set); | ||
| 544 | udelay(1); | ||
| 545 | } | ||
| 546 | |||
| 547 | static struct amba_pl011_data uart0_plat = { | 527 | static struct amba_pl011_data uart0_plat = { |
| 548 | #ifdef CONFIG_STE_DMA40 | 528 | #ifdef CONFIG_STE_DMA40 |
| 549 | .dma_filter = stedma40_filter, | 529 | .dma_filter = stedma40_filter, |
| 550 | .dma_rx_param = &uart0_dma_cfg_rx, | 530 | .dma_rx_param = &uart0_dma_cfg_rx, |
| 551 | .dma_tx_param = &uart0_dma_cfg_tx, | 531 | .dma_tx_param = &uart0_dma_cfg_tx, |
| 552 | #endif | 532 | #endif |
| 553 | .reset = ux500_uart0_reset, | ||
| 554 | }; | 533 | }; |
| 555 | 534 | ||
| 556 | static struct amba_pl011_data uart1_plat = { | 535 | static struct amba_pl011_data uart1_plat = { |
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 1a52725ffcf2..a531149823bb 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | #define __OMAP_SERIAL_H__ | 18 | #define __OMAP_SERIAL_H__ |
| 19 | 19 | ||
| 20 | #include <linux/serial_core.h> | 20 | #include <linux/serial_core.h> |
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/device.h> |
| 22 | #include <linux/pm_qos.h> | 22 | #include <linux/pm_qos.h> |
| 23 | 23 | ||
| 24 | #include <plat/mux.h> | 24 | #include <plat/mux.h> |
| @@ -42,10 +42,10 @@ | |||
| 42 | #define OMAP_UART_WER_MOD_WKUP 0X7F | 42 | #define OMAP_UART_WER_MOD_WKUP 0X7F |
| 43 | 43 | ||
| 44 | /* Enable XON/XOFF flow control on output */ | 44 | /* Enable XON/XOFF flow control on output */ |
| 45 | #define OMAP_UART_SW_TX 0x04 | 45 | #define OMAP_UART_SW_TX 0x8 |
| 46 | 46 | ||
| 47 | /* Enable XON/XOFF flow control on input */ | 47 | /* Enable XON/XOFF flow control on input */ |
| 48 | #define OMAP_UART_SW_RX 0x04 | 48 | #define OMAP_UART_SW_RX 0x2 |
| 49 | 49 | ||
| 50 | #define OMAP_UART_SYSC_RESET 0X07 | 50 | #define OMAP_UART_SYSC_RESET 0X07 |
| 51 | #define OMAP_UART_TCR_TRIG 0X0F | 51 | #define OMAP_UART_TCR_TRIG 0X0F |
| @@ -69,11 +69,14 @@ struct omap_uart_port_info { | |||
| 69 | unsigned int dma_rx_timeout; | 69 | unsigned int dma_rx_timeout; |
| 70 | unsigned int autosuspend_timeout; | 70 | unsigned int autosuspend_timeout; |
| 71 | unsigned int dma_rx_poll_rate; | 71 | unsigned int dma_rx_poll_rate; |
| 72 | int DTR_gpio; | ||
| 73 | int DTR_inverted; | ||
| 74 | int DTR_present; | ||
| 72 | 75 | ||
| 73 | int (*get_context_loss_count)(struct device *); | 76 | int (*get_context_loss_count)(struct device *); |
| 74 | void (*set_forceidle)(struct platform_device *); | 77 | void (*set_forceidle)(struct device *); |
| 75 | void (*set_noidle)(struct platform_device *); | 78 | void (*set_noidle)(struct device *); |
| 76 | void (*enable_wakeup)(struct platform_device *, bool); | 79 | void (*enable_wakeup)(struct device *, bool); |
| 77 | }; | 80 | }; |
| 78 | 81 | ||
| 79 | struct uart_omap_dma { | 82 | struct uart_omap_dma { |
| @@ -102,39 +105,4 @@ struct uart_omap_dma { | |||
| 102 | unsigned int rx_timeout; | 105 | unsigned int rx_timeout; |
| 103 | }; | 106 | }; |
| 104 | 107 | ||
| 105 | struct uart_omap_port { | ||
| 106 | struct uart_port port; | ||
| 107 | struct uart_omap_dma uart_dma; | ||
| 108 | struct platform_device *pdev; | ||
| 109 | |||
| 110 | unsigned char ier; | ||
| 111 | unsigned char lcr; | ||
| 112 | unsigned char mcr; | ||
| 113 | unsigned char fcr; | ||
| 114 | unsigned char efr; | ||
| 115 | unsigned char dll; | ||
| 116 | unsigned char dlh; | ||
| 117 | unsigned char mdr1; | ||
| 118 | unsigned char scr; | ||
| 119 | |||
| 120 | int use_dma; | ||
| 121 | /* | ||
| 122 | * Some bits in registers are cleared on a read, so they must | ||
| 123 | * be saved whenever the register is read but the bits will not | ||
| 124 | * be immediately processed. | ||
| 125 | */ | ||
| 126 | unsigned int lsr_break_flag; | ||
| 127 | unsigned char msr_saved_flags; | ||
| 128 | char name[20]; | ||
| 129 | unsigned long port_activity; | ||
| 130 | u32 context_loss_cnt; | ||
| 131 | u32 errata; | ||
| 132 | u8 wakeups_enabled; | ||
| 133 | |||
| 134 | struct pm_qos_request pm_qos_request; | ||
| 135 | u32 latency; | ||
| 136 | u32 calc_latency; | ||
| 137 | struct work_struct qos_work; | ||
| 138 | }; | ||
| 139 | |||
| 140 | #endif /* __OMAP_SERIAL_H__ */ | 108 | #endif /* __OMAP_SERIAL_H__ */ |
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index c34785dca92b..ec536e4e36c9 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c | |||
| @@ -338,7 +338,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 338 | { | 338 | { |
| 339 | /* Handle turning off CRTSCTS */ | 339 | /* Handle turning off CRTSCTS */ |
| 340 | if ((old_termios->c_cflag & CRTSCTS) && | 340 | if ((old_termios->c_cflag & CRTSCTS) && |
| 341 | !(tty->termios->c_cflag & CRTSCTS)) { | 341 | !(tty->termios.c_cflag & CRTSCTS)) { |
| 342 | tty->hw_stopped = 0; | 342 | tty->hw_stopped = 0; |
| 343 | } | 343 | } |
| 344 | } | 344 | } |
| @@ -545,6 +545,7 @@ static int __init simrs_init(void) | |||
| 545 | /* the port is imaginary */ | 545 | /* the port is imaginary */ |
| 546 | printk(KERN_INFO "ttyS0 at 0x03f8 (irq = %d) is a 16550\n", state->irq); | 546 | printk(KERN_INFO "ttyS0 at 0x03f8 (irq = %d) is a 16550\n", state->irq); |
| 547 | 547 | ||
| 548 | tty_port_link_device(&state->port, hp_simserial_driver, 0); | ||
| 548 | retval = tty_register_driver(hp_simserial_driver); | 549 | retval = tty_register_driver(hp_simserial_driver); |
| 549 | if (retval) { | 550 | if (retval) { |
| 550 | printk(KERN_ERR "Couldn't register simserial driver\n"); | 551 | printk(KERN_ERR "Couldn't register simserial driver\n"); |
diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c index 8db25e806947..16d170f53bfd 100644 --- a/arch/m68k/emu/nfcon.c +++ b/arch/m68k/emu/nfcon.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <asm/natfeat.h> | 19 | #include <asm/natfeat.h> |
| 20 | 20 | ||
| 21 | static int stderr_id; | 21 | static int stderr_id; |
| 22 | static struct tty_port nfcon_tty_port; | ||
| 22 | static struct tty_driver *nfcon_tty_driver; | 23 | static struct tty_driver *nfcon_tty_driver; |
| 23 | 24 | ||
| 24 | static void nfputs(const char *str, unsigned int count) | 25 | static void nfputs(const char *str, unsigned int count) |
| @@ -119,6 +120,8 @@ static int __init nfcon_init(void) | |||
| 119 | { | 120 | { |
| 120 | int res; | 121 | int res; |
| 121 | 122 | ||
| 123 | tty_port_init(&nfcon_tty_port); | ||
| 124 | |||
| 122 | stderr_id = nf_get_id("NF_STDERR"); | 125 | stderr_id = nf_get_id("NF_STDERR"); |
| 123 | if (!stderr_id) | 126 | if (!stderr_id) |
| 124 | return -ENODEV; | 127 | return -ENODEV; |
| @@ -135,6 +138,7 @@ static int __init nfcon_init(void) | |||
| 135 | nfcon_tty_driver->flags = TTY_DRIVER_REAL_RAW; | 138 | nfcon_tty_driver->flags = TTY_DRIVER_REAL_RAW; |
| 136 | 139 | ||
| 137 | tty_set_operations(nfcon_tty_driver, &nfcon_tty_ops); | 140 | tty_set_operations(nfcon_tty_driver, &nfcon_tty_ops); |
| 141 | tty_port_link_device(&nfcon_tty_port, nfcon_tty_driver, 0); | ||
| 138 | res = tty_register_driver(nfcon_tty_driver); | 142 | res = tty_register_driver(nfcon_tty_driver); |
| 139 | if (res) { | 143 | if (res) { |
| 140 | pr_err("failed to register nfcon tty driver\n"); | 144 | pr_err("failed to register nfcon tty driver\n"); |
diff --git a/arch/mips/cavium-octeon/serial.c b/arch/mips/cavium-octeon/serial.c index 138b2216b4f8..569f41bdcc46 100644 --- a/arch/mips/cavium-octeon/serial.c +++ b/arch/mips/cavium-octeon/serial.c | |||
| @@ -47,40 +47,40 @@ static int __devinit octeon_serial_probe(struct platform_device *pdev) | |||
| 47 | { | 47 | { |
| 48 | int irq, res; | 48 | int irq, res; |
| 49 | struct resource *res_mem; | 49 | struct resource *res_mem; |
| 50 | struct uart_port port; | 50 | struct uart_8250_port up; |
| 51 | 51 | ||
| 52 | /* All adaptors have an irq. */ | 52 | /* All adaptors have an irq. */ |
| 53 | irq = platform_get_irq(pdev, 0); | 53 | irq = platform_get_irq(pdev, 0); |
| 54 | if (irq < 0) | 54 | if (irq < 0) |
| 55 | return irq; | 55 | return irq; |
| 56 | 56 | ||
| 57 | memset(&port, 0, sizeof(port)); | 57 | memset(&up, 0, sizeof(up)); |
| 58 | 58 | ||
| 59 | port.flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; | 59 | up.port.flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; |
| 60 | port.type = PORT_OCTEON; | 60 | up.port.type = PORT_OCTEON; |
| 61 | port.iotype = UPIO_MEM; | 61 | up.port.iotype = UPIO_MEM; |
| 62 | port.regshift = 3; | 62 | up.port.regshift = 3; |
| 63 | port.dev = &pdev->dev; | 63 | up.port.dev = &pdev->dev; |
| 64 | 64 | ||
| 65 | if (octeon_is_simulation()) | 65 | if (octeon_is_simulation()) |
| 66 | /* Make simulator output fast*/ | 66 | /* Make simulator output fast*/ |
| 67 | port.uartclk = 115200 * 16; | 67 | up.port.uartclk = 115200 * 16; |
| 68 | else | 68 | else |
| 69 | port.uartclk = octeon_get_io_clock_rate(); | 69 | up.port.uartclk = octeon_get_io_clock_rate(); |
| 70 | 70 | ||
| 71 | port.serial_in = octeon_serial_in; | 71 | up.port.serial_in = octeon_serial_in; |
| 72 | port.serial_out = octeon_serial_out; | 72 | up.port.serial_out = octeon_serial_out; |
| 73 | port.irq = irq; | 73 | up.port.irq = irq; |
| 74 | 74 | ||
| 75 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 75 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 76 | if (res_mem == NULL) { | 76 | if (res_mem == NULL) { |
| 77 | dev_err(&pdev->dev, "found no memory resource\n"); | 77 | dev_err(&pdev->dev, "found no memory resource\n"); |
| 78 | return -ENXIO; | 78 | return -ENXIO; |
| 79 | } | 79 | } |
| 80 | port.mapbase = res_mem->start; | 80 | up.port.mapbase = res_mem->start; |
| 81 | port.membase = ioremap(res_mem->start, resource_size(res_mem)); | 81 | up.port.membase = ioremap(res_mem->start, resource_size(res_mem)); |
| 82 | 82 | ||
| 83 | res = serial8250_register_port(&port); | 83 | res = serial8250_register_8250_port(&up); |
| 84 | 84 | ||
| 85 | return res >= 0 ? 0 : res; | 85 | return res >= 0 ? 0 : res; |
| 86 | } | 86 | } |
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c index c48194c3073b..b2d4f492d782 100644 --- a/arch/mips/sni/a20r.c +++ b/arch/mips/sni/a20r.c | |||
| @@ -133,6 +133,38 @@ static struct platform_device sc26xx_pdev = { | |||
| 133 | } | 133 | } |
| 134 | }; | 134 | }; |
| 135 | 135 | ||
| 136 | #warning "Please try migrate to use new driver SCCNXP and report the status" \ | ||
| 137 | "in the linux-serial mailing list." | ||
| 138 | |||
| 139 | /* The code bellow is a replacement of SC26XX to SCCNXP */ | ||
| 140 | #if 0 | ||
| 141 | #include <linux/platform_data/sccnxp.h> | ||
| 142 | |||
| 143 | static struct sccnxp_pdata sccnxp_data = { | ||
| 144 | .reg_shift = 2, | ||
| 145 | .frequency = 3686400, | ||
| 146 | .mctrl_cfg[0] = MCTRL_SIG(DTR_OP, LINE_OP7) | | ||
| 147 | MCTRL_SIG(RTS_OP, LINE_OP3) | | ||
| 148 | MCTRL_SIG(DSR_IP, LINE_IP5) | | ||
| 149 | MCTRL_SIG(DCD_IP, LINE_IP6), | ||
| 150 | .mctrl_cfg[1] = MCTRL_SIG(DTR_OP, LINE_OP2) | | ||
| 151 | MCTRL_SIG(RTS_OP, LINE_OP1) | | ||
| 152 | MCTRL_SIG(DSR_IP, LINE_IP0) | | ||
| 153 | MCTRL_SIG(CTS_IP, LINE_IP1) | | ||
| 154 | MCTRL_SIG(DCD_IP, LINE_IP2) | | ||
| 155 | MCTRL_SIG(RNG_IP, LINE_IP3), | ||
| 156 | }; | ||
| 157 | |||
| 158 | static struct platform_device sc2681_pdev = { | ||
| 159 | .name = "sc2681", | ||
| 160 | .resource = sc2xxx_rsrc, | ||
| 161 | .num_resources = ARRAY_SIZE(sc2xxx_rsrc), | ||
| 162 | .dev = { | ||
| 163 | .platform_data = &sccnxp_data, | ||
| 164 | }, | ||
| 165 | }; | ||
| 166 | #endif | ||
| 167 | |||
| 136 | static u32 a20r_ack_hwint(void) | 168 | static u32 a20r_ack_hwint(void) |
| 137 | { | 169 | { |
| 138 | u32 status = read_c0_status(); | 170 | u32 status = read_c0_status(); |
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index 47341aa208f2..88238638aee6 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c | |||
| @@ -202,6 +202,7 @@ static int __init pdc_console_tty_driver_init(void) | |||
| 202 | pdc_console_tty_driver->flags = TTY_DRIVER_REAL_RAW | | 202 | pdc_console_tty_driver->flags = TTY_DRIVER_REAL_RAW | |
| 203 | TTY_DRIVER_RESET_TERMIOS; | 203 | TTY_DRIVER_RESET_TERMIOS; |
| 204 | tty_set_operations(pdc_console_tty_driver, &pdc_console_tty_ops); | 204 | tty_set_operations(pdc_console_tty_driver, &pdc_console_tty_ops); |
| 205 | tty_port_link_device(&tty_port, pdc_console_tty_driver, 0); | ||
| 205 | 206 | ||
| 206 | err = tty_register_driver(pdc_console_tty_driver); | 207 | err = tty_register_driver(pdc_console_tty_driver); |
| 207 | if (err) { | 208 | if (err) { |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index bbaf2c59830a..457475f98414 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
| @@ -409,7 +409,8 @@ int setup_one_line(struct line *lines, int n, char *init, | |||
| 409 | line->valid = 1; | 409 | line->valid = 1; |
| 410 | err = parse_chan_pair(new, line, n, opts, error_out); | 410 | err = parse_chan_pair(new, line, n, opts, error_out); |
| 411 | if (!err) { | 411 | if (!err) { |
| 412 | struct device *d = tty_register_device(driver, n, NULL); | 412 | struct device *d = tty_port_register_device(&line->port, |
| 413 | driver, n, NULL); | ||
| 413 | if (IS_ERR(d)) { | 414 | if (IS_ERR(d)) { |
| 414 | *error_out = "Failed to register device"; | 415 | *error_out = "Failed to register device"; |
| 415 | err = PTR_ERR(d); | 416 | err = PTR_ERR(d); |
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index f9726f6afdf1..2cd3d3a3400b 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c | |||
| @@ -223,6 +223,7 @@ int __init rs_init(void) | |||
| 223 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | 223 | serial_driver->flags = TTY_DRIVER_REAL_RAW; |
| 224 | 224 | ||
| 225 | tty_set_operations(serial_driver, &serial_ops); | 225 | tty_set_operations(serial_driver, &serial_ops); |
| 226 | tty_port_link_device(&serial_port, serial_driver, 0); | ||
| 226 | 227 | ||
| 227 | if (tty_register_driver(serial_driver)) | 228 | if (tty_register_driver(serial_driver)) |
| 228 | panic("Couldn't register serial driver\n"); | 229 | panic("Couldn't register serial driver\n"); |
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index 12172a6a95c4..0bc8a6a6a148 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c | |||
| @@ -58,7 +58,7 @@ static int ath_wakeup_ar3k(struct tty_struct *tty) | |||
| 58 | return status; | 58 | return status; |
| 59 | 59 | ||
| 60 | /* Disable Automatic RTSCTS */ | 60 | /* Disable Automatic RTSCTS */ |
| 61 | memcpy(&ktermios, tty->termios, sizeof(ktermios)); | 61 | ktermios = tty->termios; |
| 62 | ktermios.c_cflag &= ~CRTSCTS; | 62 | ktermios.c_cflag &= ~CRTSCTS; |
| 63 | tty_set_termios(tty, &ktermios); | 63 | tty_set_termios(tty, &ktermios); |
| 64 | 64 | ||
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c index 1d82d5838f0c..164544afd680 100644 --- a/drivers/char/mwave/mwavedd.c +++ b/drivers/char/mwave/mwavedd.c | |||
| @@ -430,7 +430,7 @@ static ssize_t mwave_write(struct file *file, const char __user *buf, | |||
| 430 | 430 | ||
| 431 | static int register_serial_portandirq(unsigned int port, int irq) | 431 | static int register_serial_portandirq(unsigned int port, int irq) |
| 432 | { | 432 | { |
| 433 | struct uart_port uart; | 433 | struct uart_8250_port uart; |
| 434 | 434 | ||
| 435 | switch ( port ) { | 435 | switch ( port ) { |
| 436 | case 0x3f8: | 436 | case 0x3f8: |
| @@ -462,14 +462,14 @@ static int register_serial_portandirq(unsigned int port, int irq) | |||
| 462 | } /* switch */ | 462 | } /* switch */ |
| 463 | /* irq is okay */ | 463 | /* irq is okay */ |
| 464 | 464 | ||
| 465 | memset(&uart, 0, sizeof(struct uart_port)); | 465 | memset(&uart, 0, sizeof(uart)); |
| 466 | 466 | ||
| 467 | uart.uartclk = 1843200; | 467 | uart.port.uartclk = 1843200; |
| 468 | uart.iobase = port; | 468 | uart.port.iobase = port; |
| 469 | uart.irq = irq; | 469 | uart.port.irq = irq; |
| 470 | uart.iotype = UPIO_PORT; | 470 | uart.port.iotype = UPIO_PORT; |
| 471 | uart.flags = UPF_SHARE_IRQ; | 471 | uart.port.flags = UPF_SHARE_IRQ; |
| 472 | return serial8250_register_port(&uart); | 472 | return serial8250_register_8250_port(&uart); |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | 475 | ||
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index a6b8ddea2227..21721d25e388 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
| @@ -1058,7 +1058,7 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty) | |||
| 1058 | wake_up_interruptible(&info->status_event_wait_q); | 1058 | wake_up_interruptible(&info->status_event_wait_q); |
| 1059 | wake_up_interruptible(&info->event_wait_q); | 1059 | wake_up_interruptible(&info->event_wait_q); |
| 1060 | 1060 | ||
| 1061 | if (tty && (info->port.flags & ASYNC_CTS_FLOW)) { | 1061 | if (tty && tty_port_cts_enabled(&info->port)) { |
| 1062 | if (tty->hw_stopped) { | 1062 | if (tty->hw_stopped) { |
| 1063 | if (info->serial_signals & SerialSignal_CTS) { | 1063 | if (info->serial_signals & SerialSignal_CTS) { |
| 1064 | if (debug_level >= DEBUG_LEVEL_ISR) | 1064 | if (debug_level >= DEBUG_LEVEL_ISR) |
| @@ -1350,7 +1350,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty) | |||
| 1350 | /* TODO:disable interrupts instead of reset to preserve signal states */ | 1350 | /* TODO:disable interrupts instead of reset to preserve signal states */ |
| 1351 | reset_device(info); | 1351 | reset_device(info); |
| 1352 | 1352 | ||
| 1353 | if (!tty || tty->termios->c_cflag & HUPCL) { | 1353 | if (!tty || tty->termios.c_cflag & HUPCL) { |
| 1354 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 1354 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); |
| 1355 | set_signals(info); | 1355 | set_signals(info); |
| 1356 | } | 1356 | } |
| @@ -1391,7 +1391,7 @@ static void mgslpc_program_hw(MGSLPC_INFO *info, struct tty_struct *tty) | |||
| 1391 | port_irq_enable(info, (unsigned char) PVR_DSR | PVR_RI); | 1391 | port_irq_enable(info, (unsigned char) PVR_DSR | PVR_RI); |
| 1392 | get_signals(info); | 1392 | get_signals(info); |
| 1393 | 1393 | ||
| 1394 | if (info->netcount || (tty && (tty->termios->c_cflag & CREAD))) | 1394 | if (info->netcount || (tty && (tty->termios.c_cflag & CREAD))) |
| 1395 | rx_start(info); | 1395 | rx_start(info); |
| 1396 | 1396 | ||
| 1397 | spin_unlock_irqrestore(&info->lock,flags); | 1397 | spin_unlock_irqrestore(&info->lock,flags); |
| @@ -1404,14 +1404,14 @@ static void mgslpc_change_params(MGSLPC_INFO *info, struct tty_struct *tty) | |||
| 1404 | unsigned cflag; | 1404 | unsigned cflag; |
| 1405 | int bits_per_char; | 1405 | int bits_per_char; |
| 1406 | 1406 | ||
| 1407 | if (!tty || !tty->termios) | 1407 | if (!tty) |
| 1408 | return; | 1408 | return; |
| 1409 | 1409 | ||
| 1410 | if (debug_level >= DEBUG_LEVEL_INFO) | 1410 | if (debug_level >= DEBUG_LEVEL_INFO) |
| 1411 | printk("%s(%d):mgslpc_change_params(%s)\n", | 1411 | printk("%s(%d):mgslpc_change_params(%s)\n", |
| 1412 | __FILE__,__LINE__, info->device_name ); | 1412 | __FILE__,__LINE__, info->device_name ); |
| 1413 | 1413 | ||
| 1414 | cflag = tty->termios->c_cflag; | 1414 | cflag = tty->termios.c_cflag; |
| 1415 | 1415 | ||
| 1416 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 1416 | /* if B0 rate (hangup) specified then negate DTR and RTS */ |
| 1417 | /* otherwise assert DTR and RTS */ | 1417 | /* otherwise assert DTR and RTS */ |
| @@ -1734,7 +1734,7 @@ static void mgslpc_throttle(struct tty_struct * tty) | |||
| 1734 | if (I_IXOFF(tty)) | 1734 | if (I_IXOFF(tty)) |
| 1735 | mgslpc_send_xchar(tty, STOP_CHAR(tty)); | 1735 | mgslpc_send_xchar(tty, STOP_CHAR(tty)); |
| 1736 | 1736 | ||
| 1737 | if (tty->termios->c_cflag & CRTSCTS) { | 1737 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1738 | spin_lock_irqsave(&info->lock,flags); | 1738 | spin_lock_irqsave(&info->lock,flags); |
| 1739 | info->serial_signals &= ~SerialSignal_RTS; | 1739 | info->serial_signals &= ~SerialSignal_RTS; |
| 1740 | set_signals(info); | 1740 | set_signals(info); |
| @@ -1763,7 +1763,7 @@ static void mgslpc_unthrottle(struct tty_struct * tty) | |||
| 1763 | mgslpc_send_xchar(tty, START_CHAR(tty)); | 1763 | mgslpc_send_xchar(tty, START_CHAR(tty)); |
| 1764 | } | 1764 | } |
| 1765 | 1765 | ||
| 1766 | if (tty->termios->c_cflag & CRTSCTS) { | 1766 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1767 | spin_lock_irqsave(&info->lock,flags); | 1767 | spin_lock_irqsave(&info->lock,flags); |
| 1768 | info->serial_signals |= SerialSignal_RTS; | 1768 | info->serial_signals |= SerialSignal_RTS; |
| 1769 | set_signals(info); | 1769 | set_signals(info); |
| @@ -2299,8 +2299,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
| 2299 | tty->driver->name ); | 2299 | tty->driver->name ); |
| 2300 | 2300 | ||
| 2301 | /* just return if nothing has changed */ | 2301 | /* just return if nothing has changed */ |
| 2302 | if ((tty->termios->c_cflag == old_termios->c_cflag) | 2302 | if ((tty->termios.c_cflag == old_termios->c_cflag) |
| 2303 | && (RELEVANT_IFLAG(tty->termios->c_iflag) | 2303 | && (RELEVANT_IFLAG(tty->termios.c_iflag) |
| 2304 | == RELEVANT_IFLAG(old_termios->c_iflag))) | 2304 | == RELEVANT_IFLAG(old_termios->c_iflag))) |
| 2305 | return; | 2305 | return; |
| 2306 | 2306 | ||
| @@ -2308,7 +2308,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
| 2308 | 2308 | ||
| 2309 | /* Handle transition to B0 status */ | 2309 | /* Handle transition to B0 status */ |
| 2310 | if (old_termios->c_cflag & CBAUD && | 2310 | if (old_termios->c_cflag & CBAUD && |
| 2311 | !(tty->termios->c_cflag & CBAUD)) { | 2311 | !(tty->termios.c_cflag & CBAUD)) { |
| 2312 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 2312 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); |
| 2313 | spin_lock_irqsave(&info->lock,flags); | 2313 | spin_lock_irqsave(&info->lock,flags); |
| 2314 | set_signals(info); | 2314 | set_signals(info); |
| @@ -2317,9 +2317,9 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
| 2317 | 2317 | ||
| 2318 | /* Handle transition away from B0 status */ | 2318 | /* Handle transition away from B0 status */ |
| 2319 | if (!(old_termios->c_cflag & CBAUD) && | 2319 | if (!(old_termios->c_cflag & CBAUD) && |
| 2320 | tty->termios->c_cflag & CBAUD) { | 2320 | tty->termios.c_cflag & CBAUD) { |
| 2321 | info->serial_signals |= SerialSignal_DTR; | 2321 | info->serial_signals |= SerialSignal_DTR; |
| 2322 | if (!(tty->termios->c_cflag & CRTSCTS) || | 2322 | if (!(tty->termios.c_cflag & CRTSCTS) || |
| 2323 | !test_bit(TTY_THROTTLED, &tty->flags)) { | 2323 | !test_bit(TTY_THROTTLED, &tty->flags)) { |
| 2324 | info->serial_signals |= SerialSignal_RTS; | 2324 | info->serial_signals |= SerialSignal_RTS; |
| 2325 | } | 2325 | } |
| @@ -2330,7 +2330,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
| 2330 | 2330 | ||
| 2331 | /* Handle turning off CRTSCTS */ | 2331 | /* Handle turning off CRTSCTS */ |
| 2332 | if (old_termios->c_cflag & CRTSCTS && | 2332 | if (old_termios->c_cflag & CRTSCTS && |
| 2333 | !(tty->termios->c_cflag & CRTSCTS)) { | 2333 | !(tty->termios.c_cflag & CRTSCTS)) { |
| 2334 | tty->hw_stopped = 0; | 2334 | tty->hw_stopped = 0; |
| 2335 | tx_release(tty); | 2335 | tx_release(tty); |
| 2336 | } | 2336 | } |
| @@ -2737,6 +2737,8 @@ static void mgslpc_add_device(MGSLPC_INFO *info) | |||
| 2737 | #if SYNCLINK_GENERIC_HDLC | 2737 | #if SYNCLINK_GENERIC_HDLC |
| 2738 | hdlcdev_init(info); | 2738 | hdlcdev_init(info); |
| 2739 | #endif | 2739 | #endif |
| 2740 | tty_port_register_device(&info->port, serial_driver, info->line, | ||
| 2741 | &info->p_dev->dev); | ||
| 2740 | } | 2742 | } |
| 2741 | 2743 | ||
| 2742 | static void mgslpc_remove_device(MGSLPC_INFO *remove_info) | 2744 | static void mgslpc_remove_device(MGSLPC_INFO *remove_info) |
| @@ -2750,6 +2752,7 @@ static void mgslpc_remove_device(MGSLPC_INFO *remove_info) | |||
| 2750 | last->next_device = info->next_device; | 2752 | last->next_device = info->next_device; |
| 2751 | else | 2753 | else |
| 2752 | mgslpc_device_list = info->next_device; | 2754 | mgslpc_device_list = info->next_device; |
| 2755 | tty_unregister_device(serial_driver, info->line); | ||
| 2753 | #if SYNCLINK_GENERIC_HDLC | 2756 | #if SYNCLINK_GENERIC_HDLC |
| 2754 | hdlcdev_exit(info); | 2757 | hdlcdev_exit(info); |
| 2755 | #endif | 2758 | #endif |
| @@ -2804,77 +2807,63 @@ static const struct tty_operations mgslpc_ops = { | |||
| 2804 | .proc_fops = &mgslpc_proc_fops, | 2807 | .proc_fops = &mgslpc_proc_fops, |
| 2805 | }; | 2808 | }; |
| 2806 | 2809 | ||
| 2807 | static void synclink_cs_cleanup(void) | 2810 | static int __init synclink_cs_init(void) |
| 2808 | { | 2811 | { |
| 2809 | int rc; | 2812 | int rc; |
| 2810 | 2813 | ||
| 2811 | while(mgslpc_device_list) | 2814 | if (break_on_load) { |
| 2812 | mgslpc_remove_device(mgslpc_device_list); | 2815 | mgslpc_get_text_ptr(); |
| 2813 | 2816 | BREAKPOINT(); | |
| 2814 | if (serial_driver) { | ||
| 2815 | if ((rc = tty_unregister_driver(serial_driver))) | ||
| 2816 | printk("%s(%d) failed to unregister tty driver err=%d\n", | ||
| 2817 | __FILE__,__LINE__,rc); | ||
| 2818 | put_tty_driver(serial_driver); | ||
| 2819 | } | 2817 | } |
| 2820 | 2818 | ||
| 2821 | pcmcia_unregister_driver(&mgslpc_driver); | 2819 | serial_driver = tty_alloc_driver(MAX_DEVICE_COUNT, |
| 2822 | } | 2820 | TTY_DRIVER_REAL_RAW | |
| 2823 | 2821 | TTY_DRIVER_DYNAMIC_DEV); | |
| 2824 | static int __init synclink_cs_init(void) | 2822 | if (IS_ERR(serial_driver)) { |
| 2825 | { | 2823 | rc = PTR_ERR(serial_driver); |
| 2826 | int rc; | 2824 | goto err; |
| 2827 | 2825 | } | |
| 2828 | if (break_on_load) { | ||
| 2829 | mgslpc_get_text_ptr(); | ||
| 2830 | BREAKPOINT(); | ||
| 2831 | } | ||
| 2832 | |||
| 2833 | if ((rc = pcmcia_register_driver(&mgslpc_driver)) < 0) | ||
| 2834 | return rc; | ||
| 2835 | |||
| 2836 | serial_driver = alloc_tty_driver(MAX_DEVICE_COUNT); | ||
| 2837 | if (!serial_driver) { | ||
| 2838 | rc = -ENOMEM; | ||
| 2839 | goto error; | ||
| 2840 | } | ||
| 2841 | 2826 | ||
| 2842 | /* Initialize the tty_driver structure */ | 2827 | /* Initialize the tty_driver structure */ |
| 2843 | 2828 | serial_driver->driver_name = "synclink_cs"; | |
| 2844 | serial_driver->driver_name = "synclink_cs"; | 2829 | serial_driver->name = "ttySLP"; |
| 2845 | serial_driver->name = "ttySLP"; | 2830 | serial_driver->major = ttymajor; |
| 2846 | serial_driver->major = ttymajor; | 2831 | serial_driver->minor_start = 64; |
| 2847 | serial_driver->minor_start = 64; | 2832 | serial_driver->type = TTY_DRIVER_TYPE_SERIAL; |
| 2848 | serial_driver->type = TTY_DRIVER_TYPE_SERIAL; | 2833 | serial_driver->subtype = SERIAL_TYPE_NORMAL; |
| 2849 | serial_driver->subtype = SERIAL_TYPE_NORMAL; | 2834 | serial_driver->init_termios = tty_std_termios; |
| 2850 | serial_driver->init_termios = tty_std_termios; | 2835 | serial_driver->init_termios.c_cflag = |
| 2851 | serial_driver->init_termios.c_cflag = | 2836 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
| 2852 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 2837 | tty_set_operations(serial_driver, &mgslpc_ops); |
| 2853 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | 2838 | |
| 2854 | tty_set_operations(serial_driver, &mgslpc_ops); | 2839 | rc = tty_register_driver(serial_driver); |
| 2855 | 2840 | if (rc < 0) { | |
| 2856 | if ((rc = tty_register_driver(serial_driver)) < 0) { | 2841 | printk(KERN_ERR "%s(%d):Couldn't register serial driver\n", |
| 2857 | printk("%s(%d):Couldn't register serial driver\n", | 2842 | __FILE__, __LINE__); |
| 2858 | __FILE__,__LINE__); | 2843 | goto err_put_tty; |
| 2859 | put_tty_driver(serial_driver); | 2844 | } |
| 2860 | serial_driver = NULL; | ||
| 2861 | goto error; | ||
| 2862 | } | ||
| 2863 | 2845 | ||
| 2864 | printk("%s %s, tty major#%d\n", | 2846 | rc = pcmcia_register_driver(&mgslpc_driver); |
| 2865 | driver_name, driver_version, | 2847 | if (rc < 0) |
| 2866 | serial_driver->major); | 2848 | goto err_unreg_tty; |
| 2867 | 2849 | ||
| 2868 | return 0; | 2850 | printk(KERN_INFO "%s %s, tty major#%d\n", driver_name, driver_version, |
| 2851 | serial_driver->major); | ||
| 2869 | 2852 | ||
| 2870 | error: | 2853 | return 0; |
| 2871 | synclink_cs_cleanup(); | 2854 | err_unreg_tty: |
| 2872 | return rc; | 2855 | tty_unregister_driver(serial_driver); |
| 2856 | err_put_tty: | ||
| 2857 | put_tty_driver(serial_driver); | ||
| 2858 | err: | ||
| 2859 | return rc; | ||
| 2873 | } | 2860 | } |
| 2874 | 2861 | ||
| 2875 | static void __exit synclink_cs_exit(void) | 2862 | static void __exit synclink_cs_exit(void) |
| 2876 | { | 2863 | { |
| 2877 | synclink_cs_cleanup(); | 2864 | pcmcia_unregister_driver(&mgslpc_driver); |
| 2865 | tty_unregister_driver(serial_driver); | ||
| 2866 | put_tty_driver(serial_driver); | ||
| 2878 | } | 2867 | } |
| 2879 | 2868 | ||
| 2880 | module_init(synclink_cs_init); | 2869 | module_init(synclink_cs_init); |
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index 46b77ede84c0..af98f6d6509b 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c | |||
| @@ -67,7 +67,7 @@ static int tpk_printk(const unsigned char *buf, int count) | |||
| 67 | tmp[tpk_curr + 1] = '\0'; | 67 | tmp[tpk_curr + 1] = '\0'; |
| 68 | printk(KERN_INFO "%s%s", tpk_tag, tmp); | 68 | printk(KERN_INFO "%s%s", tpk_tag, tmp); |
| 69 | tpk_curr = 0; | 69 | tpk_curr = 0; |
| 70 | if (buf[i + 1] == '\n') | 70 | if ((i + 1) < count && buf[i + 1] == '\n') |
| 71 | i++; | 71 | i++; |
| 72 | break; | 72 | break; |
| 73 | case '\n': | 73 | case '\n': |
| @@ -178,11 +178,17 @@ static struct tty_driver *ttyprintk_driver; | |||
| 178 | static int __init ttyprintk_init(void) | 178 | static int __init ttyprintk_init(void) |
| 179 | { | 179 | { |
| 180 | int ret = -ENOMEM; | 180 | int ret = -ENOMEM; |
| 181 | void *rp; | ||
| 182 | 181 | ||
| 183 | ttyprintk_driver = alloc_tty_driver(1); | 182 | tty_port_init(&tpk_port.port); |
| 184 | if (!ttyprintk_driver) | 183 | tpk_port.port.ops = &null_ops; |
| 185 | return ret; | 184 | mutex_init(&tpk_port.port_write_mutex); |
| 185 | |||
| 186 | ttyprintk_driver = tty_alloc_driver(1, | ||
| 187 | TTY_DRIVER_RESET_TERMIOS | | ||
| 188 | TTY_DRIVER_REAL_RAW | | ||
| 189 | TTY_DRIVER_UNNUMBERED_NODE); | ||
| 190 | if (IS_ERR(ttyprintk_driver)) | ||
| 191 | return PTR_ERR(ttyprintk_driver); | ||
| 186 | 192 | ||
| 187 | ttyprintk_driver->driver_name = "ttyprintk"; | 193 | ttyprintk_driver->driver_name = "ttyprintk"; |
| 188 | ttyprintk_driver->name = "ttyprintk"; | 194 | ttyprintk_driver->name = "ttyprintk"; |
| @@ -191,9 +197,8 @@ static int __init ttyprintk_init(void) | |||
| 191 | ttyprintk_driver->type = TTY_DRIVER_TYPE_CONSOLE; | 197 | ttyprintk_driver->type = TTY_DRIVER_TYPE_CONSOLE; |
| 192 | ttyprintk_driver->init_termios = tty_std_termios; | 198 | ttyprintk_driver->init_termios = tty_std_termios; |
| 193 | ttyprintk_driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET; | 199 | ttyprintk_driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET; |
| 194 | ttyprintk_driver->flags = TTY_DRIVER_RESET_TERMIOS | | ||
| 195 | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
| 196 | tty_set_operations(ttyprintk_driver, &ttyprintk_ops); | 200 | tty_set_operations(ttyprintk_driver, &ttyprintk_ops); |
| 201 | tty_port_link_device(&tpk_port.port, ttyprintk_driver, 0); | ||
| 197 | 202 | ||
| 198 | ret = tty_register_driver(ttyprintk_driver); | 203 | ret = tty_register_driver(ttyprintk_driver); |
| 199 | if (ret < 0) { | 204 | if (ret < 0) { |
| @@ -201,22 +206,10 @@ static int __init ttyprintk_init(void) | |||
| 201 | goto error; | 206 | goto error; |
| 202 | } | 207 | } |
| 203 | 208 | ||
| 204 | /* create our unnumbered device */ | ||
| 205 | rp = device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 3), NULL, | ||
| 206 | ttyprintk_driver->name); | ||
| 207 | if (IS_ERR(rp)) { | ||
| 208 | printk(KERN_ERR "Couldn't create ttyprintk device\n"); | ||
| 209 | ret = PTR_ERR(rp); | ||
| 210 | goto error; | ||
| 211 | } | ||
| 212 | |||
| 213 | tty_port_init(&tpk_port.port); | ||
| 214 | tpk_port.port.ops = &null_ops; | ||
| 215 | mutex_init(&tpk_port.port_write_mutex); | ||
| 216 | |||
| 217 | return 0; | 209 | return 0; |
| 218 | 210 | ||
| 219 | error: | 211 | error: |
| 212 | tty_unregister_driver(ttyprintk_driver); | ||
| 220 | put_tty_driver(ttyprintk_driver); | 213 | put_tty_driver(ttyprintk_driver); |
| 221 | ttyprintk_driver = NULL; | 214 | ttyprintk_driver = NULL; |
| 222 | return ret; | 215 | return ret; |
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 38c4bd87b2c9..c679867c2ccd 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
| @@ -234,7 +234,8 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) | |||
| 234 | 234 | ||
| 235 | mp->minor = minor; | 235 | mp->minor = minor; |
| 236 | 236 | ||
| 237 | dev = tty_register_device(capinc_tty_driver, minor, NULL); | 237 | dev = tty_port_register_device(&mp->port, capinc_tty_driver, minor, |
| 238 | NULL); | ||
| 238 | if (IS_ERR(dev)) | 239 | if (IS_ERR(dev)) |
| 239 | goto err_out2; | 240 | goto err_out2; |
| 240 | 241 | ||
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index a6d9fd2858f7..67abf3ff45e8 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
| @@ -446,8 +446,8 @@ static void if_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
| 446 | goto out; | 446 | goto out; |
| 447 | } | 447 | } |
| 448 | 448 | ||
| 449 | iflag = tty->termios->c_iflag; | 449 | iflag = tty->termios.c_iflag; |
| 450 | cflag = tty->termios->c_cflag; | 450 | cflag = tty->termios.c_cflag; |
| 451 | old_cflag = old ? old->c_cflag : cflag; | 451 | old_cflag = old ? old->c_cflag : cflag; |
| 452 | gig_dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x", | 452 | gig_dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x", |
| 453 | cs->minor_index, iflag, cflag, old_cflag); | 453 | cs->minor_index, iflag, cflag, old_cflag); |
| @@ -524,7 +524,8 @@ void gigaset_if_init(struct cardstate *cs) | |||
| 524 | tasklet_init(&cs->if_wake_tasklet, if_wake, (unsigned long) cs); | 524 | tasklet_init(&cs->if_wake_tasklet, if_wake, (unsigned long) cs); |
| 525 | 525 | ||
| 526 | mutex_lock(&cs->mutex); | 526 | mutex_lock(&cs->mutex); |
| 527 | cs->tty_dev = tty_register_device(drv->tty, cs->minor_index, NULL); | 527 | cs->tty_dev = tty_port_register_device(&cs->port, drv->tty, |
| 528 | cs->minor_index, NULL); | ||
| 528 | 529 | ||
| 529 | if (!IS_ERR(cs->tty_dev)) | 530 | if (!IS_ERR(cs->tty_dev)) |
| 530 | dev_set_drvdata(cs->tty_dev, cs); | 531 | dev_set_drvdata(cs->tty_dev, cs); |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 7bc50670d7d9..b817809f763c 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
| @@ -1009,15 +1009,15 @@ isdn_tty_change_speed(modem_info *info) | |||
| 1009 | quot; | 1009 | quot; |
| 1010 | int i; | 1010 | int i; |
| 1011 | 1011 | ||
| 1012 | if (!port->tty || !port->tty->termios) | 1012 | if (!port->tty) |
| 1013 | return; | 1013 | return; |
| 1014 | cflag = port->tty->termios->c_cflag; | 1014 | cflag = port->tty->termios.c_cflag; |
| 1015 | 1015 | ||
| 1016 | quot = i = cflag & CBAUD; | 1016 | quot = i = cflag & CBAUD; |
| 1017 | if (i & CBAUDEX) { | 1017 | if (i & CBAUDEX) { |
| 1018 | i &= ~CBAUDEX; | 1018 | i &= ~CBAUDEX; |
| 1019 | if (i < 1 || i > 2) | 1019 | if (i < 1 || i > 2) |
| 1020 | port->tty->termios->c_cflag &= ~CBAUDEX; | 1020 | port->tty->termios.c_cflag &= ~CBAUDEX; |
| 1021 | else | 1021 | else |
| 1022 | i += 15; | 1022 | i += 15; |
| 1023 | } | 1023 | } |
| @@ -1097,7 +1097,7 @@ isdn_tty_shutdown(modem_info *info) | |||
| 1097 | #endif | 1097 | #endif |
| 1098 | isdn_unlock_drivers(); | 1098 | isdn_unlock_drivers(); |
| 1099 | info->msr &= ~UART_MSR_RI; | 1099 | info->msr &= ~UART_MSR_RI; |
| 1100 | if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) { | 1100 | if (!info->port.tty || (info->port.tty->termios.c_cflag & HUPCL)) { |
| 1101 | info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS); | 1101 | info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS); |
| 1102 | if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) { | 1102 | if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) { |
| 1103 | isdn_tty_modem_reset_regs(info, 0); | 1103 | isdn_tty_modem_reset_regs(info, 0); |
| @@ -1469,13 +1469,13 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 1469 | if (!old_termios) | 1469 | if (!old_termios) |
| 1470 | isdn_tty_change_speed(info); | 1470 | isdn_tty_change_speed(info); |
| 1471 | else { | 1471 | else { |
| 1472 | if (tty->termios->c_cflag == old_termios->c_cflag && | 1472 | if (tty->termios.c_cflag == old_termios->c_cflag && |
| 1473 | tty->termios->c_ispeed == old_termios->c_ispeed && | 1473 | tty->termios.c_ispeed == old_termios->c_ispeed && |
| 1474 | tty->termios->c_ospeed == old_termios->c_ospeed) | 1474 | tty->termios.c_ospeed == old_termios->c_ospeed) |
| 1475 | return; | 1475 | return; |
| 1476 | isdn_tty_change_speed(info); | 1476 | isdn_tty_change_speed(info); |
| 1477 | if ((old_termios->c_cflag & CRTSCTS) && | 1477 | if ((old_termios->c_cflag & CRTSCTS) && |
| 1478 | !(tty->termios->c_cflag & CRTSCTS)) | 1478 | !(tty->termios.c_cflag & CRTSCTS)) |
| 1479 | tty->hw_stopped = 0; | 1479 | tty->hw_stopped = 0; |
| 1480 | } | 1480 | } |
| 1481 | } | 1481 | } |
| @@ -1486,6 +1486,18 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 1486 | * ------------------------------------------------------------ | 1486 | * ------------------------------------------------------------ |
| 1487 | */ | 1487 | */ |
| 1488 | 1488 | ||
| 1489 | static int isdn_tty_install(struct tty_driver *driver, struct tty_struct *tty) | ||
| 1490 | { | ||
| 1491 | modem_info *info = &dev->mdm.info[tty->index]; | ||
| 1492 | |||
| 1493 | if (isdn_tty_paranoia_check(info, tty->name, __func__)) | ||
| 1494 | return -ENODEV; | ||
| 1495 | |||
| 1496 | tty->driver_data = info; | ||
| 1497 | |||
| 1498 | return tty_port_install(&info->port, driver, tty); | ||
| 1499 | } | ||
| 1500 | |||
| 1489 | /* | 1501 | /* |
| 1490 | * This routine is called whenever a serial port is opened. It | 1502 | * This routine is called whenever a serial port is opened. It |
| 1491 | * enables interrupts for a serial port, linking in its async structure into | 1503 | * enables interrupts for a serial port, linking in its async structure into |
| @@ -1495,22 +1507,16 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 1495 | static int | 1507 | static int |
| 1496 | isdn_tty_open(struct tty_struct *tty, struct file *filp) | 1508 | isdn_tty_open(struct tty_struct *tty, struct file *filp) |
| 1497 | { | 1509 | { |
| 1498 | struct tty_port *port; | 1510 | modem_info *info = tty->driver_data; |
| 1499 | modem_info *info; | 1511 | struct tty_port *port = &info->port; |
| 1500 | int retval; | 1512 | int retval; |
| 1501 | 1513 | ||
| 1502 | info = &dev->mdm.info[tty->index]; | ||
| 1503 | if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open")) | ||
| 1504 | return -ENODEV; | ||
| 1505 | port = &info->port; | ||
| 1506 | #ifdef ISDN_DEBUG_MODEM_OPEN | 1514 | #ifdef ISDN_DEBUG_MODEM_OPEN |
| 1507 | printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name, | 1515 | printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name, |
| 1508 | port->count); | 1516 | port->count); |
| 1509 | #endif | 1517 | #endif |
| 1510 | port->count++; | 1518 | port->count++; |
| 1511 | tty->driver_data = info; | ||
| 1512 | port->tty = tty; | 1519 | port->tty = tty; |
| 1513 | tty->port = port; | ||
| 1514 | /* | 1520 | /* |
| 1515 | * Start up serial port | 1521 | * Start up serial port |
| 1516 | */ | 1522 | */ |
| @@ -1738,6 +1744,7 @@ modem_write_profile(atemu *m) | |||
| 1738 | } | 1744 | } |
| 1739 | 1745 | ||
| 1740 | static const struct tty_operations modem_ops = { | 1746 | static const struct tty_operations modem_ops = { |
| 1747 | .install = isdn_tty_install, | ||
| 1741 | .open = isdn_tty_open, | 1748 | .open = isdn_tty_open, |
| 1742 | .close = isdn_tty_close, | 1749 | .close = isdn_tty_close, |
| 1743 | .write = isdn_tty_write, | 1750 | .write = isdn_tty_write, |
| @@ -1782,7 +1789,7 @@ isdn_tty_modem_init(void) | |||
| 1782 | m->tty_modem->subtype = SERIAL_TYPE_NORMAL; | 1789 | m->tty_modem->subtype = SERIAL_TYPE_NORMAL; |
| 1783 | m->tty_modem->init_termios = tty_std_termios; | 1790 | m->tty_modem->init_termios = tty_std_termios; |
| 1784 | m->tty_modem->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 1791 | m->tty_modem->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
| 1785 | m->tty_modem->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 1792 | m->tty_modem->flags = TTY_DRIVER_REAL_RAW; |
| 1786 | m->tty_modem->driver_name = "isdn_tty"; | 1793 | m->tty_modem->driver_name = "isdn_tty"; |
| 1787 | tty_set_operations(m->tty_modem, &modem_ops); | 1794 | tty_set_operations(m->tty_modem, &modem_ops); |
| 1788 | retval = tty_register_driver(m->tty_modem); | 1795 | retval = tty_register_driver(m->tty_modem); |
diff --git a/drivers/misc/ibmasm/uart.c b/drivers/misc/ibmasm/uart.c index 1dcb9ae1905a..01e2b0d7e590 100644 --- a/drivers/misc/ibmasm/uart.c +++ b/drivers/misc/ibmasm/uart.c | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | 33 | ||
| 34 | void ibmasm_register_uart(struct service_processor *sp) | 34 | void ibmasm_register_uart(struct service_processor *sp) |
| 35 | { | 35 | { |
| 36 | struct uart_port uport; | 36 | struct uart_8250_port uart; |
| 37 | void __iomem *iomem_base; | 37 | void __iomem *iomem_base; |
| 38 | 38 | ||
| 39 | iomem_base = sp->base_address + SCOUT_COM_B_BASE; | 39 | iomem_base = sp->base_address + SCOUT_COM_B_BASE; |
| @@ -47,14 +47,14 @@ void ibmasm_register_uart(struct service_processor *sp) | |||
| 47 | return; | 47 | return; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | memset(&uport, 0, sizeof(struct uart_port)); | 50 | memset(&uart, 0, sizeof(uart)); |
| 51 | uport.irq = sp->irq; | 51 | uart.port.irq = sp->irq; |
| 52 | uport.uartclk = 3686400; | 52 | uart.port.uartclk = 3686400; |
| 53 | uport.flags = UPF_SHARE_IRQ; | 53 | uart.port.flags = UPF_SHARE_IRQ; |
| 54 | uport.iotype = UPIO_MEM; | 54 | uart.port.iotype = UPIO_MEM; |
| 55 | uport.membase = iomem_base; | 55 | uart.port.membase = iomem_base; |
| 56 | 56 | ||
| 57 | sp->serial_line = serial8250_register_port(&uport); | 57 | sp->serial_line = serial8250_register_8250_port(&uart); |
| 58 | if (sp->serial_line < 0) { | 58 | if (sp->serial_line < 0) { |
| 59 | dev_err(sp->dev, "Failed to register serial port\n"); | 59 | dev_err(sp->dev, "Failed to register serial port\n"); |
| 60 | return; | 60 | return; |
diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index b7eb545394b1..4999b34b7a60 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c | |||
| @@ -60,7 +60,7 @@ struct pti_tty { | |||
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | struct pti_dev { | 62 | struct pti_dev { |
| 63 | struct tty_port port; | 63 | struct tty_port port[PTITTY_MINOR_NUM]; |
| 64 | unsigned long pti_addr; | 64 | unsigned long pti_addr; |
| 65 | unsigned long aperture_base; | 65 | unsigned long aperture_base; |
| 66 | void __iomem *pti_ioaddr; | 66 | void __iomem *pti_ioaddr; |
| @@ -76,7 +76,7 @@ struct pti_dev { | |||
| 76 | */ | 76 | */ |
| 77 | static DEFINE_MUTEX(alloclock); | 77 | static DEFINE_MUTEX(alloclock); |
| 78 | 78 | ||
| 79 | static struct pci_device_id pci_ids[] __devinitconst = { | 79 | static const struct pci_device_id pci_ids[] __devinitconst = { |
| 80 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)}, | 80 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)}, |
| 81 | {0} | 81 | {0} |
| 82 | }; | 82 | }; |
| @@ -393,25 +393,6 @@ void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count) | |||
| 393 | } | 393 | } |
| 394 | EXPORT_SYMBOL_GPL(pti_writedata); | 394 | EXPORT_SYMBOL_GPL(pti_writedata); |
| 395 | 395 | ||
| 396 | /** | ||
| 397 | * pti_pci_remove()- Driver exit method to remove PTI from | ||
| 398 | * PCI bus. | ||
| 399 | * @pdev: variable containing pci info of PTI. | ||
| 400 | */ | ||
| 401 | static void __devexit pti_pci_remove(struct pci_dev *pdev) | ||
| 402 | { | ||
| 403 | struct pti_dev *drv_data; | ||
| 404 | |||
| 405 | drv_data = pci_get_drvdata(pdev); | ||
| 406 | if (drv_data != NULL) { | ||
| 407 | pci_iounmap(pdev, drv_data->pti_ioaddr); | ||
| 408 | pci_set_drvdata(pdev, NULL); | ||
| 409 | kfree(drv_data); | ||
| 410 | pci_release_region(pdev, 1); | ||
| 411 | pci_disable_device(pdev); | ||
| 412 | } | ||
| 413 | } | ||
| 414 | |||
| 415 | /* | 396 | /* |
| 416 | * for the tty_driver_*() basic function descriptions, see tty_driver.h. | 397 | * for the tty_driver_*() basic function descriptions, see tty_driver.h. |
| 417 | * Specific header comments made for PTI-related specifics. | 398 | * Specific header comments made for PTI-related specifics. |
| @@ -446,7 +427,7 @@ static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp) | |||
| 446 | * also removes a locking requirement for the actual write | 427 | * also removes a locking requirement for the actual write |
| 447 | * procedure. | 428 | * procedure. |
| 448 | */ | 429 | */ |
| 449 | return tty_port_open(&drv_data->port, tty, filp); | 430 | return tty_port_open(tty->port, tty, filp); |
| 450 | } | 431 | } |
| 451 | 432 | ||
| 452 | /** | 433 | /** |
| @@ -462,7 +443,7 @@ static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp) | |||
| 462 | */ | 443 | */ |
| 463 | static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp) | 444 | static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp) |
| 464 | { | 445 | { |
| 465 | tty_port_close(&drv_data->port, tty, filp); | 446 | tty_port_close(tty->port, tty, filp); |
| 466 | } | 447 | } |
| 467 | 448 | ||
| 468 | /** | 449 | /** |
| @@ -818,6 +799,7 @@ static const struct tty_port_operations tty_port_ops = { | |||
| 818 | static int __devinit pti_pci_probe(struct pci_dev *pdev, | 799 | static int __devinit pti_pci_probe(struct pci_dev *pdev, |
| 819 | const struct pci_device_id *ent) | 800 | const struct pci_device_id *ent) |
| 820 | { | 801 | { |
| 802 | unsigned int a; | ||
| 821 | int retval = -EINVAL; | 803 | int retval = -EINVAL; |
| 822 | int pci_bar = 1; | 804 | int pci_bar = 1; |
| 823 | 805 | ||
| @@ -830,7 +812,7 @@ static int __devinit pti_pci_probe(struct pci_dev *pdev, | |||
| 830 | __func__, __LINE__); | 812 | __func__, __LINE__); |
| 831 | pr_err("%s(%d): Error value returned: %d\n", | 813 | pr_err("%s(%d): Error value returned: %d\n", |
| 832 | __func__, __LINE__, retval); | 814 | __func__, __LINE__, retval); |
| 833 | return retval; | 815 | goto err; |
| 834 | } | 816 | } |
| 835 | 817 | ||
| 836 | retval = pci_enable_device(pdev); | 818 | retval = pci_enable_device(pdev); |
| @@ -838,17 +820,16 @@ static int __devinit pti_pci_probe(struct pci_dev *pdev, | |||
| 838 | dev_err(&pdev->dev, | 820 | dev_err(&pdev->dev, |
| 839 | "%s: pci_enable_device() returned error %d\n", | 821 | "%s: pci_enable_device() returned error %d\n", |
| 840 | __func__, retval); | 822 | __func__, retval); |
| 841 | return retval; | 823 | goto err_unreg_misc; |
| 842 | } | 824 | } |
| 843 | 825 | ||
| 844 | drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); | 826 | drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); |
| 845 | |||
| 846 | if (drv_data == NULL) { | 827 | if (drv_data == NULL) { |
| 847 | retval = -ENOMEM; | 828 | retval = -ENOMEM; |
| 848 | dev_err(&pdev->dev, | 829 | dev_err(&pdev->dev, |
| 849 | "%s(%d): kmalloc() returned NULL memory.\n", | 830 | "%s(%d): kmalloc() returned NULL memory.\n", |
| 850 | __func__, __LINE__); | 831 | __func__, __LINE__); |
| 851 | return retval; | 832 | goto err_disable_pci; |
| 852 | } | 833 | } |
| 853 | drv_data->pti_addr = pci_resource_start(pdev, pci_bar); | 834 | drv_data->pti_addr = pci_resource_start(pdev, pci_bar); |
| 854 | 835 | ||
| @@ -857,33 +838,65 @@ static int __devinit pti_pci_probe(struct pci_dev *pdev, | |||
| 857 | dev_err(&pdev->dev, | 838 | dev_err(&pdev->dev, |
| 858 | "%s(%d): pci_request_region() returned error %d\n", | 839 | "%s(%d): pci_request_region() returned error %d\n", |
| 859 | __func__, __LINE__, retval); | 840 | __func__, __LINE__, retval); |
| 860 | kfree(drv_data); | 841 | goto err_free_dd; |
| 861 | return retval; | ||
| 862 | } | 842 | } |
| 863 | drv_data->aperture_base = drv_data->pti_addr+APERTURE_14; | 843 | drv_data->aperture_base = drv_data->pti_addr+APERTURE_14; |
| 864 | drv_data->pti_ioaddr = | 844 | drv_data->pti_ioaddr = |
| 865 | ioremap_nocache((u32)drv_data->aperture_base, | 845 | ioremap_nocache((u32)drv_data->aperture_base, |
| 866 | APERTURE_LEN); | 846 | APERTURE_LEN); |
| 867 | if (!drv_data->pti_ioaddr) { | 847 | if (!drv_data->pti_ioaddr) { |
| 868 | pci_release_region(pdev, pci_bar); | ||
| 869 | retval = -ENOMEM; | 848 | retval = -ENOMEM; |
| 870 | kfree(drv_data); | 849 | goto err_rel_reg; |
| 871 | return retval; | ||
| 872 | } | 850 | } |
| 873 | 851 | ||
| 874 | pci_set_drvdata(pdev, drv_data); | 852 | pci_set_drvdata(pdev, drv_data); |
| 875 | 853 | ||
| 876 | tty_port_init(&drv_data->port); | 854 | for (a = 0; a < PTITTY_MINOR_NUM; a++) { |
| 877 | drv_data->port.ops = &tty_port_ops; | 855 | struct tty_port *port = &drv_data->port[a]; |
| 856 | tty_port_init(port); | ||
| 857 | port->ops = &tty_port_ops; | ||
| 878 | 858 | ||
| 879 | tty_register_device(pti_tty_driver, 0, &pdev->dev); | 859 | tty_port_register_device(port, pti_tty_driver, a, &pdev->dev); |
| 880 | tty_register_device(pti_tty_driver, 1, &pdev->dev); | 860 | } |
| 881 | 861 | ||
| 882 | register_console(&pti_console); | 862 | register_console(&pti_console); |
| 883 | 863 | ||
| 864 | return 0; | ||
| 865 | err_rel_reg: | ||
| 866 | pci_release_region(pdev, pci_bar); | ||
| 867 | err_free_dd: | ||
| 868 | kfree(drv_data); | ||
| 869 | err_disable_pci: | ||
| 870 | pci_disable_device(pdev); | ||
| 871 | err_unreg_misc: | ||
| 872 | misc_deregister(&pti_char_driver); | ||
| 873 | err: | ||
| 884 | return retval; | 874 | return retval; |
| 885 | } | 875 | } |
| 886 | 876 | ||
| 877 | /** | ||
| 878 | * pti_pci_remove()- Driver exit method to remove PTI from | ||
| 879 | * PCI bus. | ||
| 880 | * @pdev: variable containing pci info of PTI. | ||
| 881 | */ | ||
| 882 | static void __devexit pti_pci_remove(struct pci_dev *pdev) | ||
| 883 | { | ||
| 884 | struct pti_dev *drv_data = pci_get_drvdata(pdev); | ||
| 885 | |||
| 886 | unregister_console(&pti_console); | ||
| 887 | |||
| 888 | tty_unregister_device(pti_tty_driver, 0); | ||
| 889 | tty_unregister_device(pti_tty_driver, 1); | ||
| 890 | |||
| 891 | iounmap(drv_data->pti_ioaddr); | ||
| 892 | pci_set_drvdata(pdev, NULL); | ||
| 893 | kfree(drv_data); | ||
| 894 | pci_release_region(pdev, 1); | ||
| 895 | pci_disable_device(pdev); | ||
| 896 | |||
| 897 | misc_deregister(&pti_char_driver); | ||
| 898 | } | ||
| 899 | |||
| 887 | static struct pci_driver pti_pci_driver = { | 900 | static struct pci_driver pti_pci_driver = { |
| 888 | .name = PCINAME, | 901 | .name = PCINAME, |
| 889 | .id_table = pci_ids, | 902 | .id_table = pci_ids, |
| @@ -933,25 +946,24 @@ static int __init pti_init(void) | |||
| 933 | pr_err("%s(%d): Error value returned: %d\n", | 946 | pr_err("%s(%d): Error value returned: %d\n", |
| 934 | __func__, __LINE__, retval); | 947 | __func__, __LINE__, retval); |
| 935 | 948 | ||
| 936 | pti_tty_driver = NULL; | 949 | goto put_tty; |
| 937 | return retval; | ||
| 938 | } | 950 | } |
| 939 | 951 | ||
| 940 | retval = pci_register_driver(&pti_pci_driver); | 952 | retval = pci_register_driver(&pti_pci_driver); |
| 941 | |||
| 942 | if (retval) { | 953 | if (retval) { |
| 943 | pr_err("%s(%d): PCI registration failed of pti driver\n", | 954 | pr_err("%s(%d): PCI registration failed of pti driver\n", |
| 944 | __func__, __LINE__); | 955 | __func__, __LINE__); |
| 945 | pr_err("%s(%d): Error value returned: %d\n", | 956 | pr_err("%s(%d): Error value returned: %d\n", |
| 946 | __func__, __LINE__, retval); | 957 | __func__, __LINE__, retval); |
| 947 | 958 | goto unreg_tty; | |
| 948 | tty_unregister_driver(pti_tty_driver); | ||
| 949 | pr_err("%s(%d): Unregistering TTY part of pti driver\n", | ||
| 950 | __func__, __LINE__); | ||
| 951 | pti_tty_driver = NULL; | ||
| 952 | return retval; | ||
| 953 | } | 959 | } |
| 954 | 960 | ||
| 961 | return 0; | ||
| 962 | unreg_tty: | ||
| 963 | tty_unregister_driver(pti_tty_driver); | ||
| 964 | put_tty: | ||
| 965 | put_tty_driver(pti_tty_driver); | ||
| 966 | pti_tty_driver = NULL; | ||
| 955 | return retval; | 967 | return retval; |
| 956 | } | 968 | } |
| 957 | 969 | ||
| @@ -960,31 +972,9 @@ static int __init pti_init(void) | |||
| 960 | */ | 972 | */ |
| 961 | static void __exit pti_exit(void) | 973 | static void __exit pti_exit(void) |
| 962 | { | 974 | { |
| 963 | int retval; | 975 | tty_unregister_driver(pti_tty_driver); |
| 964 | |||
| 965 | tty_unregister_device(pti_tty_driver, 0); | ||
| 966 | tty_unregister_device(pti_tty_driver, 1); | ||
| 967 | |||
| 968 | retval = tty_unregister_driver(pti_tty_driver); | ||
| 969 | if (retval) { | ||
| 970 | pr_err("%s(%d): TTY unregistration failed of pti driver\n", | ||
| 971 | __func__, __LINE__); | ||
| 972 | pr_err("%s(%d): Error value returned: %d\n", | ||
| 973 | __func__, __LINE__, retval); | ||
| 974 | } | ||
| 975 | |||
| 976 | pci_unregister_driver(&pti_pci_driver); | 976 | pci_unregister_driver(&pti_pci_driver); |
| 977 | 977 | put_tty_driver(pti_tty_driver); | |
| 978 | retval = misc_deregister(&pti_char_driver); | ||
| 979 | if (retval) { | ||
| 980 | pr_err("%s(%d): CHAR unregistration failed of pti driver\n", | ||
| 981 | __func__, __LINE__); | ||
| 982 | pr_err("%s(%d): Error value returned: %d\n", | ||
| 983 | __func__, __LINE__, retval); | ||
| 984 | } | ||
| 985 | |||
| 986 | unregister_console(&pti_console); | ||
| 987 | return; | ||
| 988 | } | 978 | } |
| 989 | 979 | ||
| 990 | module_init(pti_init); | 980 | module_init(pti_init); |
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index 5a2cbfac66d2..d2339ea37815 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c | |||
| @@ -518,7 +518,7 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port) | |||
| 518 | if (status & UART_MSR_DCTS) { | 518 | if (status & UART_MSR_DCTS) { |
| 519 | port->icount.cts++; | 519 | port->icount.cts++; |
| 520 | tty = tty_port_tty_get(&port->port); | 520 | tty = tty_port_tty_get(&port->port); |
| 521 | if (tty && (tty->termios->c_cflag & CRTSCTS)) { | 521 | if (tty && (tty->termios.c_cflag & CRTSCTS)) { |
| 522 | int cts = (status & UART_MSR_CTS); | 522 | int cts = (status & UART_MSR_CTS); |
| 523 | if (tty->hw_stopped) { | 523 | if (tty->hw_stopped) { |
| 524 | if (cts) { | 524 | if (cts) { |
| @@ -671,12 +671,12 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty) | |||
| 671 | port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE; | 671 | port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE; |
| 672 | port->mctrl = TIOCM_OUT2; | 672 | port->mctrl = TIOCM_OUT2; |
| 673 | 673 | ||
| 674 | sdio_uart_change_speed(port, tty->termios, NULL); | 674 | sdio_uart_change_speed(port, &tty->termios, NULL); |
| 675 | 675 | ||
| 676 | if (tty->termios->c_cflag & CBAUD) | 676 | if (tty->termios.c_cflag & CBAUD) |
| 677 | sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); | 677 | sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); |
| 678 | 678 | ||
| 679 | if (tty->termios->c_cflag & CRTSCTS) | 679 | if (tty->termios.c_cflag & CRTSCTS) |
| 680 | if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) | 680 | if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) |
| 681 | tty->hw_stopped = 1; | 681 | tty->hw_stopped = 1; |
| 682 | 682 | ||
| @@ -850,7 +850,7 @@ static void sdio_uart_throttle(struct tty_struct *tty) | |||
| 850 | { | 850 | { |
| 851 | struct sdio_uart_port *port = tty->driver_data; | 851 | struct sdio_uart_port *port = tty->driver_data; |
| 852 | 852 | ||
| 853 | if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS)) | 853 | if (!I_IXOFF(tty) && !(tty->termios.c_cflag & CRTSCTS)) |
| 854 | return; | 854 | return; |
| 855 | 855 | ||
| 856 | if (sdio_uart_claim_func(port) != 0) | 856 | if (sdio_uart_claim_func(port) != 0) |
| @@ -861,7 +861,7 @@ static void sdio_uart_throttle(struct tty_struct *tty) | |||
| 861 | sdio_uart_start_tx(port); | 861 | sdio_uart_start_tx(port); |
| 862 | } | 862 | } |
| 863 | 863 | ||
| 864 | if (tty->termios->c_cflag & CRTSCTS) | 864 | if (tty->termios.c_cflag & CRTSCTS) |
| 865 | sdio_uart_clear_mctrl(port, TIOCM_RTS); | 865 | sdio_uart_clear_mctrl(port, TIOCM_RTS); |
| 866 | 866 | ||
| 867 | sdio_uart_irq(port->func); | 867 | sdio_uart_irq(port->func); |
| @@ -872,7 +872,7 @@ static void sdio_uart_unthrottle(struct tty_struct *tty) | |||
| 872 | { | 872 | { |
| 873 | struct sdio_uart_port *port = tty->driver_data; | 873 | struct sdio_uart_port *port = tty->driver_data; |
| 874 | 874 | ||
| 875 | if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS)) | 875 | if (!I_IXOFF(tty) && !(tty->termios.c_cflag & CRTSCTS)) |
| 876 | return; | 876 | return; |
| 877 | 877 | ||
| 878 | if (sdio_uart_claim_func(port) != 0) | 878 | if (sdio_uart_claim_func(port) != 0) |
| @@ -887,7 +887,7 @@ static void sdio_uart_unthrottle(struct tty_struct *tty) | |||
| 887 | } | 887 | } |
| 888 | } | 888 | } |
| 889 | 889 | ||
| 890 | if (tty->termios->c_cflag & CRTSCTS) | 890 | if (tty->termios.c_cflag & CRTSCTS) |
| 891 | sdio_uart_set_mctrl(port, TIOCM_RTS); | 891 | sdio_uart_set_mctrl(port, TIOCM_RTS); |
| 892 | 892 | ||
| 893 | sdio_uart_irq(port->func); | 893 | sdio_uart_irq(port->func); |
| @@ -898,12 +898,12 @@ static void sdio_uart_set_termios(struct tty_struct *tty, | |||
| 898 | struct ktermios *old_termios) | 898 | struct ktermios *old_termios) |
| 899 | { | 899 | { |
| 900 | struct sdio_uart_port *port = tty->driver_data; | 900 | struct sdio_uart_port *port = tty->driver_data; |
| 901 | unsigned int cflag = tty->termios->c_cflag; | 901 | unsigned int cflag = tty->termios.c_cflag; |
| 902 | 902 | ||
| 903 | if (sdio_uart_claim_func(port) != 0) | 903 | if (sdio_uart_claim_func(port) != 0) |
| 904 | return; | 904 | return; |
| 905 | 905 | ||
| 906 | sdio_uart_change_speed(port, tty->termios, old_termios); | 906 | sdio_uart_change_speed(port, &tty->termios, old_termios); |
| 907 | 907 | ||
| 908 | /* Handle transition to B0 status */ | 908 | /* Handle transition to B0 status */ |
| 909 | if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) | 909 | if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) |
| @@ -1132,8 +1132,8 @@ static int sdio_uart_probe(struct sdio_func *func, | |||
| 1132 | kfree(port); | 1132 | kfree(port); |
| 1133 | } else { | 1133 | } else { |
| 1134 | struct device *dev; | 1134 | struct device *dev; |
| 1135 | dev = tty_register_device(sdio_uart_tty_driver, | 1135 | dev = tty_port_register_device(&port->port, |
| 1136 | port->index, &func->dev); | 1136 | sdio_uart_tty_driver, port->index, &func->dev); |
| 1137 | if (IS_ERR(dev)) { | 1137 | if (IS_ERR(dev)) { |
| 1138 | sdio_uart_port_remove(port); | 1138 | sdio_uart_port_remove(port); |
| 1139 | ret = PTR_ERR(dev); | 1139 | ret = PTR_ERR(dev); |
diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c index b5ba3084c7fc..3e5519a0acc7 100644 --- a/drivers/net/ethernet/sgi/ioc3-eth.c +++ b/drivers/net/ethernet/sgi/ioc3-eth.c | |||
| @@ -1147,15 +1147,17 @@ static void __devinit ioc3_8250_register(struct ioc3_uartregs __iomem *uart) | |||
| 1147 | { | 1147 | { |
| 1148 | #define COSMISC_CONSTANT 6 | 1148 | #define COSMISC_CONSTANT 6 |
| 1149 | 1149 | ||
| 1150 | struct uart_port port = { | 1150 | struct uart_8250_port port = { |
| 1151 | .irq = 0, | 1151 | .port = { |
| 1152 | .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, | 1152 | .irq = 0, |
| 1153 | .iotype = UPIO_MEM, | 1153 | .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, |
| 1154 | .regshift = 0, | 1154 | .iotype = UPIO_MEM, |
| 1155 | .uartclk = (22000000 << 1) / COSMISC_CONSTANT, | 1155 | .regshift = 0, |
| 1156 | 1156 | .uartclk = (22000000 << 1) / COSMISC_CONSTANT, | |
| 1157 | .membase = (unsigned char __iomem *) uart, | 1157 | |
| 1158 | .mapbase = (unsigned long) uart, | 1158 | .membase = (unsigned char __iomem *) uart, |
| 1159 | .mapbase = (unsigned long) uart, | ||
| 1160 | } | ||
| 1159 | }; | 1161 | }; |
| 1160 | unsigned char lcr; | 1162 | unsigned char lcr; |
| 1161 | 1163 | ||
| @@ -1164,7 +1166,7 @@ static void __devinit ioc3_8250_register(struct ioc3_uartregs __iomem *uart) | |||
| 1164 | uart->iu_scr = COSMISC_CONSTANT, | 1166 | uart->iu_scr = COSMISC_CONSTANT, |
| 1165 | uart->iu_lcr = lcr; | 1167 | uart->iu_lcr = lcr; |
| 1166 | uart->iu_lcr; | 1168 | uart->iu_lcr; |
| 1167 | serial8250_register_port(&port); | 1169 | serial8250_register_8250_port(&port); |
| 1168 | } | 1170 | } |
| 1169 | 1171 | ||
| 1170 | static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) | 1172 | static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) |
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 3352b2443e58..30087ca23a0f 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
| @@ -124,8 +124,8 @@ static int irtty_change_speed(struct sir_dev *dev, unsigned speed) | |||
| 124 | tty = priv->tty; | 124 | tty = priv->tty; |
| 125 | 125 | ||
| 126 | mutex_lock(&tty->termios_mutex); | 126 | mutex_lock(&tty->termios_mutex); |
| 127 | old_termios = *(tty->termios); | 127 | old_termios = tty->termios; |
| 128 | cflag = tty->termios->c_cflag; | 128 | cflag = tty->termios.c_cflag; |
| 129 | tty_encode_baud_rate(tty, speed, speed); | 129 | tty_encode_baud_rate(tty, speed, speed); |
| 130 | if (tty->ops->set_termios) | 130 | if (tty->ops->set_termios) |
| 131 | tty->ops->set_termios(tty, &old_termios); | 131 | tty->ops->set_termios(tty, &old_termios); |
| @@ -281,15 +281,15 @@ static inline void irtty_stop_receiver(struct tty_struct *tty, int stop) | |||
| 281 | int cflag; | 281 | int cflag; |
| 282 | 282 | ||
| 283 | mutex_lock(&tty->termios_mutex); | 283 | mutex_lock(&tty->termios_mutex); |
| 284 | old_termios = *(tty->termios); | 284 | old_termios = tty->termios; |
| 285 | cflag = tty->termios->c_cflag; | 285 | cflag = tty->termios.c_cflag; |
| 286 | 286 | ||
| 287 | if (stop) | 287 | if (stop) |
| 288 | cflag &= ~CREAD; | 288 | cflag &= ~CREAD; |
| 289 | else | 289 | else |
| 290 | cflag |= CREAD; | 290 | cflag |= CREAD; |
| 291 | 291 | ||
| 292 | tty->termios->c_cflag = cflag; | 292 | tty->termios.c_cflag = cflag; |
| 293 | if (tty->ops->set_termios) | 293 | if (tty->ops->set_termios) |
| 294 | tty->ops->set_termios(tty, &old_termios); | 294 | tty->ops->set_termios(tty, &old_termios); |
| 295 | mutex_unlock(&tty->termios_mutex); | 295 | mutex_unlock(&tty->termios_mutex); |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 62f30b46fa42..605a4baa9b7b 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
| @@ -1107,7 +1107,6 @@ static void _hso_serial_set_termios(struct tty_struct *tty, | |||
| 1107 | struct ktermios *old) | 1107 | struct ktermios *old) |
| 1108 | { | 1108 | { |
| 1109 | struct hso_serial *serial = tty->driver_data; | 1109 | struct hso_serial *serial = tty->driver_data; |
| 1110 | struct ktermios *termios; | ||
| 1111 | 1110 | ||
| 1112 | if (!serial) { | 1111 | if (!serial) { |
| 1113 | printk(KERN_ERR "%s: no tty structures", __func__); | 1112 | printk(KERN_ERR "%s: no tty structures", __func__); |
| @@ -1119,16 +1118,15 @@ static void _hso_serial_set_termios(struct tty_struct *tty, | |||
| 1119 | /* | 1118 | /* |
| 1120 | * Fix up unsupported bits | 1119 | * Fix up unsupported bits |
| 1121 | */ | 1120 | */ |
| 1122 | termios = tty->termios; | 1121 | tty->termios.c_iflag &= ~IXON; /* disable enable XON/XOFF flow control */ |
| 1123 | termios->c_iflag &= ~IXON; /* disable enable XON/XOFF flow control */ | ||
| 1124 | 1122 | ||
| 1125 | termios->c_cflag &= | 1123 | tty->termios.c_cflag &= |
| 1126 | ~(CSIZE /* no size */ | 1124 | ~(CSIZE /* no size */ |
| 1127 | | PARENB /* disable parity bit */ | 1125 | | PARENB /* disable parity bit */ |
| 1128 | | CBAUD /* clear current baud rate */ | 1126 | | CBAUD /* clear current baud rate */ |
| 1129 | | CBAUDEX); /* clear current buad rate */ | 1127 | | CBAUDEX); /* clear current buad rate */ |
| 1130 | 1128 | ||
| 1131 | termios->c_cflag |= CS8; /* character size 8 bits */ | 1129 | tty->termios.c_cflag |= CS8; /* character size 8 bits */ |
| 1132 | 1130 | ||
| 1133 | /* baud rate 115200 */ | 1131 | /* baud rate 115200 */ |
| 1134 | tty_encode_baud_rate(tty, 115200, 115200); | 1132 | tty_encode_baud_rate(tty, 115200, 115200); |
| @@ -1425,14 +1423,14 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
| 1425 | 1423 | ||
| 1426 | if (old) | 1424 | if (old) |
| 1427 | D5("Termios called with: cflags new[%d] - old[%d]", | 1425 | D5("Termios called with: cflags new[%d] - old[%d]", |
| 1428 | tty->termios->c_cflag, old->c_cflag); | 1426 | tty->termios.c_cflag, old->c_cflag); |
| 1429 | 1427 | ||
| 1430 | /* the actual setup */ | 1428 | /* the actual setup */ |
| 1431 | spin_lock_irqsave(&serial->serial_lock, flags); | 1429 | spin_lock_irqsave(&serial->serial_lock, flags); |
| 1432 | if (serial->port.count) | 1430 | if (serial->port.count) |
| 1433 | _hso_serial_set_termios(tty, old); | 1431 | _hso_serial_set_termios(tty, old); |
| 1434 | else | 1432 | else |
| 1435 | tty->termios = old; | 1433 | tty->termios = *old; |
| 1436 | spin_unlock_irqrestore(&serial->serial_lock, flags); | 1434 | spin_unlock_irqrestore(&serial->serial_lock, flags); |
| 1437 | 1435 | ||
| 1438 | /* done */ | 1436 | /* done */ |
| @@ -2289,9 +2287,11 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, | |||
| 2289 | if (minor < 0) | 2287 | if (minor < 0) |
| 2290 | goto exit; | 2288 | goto exit; |
| 2291 | 2289 | ||
| 2290 | tty_port_init(&serial->port); | ||
| 2291 | |||
| 2292 | /* register our minor number */ | 2292 | /* register our minor number */ |
| 2293 | serial->parent->dev = tty_register_device(tty_drv, minor, | 2293 | serial->parent->dev = tty_port_register_device(&serial->port, tty_drv, |
| 2294 | &serial->parent->interface->dev); | 2294 | minor, &serial->parent->interface->dev); |
| 2295 | dev = serial->parent->dev; | 2295 | dev = serial->parent->dev; |
| 2296 | dev_set_drvdata(dev, serial->parent); | 2296 | dev_set_drvdata(dev, serial->parent); |
| 2297 | i = device_create_file(dev, &dev_attr_hsotype); | 2297 | i = device_create_file(dev, &dev_attr_hsotype); |
| @@ -2300,7 +2300,6 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, | |||
| 2300 | serial->minor = minor; | 2300 | serial->minor = minor; |
| 2301 | serial->magic = HSO_SERIAL_MAGIC; | 2301 | serial->magic = HSO_SERIAL_MAGIC; |
| 2302 | spin_lock_init(&serial->serial_lock); | 2302 | spin_lock_init(&serial->serial_lock); |
| 2303 | tty_port_init(&serial->port); | ||
| 2304 | serial->num_rx_urbs = num_urbs; | 2303 | serial->num_rx_urbs = num_urbs; |
| 2305 | 2304 | ||
| 2306 | /* RX, allocate urb and initialize */ | 2305 | /* RX, allocate urb and initialize */ |
diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c index 5d6de380e42b..352f96180bc7 100644 --- a/drivers/parport/parport_gsc.c +++ b/drivers/parport/parport_gsc.c | |||
| @@ -271,6 +271,7 @@ struct parport *__devinit parport_gsc_probe_port (unsigned long base, | |||
| 271 | if (!parport_SPP_supported (p)) { | 271 | if (!parport_SPP_supported (p)) { |
| 272 | /* No port. */ | 272 | /* No port. */ |
| 273 | kfree (priv); | 273 | kfree (priv); |
| 274 | kfree(ops); | ||
| 274 | return NULL; | 275 | return NULL; |
| 275 | } | 276 | } |
| 276 | parport_PS2_supported (p); | 277 | parport_PS2_supported (p); |
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index e9c32274df3f..1631eeaf440e 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
| @@ -62,6 +62,7 @@ enum parport_pc_pci_cards { | |||
| 62 | timedia_9079a, | 62 | timedia_9079a, |
| 63 | timedia_9079b, | 63 | timedia_9079b, |
| 64 | timedia_9079c, | 64 | timedia_9079c, |
| 65 | wch_ch353_2s1p, | ||
| 65 | }; | 66 | }; |
| 66 | 67 | ||
| 67 | /* each element directly indexed from enum list, above */ | 68 | /* each element directly indexed from enum list, above */ |
| @@ -145,6 +146,7 @@ static struct parport_pc_pci cards[] __devinitdata = { | |||
| 145 | /* timedia_9079a */ { 1, { { 2, 3 }, } }, | 146 | /* timedia_9079a */ { 1, { { 2, 3 }, } }, |
| 146 | /* timedia_9079b */ { 1, { { 2, 3 }, } }, | 147 | /* timedia_9079b */ { 1, { { 2, 3 }, } }, |
| 147 | /* timedia_9079c */ { 1, { { 2, 3 }, } }, | 148 | /* timedia_9079c */ { 1, { { 2, 3 }, } }, |
| 149 | /* wch_ch353_2s1p*/ { 1, { { 2, -1}, } }, | ||
| 148 | }; | 150 | }; |
| 149 | 151 | ||
| 150 | static struct pci_device_id parport_serial_pci_tbl[] = { | 152 | static struct pci_device_id parport_serial_pci_tbl[] = { |
| @@ -243,7 +245,8 @@ static struct pci_device_id parport_serial_pci_tbl[] = { | |||
| 243 | { 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a }, | 245 | { 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a }, |
| 244 | { 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b }, | 246 | { 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b }, |
| 245 | { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c }, | 247 | { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c }, |
| 246 | 248 | /* WCH CARDS */ | |
| 249 | { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p}, | ||
| 247 | { 0, } /* terminate list */ | 250 | { 0, } /* terminate list */ |
| 248 | }; | 251 | }; |
| 249 | MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); | 252 | MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); |
| @@ -460,6 +463,12 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = { | |||
| 460 | .base_baud = 921600, | 463 | .base_baud = 921600, |
| 461 | .uart_offset = 8, | 464 | .uart_offset = 8, |
| 462 | }, | 465 | }, |
| 466 | [wch_ch353_2s1p] = { | ||
| 467 | .flags = FL_BASE0|FL_BASE_BARS, | ||
| 468 | .num_ports = 2, | ||
| 469 | .base_baud = 115200, | ||
| 470 | .uart_offset = 8, | ||
| 471 | }, | ||
| 463 | }; | 472 | }; |
| 464 | 473 | ||
| 465 | struct parport_serial_private { | 474 | struct parport_serial_private { |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 6c0116d48c74..9ffb6d5f17aa 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
| @@ -716,10 +716,17 @@ static int raw3215_probe (struct ccw_device *cdev) | |||
| 716 | static void raw3215_remove (struct ccw_device *cdev) | 716 | static void raw3215_remove (struct ccw_device *cdev) |
| 717 | { | 717 | { |
| 718 | struct raw3215_info *raw; | 718 | struct raw3215_info *raw; |
| 719 | unsigned int line; | ||
| 719 | 720 | ||
| 720 | ccw_device_set_offline(cdev); | 721 | ccw_device_set_offline(cdev); |
| 721 | raw = dev_get_drvdata(&cdev->dev); | 722 | raw = dev_get_drvdata(&cdev->dev); |
| 722 | if (raw) { | 723 | if (raw) { |
| 724 | spin_lock(&raw3215_device_lock); | ||
| 725 | for (line = 0; line < NR_3215; line++) | ||
| 726 | if (raw3215[line] == raw) | ||
| 727 | break; | ||
| 728 | raw3215[line] = NULL; | ||
| 729 | spin_unlock(&raw3215_device_lock); | ||
| 723 | dev_set_drvdata(&cdev->dev, NULL); | 730 | dev_set_drvdata(&cdev->dev, NULL); |
| 724 | raw3215_free_info(raw); | 731 | raw3215_free_info(raw); |
| 725 | } | 732 | } |
| @@ -935,6 +942,19 @@ static int __init con3215_init(void) | |||
| 935 | console_initcall(con3215_init); | 942 | console_initcall(con3215_init); |
| 936 | #endif | 943 | #endif |
| 937 | 944 | ||
| 945 | static int tty3215_install(struct tty_driver *driver, struct tty_struct *tty) | ||
| 946 | { | ||
| 947 | struct raw3215_info *raw; | ||
| 948 | |||
| 949 | raw = raw3215[tty->index]; | ||
| 950 | if (raw == NULL) | ||
| 951 | return -ENODEV; | ||
| 952 | |||
| 953 | tty->driver_data = raw; | ||
| 954 | |||
| 955 | return tty_port_install(&raw->port, driver, tty); | ||
| 956 | } | ||
| 957 | |||
| 938 | /* | 958 | /* |
| 939 | * tty3215_open | 959 | * tty3215_open |
| 940 | * | 960 | * |
| @@ -942,14 +962,9 @@ console_initcall(con3215_init); | |||
| 942 | */ | 962 | */ |
| 943 | static int tty3215_open(struct tty_struct *tty, struct file * filp) | 963 | static int tty3215_open(struct tty_struct *tty, struct file * filp) |
| 944 | { | 964 | { |
| 945 | struct raw3215_info *raw; | 965 | struct raw3215_info *raw = tty->driver_data; |
| 946 | int retval; | 966 | int retval; |
| 947 | 967 | ||
| 948 | raw = raw3215[tty->index]; | ||
| 949 | if (raw == NULL) | ||
| 950 | return -ENODEV; | ||
| 951 | |||
| 952 | tty->driver_data = raw; | ||
| 953 | tty_port_tty_set(&raw->port, tty); | 968 | tty_port_tty_set(&raw->port, tty); |
| 954 | 969 | ||
| 955 | tty->low_latency = 0; /* don't use bottom half for pushing chars */ | 970 | tty->low_latency = 0; /* don't use bottom half for pushing chars */ |
| @@ -1110,6 +1125,7 @@ static void tty3215_start(struct tty_struct *tty) | |||
| 1110 | } | 1125 | } |
| 1111 | 1126 | ||
| 1112 | static const struct tty_operations tty3215_ops = { | 1127 | static const struct tty_operations tty3215_ops = { |
| 1128 | .install = tty3215_install, | ||
| 1113 | .open = tty3215_open, | 1129 | .open = tty3215_open, |
| 1114 | .close = tty3215_close, | 1130 | .close = tty3215_close, |
| 1115 | .write = tty3215_write, | 1131 | .write = tty3215_write, |
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 0792c85baafe..30ec09e3d037 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c | |||
| @@ -567,6 +567,7 @@ sclp_tty_init(void) | |||
| 567 | driver->init_termios.c_lflag = ISIG | ECHO; | 567 | driver->init_termios.c_lflag = ISIG | ECHO; |
| 568 | driver->flags = TTY_DRIVER_REAL_RAW; | 568 | driver->flags = TTY_DRIVER_REAL_RAW; |
| 569 | tty_set_operations(driver, &sclp_ops); | 569 | tty_set_operations(driver, &sclp_ops); |
| 570 | tty_port_link_device(&sclp_port, driver, 0); | ||
| 570 | rc = tty_register_driver(driver); | 571 | rc = tty_register_driver(driver); |
| 571 | if (rc) { | 572 | if (rc) { |
| 572 | put_tty_driver(driver); | 573 | put_tty_driver(driver); |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index edfc0fd73dc6..7e60f3d2f3f9 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
| @@ -691,6 +691,7 @@ static int __init sclp_vt220_tty_init(void) | |||
| 691 | driver->init_termios = tty_std_termios; | 691 | driver->init_termios = tty_std_termios; |
| 692 | driver->flags = TTY_DRIVER_REAL_RAW; | 692 | driver->flags = TTY_DRIVER_REAL_RAW; |
| 693 | tty_set_operations(driver, &sclp_vt220_ops); | 693 | tty_set_operations(driver, &sclp_vt220_ops); |
| 694 | tty_port_link_device(&sclp_vt220_port, driver, 0); | ||
| 694 | 695 | ||
| 695 | rc = tty_register_driver(driver); | 696 | rc = tty_register_driver(driver); |
| 696 | if (rc) | 697 | if (rc) |
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 1928f3458d10..482ee028f842 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c | |||
| @@ -842,17 +842,14 @@ static struct raw3270_fn tty3270_fn = { | |||
| 842 | }; | 842 | }; |
| 843 | 843 | ||
| 844 | /* | 844 | /* |
| 845 | * This routine is called whenever a 3270 tty is opened. | 845 | * This routine is called whenever a 3270 tty is opened first time. |
| 846 | */ | 846 | */ |
| 847 | static int | 847 | static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) |
| 848 | tty3270_open(struct tty_struct *tty, struct file * filp) | ||
| 849 | { | 848 | { |
| 850 | struct raw3270_view *view; | 849 | struct raw3270_view *view; |
| 851 | struct tty3270 *tp; | 850 | struct tty3270 *tp; |
| 852 | int i, rc; | 851 | int i, rc; |
| 853 | 852 | ||
| 854 | if (tty->count > 1) | ||
| 855 | return 0; | ||
| 856 | /* Check if the tty3270 is already there. */ | 853 | /* Check if the tty3270 is already there. */ |
| 857 | view = raw3270_find_view(&tty3270_fn, | 854 | view = raw3270_find_view(&tty3270_fn, |
| 858 | tty->index + RAW3270_FIRSTMINOR); | 855 | tty->index + RAW3270_FIRSTMINOR); |
| @@ -865,7 +862,7 @@ tty3270_open(struct tty_struct *tty, struct file * filp) | |||
| 865 | /* why to reassign? */ | 862 | /* why to reassign? */ |
| 866 | tty_port_tty_set(&tp->port, tty); | 863 | tty_port_tty_set(&tp->port, tty); |
| 867 | tp->inattr = TF_INPUT; | 864 | tp->inattr = TF_INPUT; |
| 868 | return 0; | 865 | return tty_port_install(&tp->port, driver, tty); |
| 869 | } | 866 | } |
| 870 | if (tty3270_max_index < tty->index + 1) | 867 | if (tty3270_max_index < tty->index + 1) |
| 871 | tty3270_max_index = tty->index + 1; | 868 | tty3270_max_index = tty->index + 1; |
| @@ -895,7 +892,6 @@ tty3270_open(struct tty_struct *tty, struct file * filp) | |||
| 895 | 892 | ||
| 896 | tty_port_tty_set(&tp->port, tty); | 893 | tty_port_tty_set(&tp->port, tty); |
| 897 | tty->low_latency = 0; | 894 | tty->low_latency = 0; |
| 898 | tty->driver_data = tp; | ||
| 899 | tty->winsize.ws_row = tp->view.rows - 2; | 895 | tty->winsize.ws_row = tp->view.rows - 2; |
| 900 | tty->winsize.ws_col = tp->view.cols; | 896 | tty->winsize.ws_col = tp->view.cols; |
| 901 | 897 | ||
| @@ -915,6 +911,15 @@ tty3270_open(struct tty_struct *tty, struct file * filp) | |||
| 915 | kbd_ascebc(tp->kbd, tp->view.ascebc); | 911 | kbd_ascebc(tp->kbd, tp->view.ascebc); |
| 916 | 912 | ||
| 917 | raw3270_activate_view(&tp->view); | 913 | raw3270_activate_view(&tp->view); |
| 914 | |||
| 915 | rc = tty_port_install(&tp->port, driver, tty); | ||
| 916 | if (rc) { | ||
| 917 | raw3270_put_view(&tp->view); | ||
| 918 | return rc; | ||
| 919 | } | ||
| 920 | |||
| 921 | tty->driver_data = tp; | ||
| 922 | |||
| 918 | return 0; | 923 | return 0; |
| 919 | } | 924 | } |
| 920 | 925 | ||
| @@ -932,10 +937,17 @@ tty3270_close(struct tty_struct *tty, struct file * filp) | |||
| 932 | if (tp) { | 937 | if (tp) { |
| 933 | tty->driver_data = NULL; | 938 | tty->driver_data = NULL; |
| 934 | tty_port_tty_set(&tp->port, NULL); | 939 | tty_port_tty_set(&tp->port, NULL); |
| 935 | raw3270_put_view(&tp->view); | ||
| 936 | } | 940 | } |
| 937 | } | 941 | } |
| 938 | 942 | ||
| 943 | static void tty3270_cleanup(struct tty_struct *tty) | ||
| 944 | { | ||
| 945 | struct tty3270 *tp = tty->driver_data; | ||
| 946 | |||
| 947 | if (tp) | ||
| 948 | raw3270_put_view(&tp->view); | ||
| 949 | } | ||
| 950 | |||
| 939 | /* | 951 | /* |
| 940 | * We always have room. | 952 | * We always have room. |
| 941 | */ | 953 | */ |
| @@ -1737,7 +1749,8 @@ static long tty3270_compat_ioctl(struct tty_struct *tty, | |||
| 1737 | #endif | 1749 | #endif |
| 1738 | 1750 | ||
| 1739 | static const struct tty_operations tty3270_ops = { | 1751 | static const struct tty_operations tty3270_ops = { |
| 1740 | .open = tty3270_open, | 1752 | .install = tty3270_install, |
| 1753 | .cleanup = tty3270_cleanup, | ||
| 1741 | .close = tty3270_close, | 1754 | .close = tty3270_close, |
| 1742 | .write = tty3270_write, | 1755 | .write = tty3270_write, |
| 1743 | .put_char = tty3270_put_char, | 1756 | .put_char = tty3270_put_char, |
| @@ -1781,7 +1794,7 @@ static int __init tty3270_init(void) | |||
| 1781 | driver->type = TTY_DRIVER_TYPE_SYSTEM; | 1794 | driver->type = TTY_DRIVER_TYPE_SYSTEM; |
| 1782 | driver->subtype = SYSTEM_TYPE_TTY; | 1795 | driver->subtype = SYSTEM_TYPE_TTY; |
| 1783 | driver->init_termios = tty_std_termios; | 1796 | driver->init_termios = tty_std_termios; |
| 1784 | driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_DYNAMIC_DEV; | 1797 | driver->flags = TTY_DRIVER_RESET_TERMIOS; |
| 1785 | tty_set_operations(driver, &tty3270_ops); | 1798 | tty_set_operations(driver, &tty3270_ops); |
| 1786 | ret = tty_register_driver(driver); | 1799 | ret = tty_register_driver(driver); |
| 1787 | if (ret) { | 1800 | if (ret) { |
| @@ -1800,6 +1813,7 @@ tty3270_exit(void) | |||
| 1800 | driver = tty3270_driver; | 1813 | driver = tty3270_driver; |
| 1801 | tty3270_driver = NULL; | 1814 | tty3270_driver = NULL; |
| 1802 | tty_unregister_driver(driver); | 1815 | tty_unregister_driver(driver); |
| 1816 | put_tty_driver(driver); | ||
| 1803 | tty3270_del_views(); | 1817 | tty3270_del_views(); |
| 1804 | } | 1818 | } |
| 1805 | 1819 | ||
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 0f51a158ef70..d805eef11915 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
| @@ -142,4 +142,6 @@ source "drivers/staging/ced1401/Kconfig" | |||
| 142 | 142 | ||
| 143 | source "drivers/staging/imx-drm/Kconfig" | 143 | source "drivers/staging/imx-drm/Kconfig" |
| 144 | 144 | ||
| 145 | source "drivers/staging/dgrp/Kconfig" | ||
| 146 | |||
| 145 | endif # STAGING | 147 | endif # STAGING |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index f4b2bc41f1d1..76e2ebd596ff 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
| @@ -63,3 +63,4 @@ obj-$(CONFIG_ZCACHE2) += ramster/ | |||
| 63 | obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/ | 63 | obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/ |
| 64 | obj-$(CONFIG_CED1401) += ced1401/ | 64 | obj-$(CONFIG_CED1401) += ced1401/ |
| 65 | obj-$(CONFIG_DRM_IMX) += imx-drm/ | 65 | obj-$(CONFIG_DRM_IMX) += imx-drm/ |
| 66 | obj-$(CONFIG_DGRP) += dgrp/ | ||
diff --git a/drivers/staging/dgrp/Kconfig b/drivers/staging/dgrp/Kconfig new file mode 100644 index 000000000000..39f4bb65ec83 --- /dev/null +++ b/drivers/staging/dgrp/Kconfig | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | config DGRP | ||
| 2 | tristate "Digi Realport driver" | ||
| 3 | default n | ||
| 4 | depends on SYSFS | ||
| 5 | ---help--- | ||
| 6 | Support for Digi Realport devices. These devices allow you to | ||
| 7 | access remote serial ports as if they are local tty devices. This | ||
| 8 | will build the kernel driver, you will still need the userspace | ||
| 9 | component to make your Realport device work. | ||
diff --git a/drivers/staging/dgrp/Makefile b/drivers/staging/dgrp/Makefile new file mode 100644 index 000000000000..d9c3b88d7162 --- /dev/null +++ b/drivers/staging/dgrp/Makefile | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | obj-$(CONFIG_DGRP) += dgrp.o | ||
| 2 | |||
| 3 | dgrp-y := \ | ||
| 4 | dgrp_common.o \ | ||
| 5 | dgrp_dpa_ops.o \ | ||
| 6 | dgrp_driver.o \ | ||
| 7 | dgrp_mon_ops.o \ | ||
| 8 | dgrp_net_ops.o \ | ||
| 9 | dgrp_ports_ops.o \ | ||
| 10 | dgrp_specproc.o \ | ||
| 11 | dgrp_tty.o \ | ||
| 12 | dgrp_sysfs.o | ||
diff --git a/drivers/staging/dgrp/README b/drivers/staging/dgrp/README new file mode 100644 index 000000000000..1d8aaee270e8 --- /dev/null +++ b/drivers/staging/dgrp/README | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | The user space code to work with this driver is located at | ||
| 2 | https://github.com/wfp5p/dgrp-utils | ||
diff --git a/drivers/staging/dgrp/TODO b/drivers/staging/dgrp/TODO new file mode 100644 index 000000000000..3ef2611bc6d7 --- /dev/null +++ b/drivers/staging/dgrp/TODO | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | - Use configfs for config stuff. This will require changes to the | ||
| 2 | user space code. | ||
| 3 | |||
| 4 | - dgrp_send() and dgrp_receive() could use some refactoring | ||
| 5 | |||
| 6 | - Don't automatically create CHAN_MAX (64) channel array entries for | ||
| 7 | every device as many devices are going to have much less than 64 | ||
| 8 | channels. | ||
| 9 | |||
| 10 | - The locking needs to be checked. It seems haphazardly done in most | ||
| 11 | places. | ||
| 12 | |||
| 13 | - Check Kconfig dependencies | ||
diff --git a/drivers/staging/dgrp/dgrp_common.c b/drivers/staging/dgrp/dgrp_common.c new file mode 100644 index 000000000000..fce74e7fb834 --- /dev/null +++ b/drivers/staging/dgrp/dgrp_common.c | |||
| @@ -0,0 +1,200 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright 1999 Digi International (www.digi.com) | ||
| 4 | * James Puzzo <jamesp at digi dot com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 9 | * any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the | ||
| 13 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | ||
| 14 | * PURPOSE. See the GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* | ||
| 19 | * | ||
| 20 | * Filename: | ||
| 21 | * | ||
| 22 | * dgrp_common.c | ||
| 23 | * | ||
| 24 | * Description: | ||
| 25 | * | ||
| 26 | * Definitions of global variables and functions which are either | ||
| 27 | * shared by the tty, mon, and net drivers; or which cross them | ||
| 28 | * functionally (like the poller). | ||
| 29 | * | ||
| 30 | * Author: | ||
| 31 | * | ||
| 32 | * James A. Puzzo | ||
| 33 | * | ||
| 34 | */ | ||
| 35 | |||
| 36 | #include <linux/errno.h> | ||
| 37 | #include <linux/tty.h> | ||
| 38 | #include <linux/sched.h> | ||
| 39 | #include <linux/cred.h> | ||
| 40 | |||
| 41 | #include "dgrp_common.h" | ||
| 42 | |||
| 43 | /** | ||
| 44 | * dgrp_carrier -- check for carrier change state and act | ||
| 45 | * @ch: struct ch_struct * | ||
| 46 | */ | ||
| 47 | void dgrp_carrier(struct ch_struct *ch) | ||
| 48 | { | ||
| 49 | struct nd_struct *nd; | ||
| 50 | |||
| 51 | int virt_carrier = 0; | ||
| 52 | int phys_carrier = 0; | ||
| 53 | |||
| 54 | /* fix case when the tty has already closed. */ | ||
| 55 | |||
| 56 | if (!ch) | ||
| 57 | return; | ||
| 58 | nd = ch->ch_nd; | ||
| 59 | if (!nd) | ||
| 60 | return; | ||
| 61 | |||
| 62 | /* | ||
| 63 | * If we are currently waiting to determine the status of the port, | ||
| 64 | * we don't yet know the state of the modem lines. As a result, | ||
| 65 | * we ignore state changes when we are waiting for the modem lines | ||
| 66 | * to be established. We know, as a result of code in dgrp_net_ops, | ||
| 67 | * that we will be called again immediately following the reception | ||
| 68 | * of the status message with the true modem status flags in it. | ||
| 69 | */ | ||
| 70 | if (ch->ch_expect & RR_STATUS) | ||
| 71 | return; | ||
| 72 | |||
| 73 | /* | ||
| 74 | * If CH_HANGUP is set, we gotta keep trying to get all the processes | ||
| 75 | * that have the port open to close the port. | ||
| 76 | * So lets just keep sending a hangup every time we get here. | ||
| 77 | */ | ||
| 78 | if ((ch->ch_flag & CH_HANGUP) && | ||
| 79 | (ch->ch_tun.un_open_count > 0)) | ||
| 80 | tty_hangup(ch->ch_tun.un_tty); | ||
| 81 | |||
| 82 | /* | ||
| 83 | * Compute the effective state of both the physical and virtual | ||
| 84 | * senses of carrier. | ||
| 85 | */ | ||
| 86 | |||
| 87 | if (ch->ch_s_mlast & DM_CD) | ||
| 88 | phys_carrier = 1; | ||
| 89 | |||
| 90 | if ((ch->ch_s_mlast & DM_CD) || | ||
| 91 | (ch->ch_digi.digi_flags & DIGI_FORCEDCD) || | ||
| 92 | (ch->ch_flag & CH_CLOCAL)) | ||
| 93 | virt_carrier = 1; | ||
| 94 | |||
| 95 | /* | ||
| 96 | * Test for a VIRTUAL carrier transition to HIGH. | ||
| 97 | * | ||
| 98 | * The CH_HANGUP condition is intended to prevent any action | ||
| 99 | * except for close. As a result, we ignore positive carrier | ||
| 100 | * transitions during CH_HANGUP. | ||
| 101 | */ | ||
| 102 | if (((ch->ch_flag & CH_HANGUP) == 0) && | ||
| 103 | ((ch->ch_flag & CH_VIRT_CD) == 0) && | ||
| 104 | (virt_carrier == 1)) { | ||
| 105 | /* | ||
| 106 | * When carrier rises, wake any threads waiting | ||
| 107 | * for carrier in the open routine. | ||
| 108 | */ | ||
| 109 | nd->nd_tx_work = 1; | ||
| 110 | |||
| 111 | if (waitqueue_active(&ch->ch_flag_wait)) | ||
| 112 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 113 | } | ||
| 114 | |||
| 115 | /* | ||
| 116 | * Test for a PHYSICAL transition to low, so long as we aren't | ||
| 117 | * currently ignoring physical transitions (which is what "virtual | ||
| 118 | * carrier" indicates). | ||
| 119 | * | ||
| 120 | * The transition of the virtual carrier to low really doesn't | ||
| 121 | * matter... it really only means "ignore carrier state", not | ||
| 122 | * "make pretend that carrier is there". | ||
| 123 | */ | ||
| 124 | if ((virt_carrier == 0) && | ||
| 125 | ((ch->ch_flag & CH_PHYS_CD) != 0) && | ||
| 126 | (phys_carrier == 0)) { | ||
| 127 | /* | ||
| 128 | * When carrier drops: | ||
| 129 | * | ||
| 130 | * Do a Hard Hangup if that is called for. | ||
| 131 | * | ||
| 132 | * Drop carrier on all open units. | ||
| 133 | * | ||
| 134 | * Flush queues, waking up any task waiting in the | ||
| 135 | * line discipline. | ||
| 136 | * | ||
| 137 | * Send a hangup to the control terminal. | ||
| 138 | * | ||
| 139 | * Enable all select calls. | ||
| 140 | */ | ||
| 141 | |||
| 142 | nd->nd_tx_work = 1; | ||
| 143 | |||
| 144 | ch->ch_flag &= ~(CH_LOW | CH_EMPTY | CH_DRAIN | CH_INPUT); | ||
| 145 | |||
| 146 | if (waitqueue_active(&ch->ch_flag_wait)) | ||
| 147 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 148 | |||
| 149 | if (ch->ch_tun.un_open_count > 0) | ||
| 150 | tty_hangup(ch->ch_tun.un_tty); | ||
| 151 | |||
| 152 | if (ch->ch_pun.un_open_count > 0) | ||
| 153 | tty_hangup(ch->ch_pun.un_tty); | ||
| 154 | } | ||
| 155 | |||
| 156 | /* | ||
| 157 | * Make sure that our cached values reflect the current reality. | ||
| 158 | */ | ||
| 159 | if (virt_carrier == 1) | ||
| 160 | ch->ch_flag |= CH_VIRT_CD; | ||
| 161 | else | ||
| 162 | ch->ch_flag &= ~CH_VIRT_CD; | ||
| 163 | |||
| 164 | if (phys_carrier == 1) | ||
| 165 | ch->ch_flag |= CH_PHYS_CD; | ||
| 166 | else | ||
| 167 | ch->ch_flag &= ~CH_PHYS_CD; | ||
| 168 | |||
| 169 | } | ||
| 170 | |||
| 171 | /** | ||
| 172 | * dgrp_chk_perm() -- check permissions for net device | ||
| 173 | * @inode: pointer to inode structure for the net communication device | ||
| 174 | * @op: operation to be tested | ||
| 175 | * | ||
| 176 | * The file permissions and ownerships are tested to determine whether | ||
| 177 | * the operation "op" is permitted on the file pointed to by the inode. | ||
| 178 | * Returns 0 if the operation is permitted, -EACCESS otherwise | ||
| 179 | */ | ||
| 180 | int dgrp_chk_perm(int mode, int op) | ||
| 181 | { | ||
| 182 | if (!current_euid()) | ||
| 183 | mode >>= 6; | ||
| 184 | else if (in_egroup_p(0)) | ||
| 185 | mode >>= 3; | ||
| 186 | |||
| 187 | if ((mode & op & 0007) == op) | ||
| 188 | return 0; | ||
| 189 | |||
| 190 | if (capable(CAP_SYS_ADMIN)) | ||
| 191 | return 0; | ||
| 192 | |||
| 193 | return -EACCES; | ||
| 194 | } | ||
| 195 | |||
| 196 | /* dgrp_chk_perm wrapper for permission call in struct inode_operations */ | ||
| 197 | int dgrp_inode_permission(struct inode *inode, int op) | ||
| 198 | { | ||
| 199 | return dgrp_chk_perm(inode->i_mode, op); | ||
| 200 | } | ||
diff --git a/drivers/staging/dgrp/dgrp_common.h b/drivers/staging/dgrp/dgrp_common.h new file mode 100644 index 000000000000..05ff338471ac --- /dev/null +++ b/drivers/staging/dgrp/dgrp_common.h | |||
| @@ -0,0 +1,208 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright 1999 Digi International (www.digi.com) | ||
| 4 | * James Puzzo <jamesp at digi dot com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 9 | * any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the | ||
| 13 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | ||
| 14 | * PURPOSE. See the GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef __DGRP_COMMON_H | ||
| 19 | #define __DGRP_COMMON_H | ||
| 20 | |||
| 21 | #define DIGI_VERSION "1.9-29" | ||
| 22 | |||
| 23 | #include <linux/fs.h> | ||
| 24 | #include <linux/timer.h> | ||
| 25 | #include "drp.h" | ||
| 26 | |||
| 27 | #define DGRP_TTIME 100 | ||
| 28 | #define DGRP_RTIME 100 | ||
| 29 | |||
| 30 | /************************************************************************ | ||
| 31 | * All global storage allocation. | ||
| 32 | ************************************************************************/ | ||
| 33 | |||
| 34 | extern int dgrp_rawreadok; /* Allow raw writing of input */ | ||
| 35 | extern int dgrp_register_cudevices; /* enable legacy cu devices */ | ||
| 36 | extern int dgrp_register_prdevices; /* enable transparent print devices */ | ||
| 37 | extern int dgrp_poll_tick; /* Poll interval - in ms */ | ||
| 38 | |||
| 39 | extern struct list_head nd_struct_list; | ||
| 40 | |||
| 41 | struct dgrp_poll_data { | ||
| 42 | spinlock_t poll_lock; | ||
| 43 | struct timer_list timer; | ||
| 44 | int poll_tick; | ||
| 45 | ulong poll_round; /* Timer rouding factor */ | ||
| 46 | long node_active_count; | ||
| 47 | }; | ||
| 48 | |||
| 49 | extern struct dgrp_poll_data dgrp_poll_data; | ||
| 50 | extern void dgrp_poll_handler(unsigned long arg); | ||
| 51 | |||
| 52 | /* from dgrp_mon_ops.c */ | ||
| 53 | extern void dgrp_register_mon_hook(struct proc_dir_entry *de); | ||
| 54 | |||
| 55 | /* from dgrp_tty.c */ | ||
| 56 | extern int dgrp_tty_init(struct nd_struct *nd); | ||
| 57 | extern void dgrp_tty_uninit(struct nd_struct *nd); | ||
| 58 | |||
| 59 | /* from dgrp_ports_ops.c */ | ||
| 60 | extern void dgrp_register_ports_hook(struct proc_dir_entry *de); | ||
| 61 | |||
| 62 | /* from dgrp_net_ops.c */ | ||
| 63 | extern void dgrp_register_net_hook(struct proc_dir_entry *de); | ||
| 64 | |||
| 65 | /* from dgrp_dpa_ops.c */ | ||
| 66 | extern void dgrp_register_dpa_hook(struct proc_dir_entry *de); | ||
| 67 | extern void dgrp_dpa_data(struct nd_struct *, int, u8 *, int); | ||
| 68 | |||
| 69 | /* from dgrp_sysfs.c */ | ||
| 70 | extern void dgrp_create_class_sysfs_files(void); | ||
| 71 | extern void dgrp_remove_class_sysfs_files(void); | ||
| 72 | |||
| 73 | extern void dgrp_create_node_class_sysfs_files(struct nd_struct *nd); | ||
| 74 | extern void dgrp_remove_node_class_sysfs_files(struct nd_struct *nd); | ||
| 75 | |||
| 76 | extern void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c); | ||
| 77 | extern void dgrp_remove_tty_sysfs(struct device *c); | ||
| 78 | |||
| 79 | /* from dgrp_specproc.c */ | ||
| 80 | /* | ||
| 81 | * The list of DGRP entries with r/w capabilities. These | ||
| 82 | * magic numbers are used for identification purposes. | ||
| 83 | */ | ||
| 84 | enum { | ||
| 85 | DGRP_CONFIG = 1, /* Configure portservers */ | ||
| 86 | DGRP_NETDIR = 2, /* Directory for "net" devices */ | ||
| 87 | DGRP_MONDIR = 3, /* Directory for "mon" devices */ | ||
| 88 | DGRP_PORTSDIR = 4, /* Directory for "ports" devices */ | ||
| 89 | DGRP_INFO = 5, /* Get info. about the running module */ | ||
| 90 | DGRP_NODEINFO = 6, /* Get info. about the configured nodes */ | ||
| 91 | DGRP_DPADIR = 7, /* Directory for the "dpa" devices */ | ||
| 92 | }; | ||
| 93 | |||
| 94 | /* | ||
| 95 | * Directions for proc handlers | ||
| 96 | */ | ||
| 97 | enum { | ||
| 98 | INBOUND = 1, /* Data being written to kernel */ | ||
| 99 | OUTBOUND = 2, /* Data being read from the kernel */ | ||
| 100 | }; | ||
| 101 | |||
| 102 | /** | ||
| 103 | * dgrp_proc_entry: structure for dgrp proc dirs | ||
| 104 | * @id: ID number associated with this particular entry. Should be | ||
| 105 | * unique across all of DGRP. | ||
| 106 | * @name: text name associated with the /proc entry | ||
| 107 | * @mode: file access permisssions for the /proc entry | ||
| 108 | * @child: pointer to table describing a subdirectory for this entry | ||
| 109 | * @de: pointer to directory entry for this object once registered. Used | ||
| 110 | * to grab the handle of the object for unregistration | ||
| 111 | * @excl_sem: semaphore to provide exclusive to struct | ||
| 112 | * @excl_cnt: counter of current accesses | ||
| 113 | * | ||
| 114 | * Each entry in a DGRP proc directory is described with a | ||
| 115 | * dgrp_proc_entry structure. A collection of these | ||
| 116 | * entries (in an array) represents the members associated | ||
| 117 | * with a particular /proc directory, and is referred to | ||
| 118 | * as a table. All tables are terminated by an entry with | ||
| 119 | * zeros for every member. | ||
| 120 | */ | ||
| 121 | struct dgrp_proc_entry { | ||
| 122 | int id; /* Integer identifier */ | ||
| 123 | const char *name; /* ASCII identifier */ | ||
| 124 | mode_t mode; /* File access permissions */ | ||
| 125 | struct dgrp_proc_entry *child; /* Child pointer */ | ||
| 126 | |||
| 127 | /* file ops to use, pass NULL to use default */ | ||
| 128 | struct file_operations *proc_file_ops; | ||
| 129 | |||
| 130 | struct proc_dir_entry *de; /* proc entry pointer */ | ||
| 131 | struct semaphore excl_sem; /* Protects exclusive access var */ | ||
| 132 | int excl_cnt; /* Counts number of curr accesses */ | ||
| 133 | }; | ||
| 134 | |||
| 135 | extern void dgrp_unregister_proc(void); | ||
| 136 | extern void dgrp_register_proc(void); | ||
| 137 | |||
| 138 | /*-----------------------------------------------------------------------* | ||
| 139 | * | ||
| 140 | * Declarations for common operations: | ||
| 141 | * | ||
| 142 | * (either used by more than one of net, mon, or tty, | ||
| 143 | * or in interrupt context (i.e. the poller)) | ||
| 144 | * | ||
| 145 | *-----------------------------------------------------------------------*/ | ||
| 146 | |||
| 147 | void dgrp_carrier(struct ch_struct *ch); | ||
| 148 | extern int dgrp_inode_permission(struct inode *inode, int op); | ||
| 149 | extern int dgrp_chk_perm(int mode, int op); | ||
| 150 | |||
| 151 | |||
| 152 | /* | ||
| 153 | * ID manipulation macros (where c1 & c2 are characters, i is | ||
| 154 | * a long integer, and s is a character array of at least three members | ||
| 155 | */ | ||
| 156 | |||
| 157 | static inline void ID_TO_CHAR(long i, char *s) | ||
| 158 | { | ||
| 159 | s[0] = ((i & 0xff00)>>8); | ||
| 160 | s[1] = (i & 0xff); | ||
| 161 | s[2] = 0; | ||
| 162 | } | ||
| 163 | |||
| 164 | static inline long CHAR_TO_ID(char *s) | ||
| 165 | { | ||
| 166 | return ((s[0] & 0xff) << 8) | (s[1] & 0xff); | ||
| 167 | } | ||
| 168 | |||
| 169 | static inline struct nd_struct *nd_struct_get(long major) | ||
| 170 | { | ||
| 171 | struct nd_struct *nd; | ||
| 172 | |||
| 173 | list_for_each_entry(nd, &nd_struct_list, list) { | ||
| 174 | if (major == nd->nd_major) | ||
| 175 | return nd; | ||
| 176 | } | ||
| 177 | |||
| 178 | return NULL; | ||
| 179 | } | ||
| 180 | |||
| 181 | static inline int nd_struct_add(struct nd_struct *entry) | ||
| 182 | { | ||
| 183 | struct nd_struct *ptr; | ||
| 184 | |||
| 185 | ptr = nd_struct_get(entry->nd_major); | ||
| 186 | |||
| 187 | if (ptr) | ||
| 188 | return -EBUSY; | ||
| 189 | |||
| 190 | list_add_tail(&entry->list, &nd_struct_list); | ||
| 191 | |||
| 192 | return 0; | ||
| 193 | } | ||
| 194 | |||
| 195 | static inline int nd_struct_del(struct nd_struct *entry) | ||
| 196 | { | ||
| 197 | struct nd_struct *nd; | ||
| 198 | |||
| 199 | nd = nd_struct_get(entry->nd_major); | ||
| 200 | |||
| 201 | if (!nd) | ||
| 202 | return -ENODEV; | ||
| 203 | |||
| 204 | list_del(&nd->list); | ||
| 205 | return 0; | ||
| 206 | } | ||
| 207 | |||
| 208 | #endif /* __DGRP_COMMON_H */ | ||
diff --git a/drivers/staging/dgrp/dgrp_dpa_ops.c b/drivers/staging/dgrp/dgrp_dpa_ops.c new file mode 100644 index 000000000000..49e670915e5c --- /dev/null +++ b/drivers/staging/dgrp/dgrp_dpa_ops.c | |||
| @@ -0,0 +1,556 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright 1999 Digi International (www.digi.com) | ||
| 4 | * James Puzzo <jamesp at digi dot com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 9 | * any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the | ||
| 13 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | ||
| 14 | * PURPOSE. See the GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* | ||
| 19 | * | ||
| 20 | * Filename: | ||
| 21 | * | ||
| 22 | * dgrp_dpa_ops.c | ||
| 23 | * | ||
| 24 | * Description: | ||
| 25 | * | ||
| 26 | * Handle the file operations required for the "dpa" devices. | ||
| 27 | * Includes those functions required to register the "dpa" devices | ||
| 28 | * in "/proc". | ||
| 29 | * | ||
| 30 | * Author: | ||
| 31 | * | ||
| 32 | * James A. Puzzo | ||
| 33 | * | ||
| 34 | */ | ||
| 35 | |||
| 36 | #include <linux/module.h> | ||
| 37 | #include <linux/proc_fs.h> | ||
| 38 | #include <linux/tty.h> | ||
| 39 | #include <linux/poll.h> | ||
| 40 | #include <linux/cred.h> | ||
| 41 | #include <linux/sched.h> | ||
| 42 | #include <linux/ratelimit.h> | ||
| 43 | #include <asm/unaligned.h> | ||
| 44 | |||
| 45 | #include "dgrp_common.h" | ||
| 46 | |||
| 47 | /* File operation declarations */ | ||
| 48 | static int dgrp_dpa_open(struct inode *, struct file *); | ||
| 49 | static int dgrp_dpa_release(struct inode *, struct file *); | ||
| 50 | static ssize_t dgrp_dpa_read(struct file *, char __user *, size_t, loff_t *); | ||
| 51 | static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd, | ||
| 52 | unsigned long arg); | ||
| 53 | static unsigned int dgrp_dpa_select(struct file *, struct poll_table_struct *); | ||
| 54 | |||
| 55 | static const struct file_operations dpa_ops = { | ||
| 56 | .owner = THIS_MODULE, | ||
| 57 | .read = dgrp_dpa_read, | ||
| 58 | .poll = dgrp_dpa_select, | ||
| 59 | .unlocked_ioctl = dgrp_dpa_ioctl, | ||
| 60 | .open = dgrp_dpa_open, | ||
| 61 | .release = dgrp_dpa_release, | ||
| 62 | }; | ||
| 63 | |||
| 64 | static struct inode_operations dpa_inode_ops = { | ||
| 65 | .permission = dgrp_inode_permission | ||
| 66 | }; | ||
| 67 | |||
| 68 | |||
| 69 | |||
| 70 | struct digi_node { | ||
| 71 | uint nd_state; /* Node state: 1 = up, 0 = down. */ | ||
| 72 | uint nd_chan_count; /* Number of channels found */ | ||
| 73 | uint nd_tx_byte; /* Tx data count */ | ||
| 74 | uint nd_rx_byte; /* RX data count */ | ||
| 75 | u8 nd_ps_desc[MAX_DESC_LEN]; /* Description from PS */ | ||
| 76 | }; | ||
| 77 | |||
| 78 | #define DIGI_GETNODE (('d'<<8) | 249) /* get board info */ | ||
| 79 | |||
| 80 | |||
| 81 | struct digi_chan { | ||
| 82 | uint ch_port; /* Port number to get info on */ | ||
| 83 | uint ch_open; /* 1 if open, 0 if not */ | ||
| 84 | uint ch_txcount; /* TX data count */ | ||
| 85 | uint ch_rxcount; /* RX data count */ | ||
| 86 | uint ch_s_brate; /* Realport BRATE */ | ||
| 87 | uint ch_s_estat; /* Realport ELAST */ | ||
| 88 | uint ch_s_cflag; /* Realport CFLAG */ | ||
| 89 | uint ch_s_iflag; /* Realport IFLAG */ | ||
| 90 | uint ch_s_oflag; /* Realport OFLAG */ | ||
| 91 | uint ch_s_xflag; /* Realport XFLAG */ | ||
| 92 | uint ch_s_mstat; /* Realport MLAST */ | ||
| 93 | }; | ||
| 94 | |||
| 95 | #define DIGI_GETCHAN (('d'<<8) | 248) /* get channel info */ | ||
| 96 | |||
| 97 | |||
| 98 | struct digi_vpd { | ||
| 99 | int vpd_len; | ||
| 100 | char vpd_data[VPDSIZE]; | ||
| 101 | }; | ||
| 102 | |||
| 103 | #define DIGI_GETVPD (('d'<<8) | 246) /* get VPD info */ | ||
| 104 | |||
| 105 | |||
| 106 | struct digi_debug { | ||
| 107 | int onoff; | ||
| 108 | int port; | ||
| 109 | }; | ||
| 110 | |||
| 111 | #define DIGI_SETDEBUG (('d'<<8) | 247) /* set debug info */ | ||
| 112 | |||
| 113 | |||
| 114 | void dgrp_register_dpa_hook(struct proc_dir_entry *de) | ||
| 115 | { | ||
| 116 | struct nd_struct *node = de->data; | ||
| 117 | |||
| 118 | de->proc_iops = &dpa_inode_ops; | ||
| 119 | de->proc_fops = &dpa_ops; | ||
| 120 | |||
| 121 | node->nd_dpa_de = de; | ||
| 122 | spin_lock_init(&node->nd_dpa_lock); | ||
| 123 | } | ||
| 124 | |||
| 125 | /* | ||
| 126 | * dgrp_dpa_open -- open the DPA device for a particular PortServer | ||
| 127 | */ | ||
| 128 | static int dgrp_dpa_open(struct inode *inode, struct file *file) | ||
| 129 | { | ||
| 130 | struct nd_struct *nd; | ||
| 131 | int rtn = 0; | ||
| 132 | |||
| 133 | struct proc_dir_entry *de; | ||
| 134 | |||
| 135 | rtn = try_module_get(THIS_MODULE); | ||
| 136 | if (!rtn) | ||
| 137 | return -ENXIO; | ||
| 138 | |||
| 139 | rtn = 0; | ||
| 140 | |||
| 141 | if (!capable(CAP_SYS_ADMIN)) { | ||
| 142 | rtn = -EPERM; | ||
| 143 | goto done; | ||
| 144 | } | ||
| 145 | |||
| 146 | /* | ||
| 147 | * Make sure that the "private_data" field hasn't already been used. | ||
| 148 | */ | ||
| 149 | if (file->private_data) { | ||
| 150 | rtn = -EINVAL; | ||
| 151 | goto done; | ||
| 152 | } | ||
| 153 | |||
| 154 | /* | ||
| 155 | * Get the node pointer, and fail if it doesn't exist. | ||
| 156 | */ | ||
| 157 | de = PDE(inode); | ||
| 158 | if (!de) { | ||
| 159 | rtn = -ENXIO; | ||
| 160 | goto done; | ||
| 161 | } | ||
| 162 | nd = (struct nd_struct *)de->data; | ||
| 163 | if (!nd) { | ||
| 164 | rtn = -ENXIO; | ||
| 165 | goto done; | ||
| 166 | } | ||
| 167 | |||
| 168 | file->private_data = (void *) nd; | ||
| 169 | |||
| 170 | /* | ||
| 171 | * Allocate the DPA buffer. | ||
| 172 | */ | ||
| 173 | |||
| 174 | if (nd->nd_dpa_buf) { | ||
| 175 | rtn = -EBUSY; | ||
| 176 | } else { | ||
| 177 | nd->nd_dpa_buf = kmalloc(DPA_MAX, GFP_KERNEL); | ||
| 178 | |||
| 179 | if (!nd->nd_dpa_buf) { | ||
| 180 | rtn = -ENOMEM; | ||
| 181 | } else { | ||
| 182 | nd->nd_dpa_out = 0; | ||
| 183 | nd->nd_dpa_in = 0; | ||
| 184 | nd->nd_dpa_lbolt = jiffies; | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | done: | ||
| 189 | |||
| 190 | if (rtn) | ||
| 191 | module_put(THIS_MODULE); | ||
| 192 | return rtn; | ||
| 193 | } | ||
| 194 | |||
| 195 | /* | ||
| 196 | * dgrp_dpa_release -- close the DPA device for a particular PortServer | ||
| 197 | */ | ||
| 198 | static int dgrp_dpa_release(struct inode *inode, struct file *file) | ||
| 199 | { | ||
| 200 | struct nd_struct *nd; | ||
| 201 | u8 *buf; | ||
| 202 | unsigned long lock_flags; | ||
| 203 | |||
| 204 | /* | ||
| 205 | * Get the node pointer, and quit if it doesn't exist. | ||
| 206 | */ | ||
| 207 | nd = (struct nd_struct *)(file->private_data); | ||
| 208 | if (!nd) | ||
| 209 | goto done; | ||
| 210 | |||
| 211 | /* | ||
| 212 | * Free the dpa buffer. | ||
| 213 | */ | ||
| 214 | |||
| 215 | spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags); | ||
| 216 | |||
| 217 | buf = nd->nd_dpa_buf; | ||
| 218 | |||
| 219 | nd->nd_dpa_buf = NULL; | ||
| 220 | nd->nd_dpa_out = nd->nd_dpa_in; | ||
| 221 | |||
| 222 | /* | ||
| 223 | * Wakeup any thread waiting for buffer space. | ||
| 224 | */ | ||
| 225 | |||
| 226 | if (nd->nd_dpa_flag & DPA_WAIT_SPACE) { | ||
| 227 | nd->nd_dpa_flag &= ~DPA_WAIT_SPACE; | ||
| 228 | wake_up_interruptible(&nd->nd_dpa_wqueue); | ||
| 229 | } | ||
| 230 | |||
| 231 | spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags); | ||
| 232 | |||
| 233 | kfree(buf); | ||
| 234 | |||
| 235 | done: | ||
| 236 | module_put(THIS_MODULE); | ||
| 237 | file->private_data = NULL; | ||
| 238 | return 0; | ||
| 239 | } | ||
| 240 | |||
| 241 | /* | ||
| 242 | * dgrp_dpa_read | ||
| 243 | * | ||
| 244 | * Copy data from the monitoring buffer to the user, freeing space | ||
| 245 | * in the monitoring buffer for more messages | ||
| 246 | */ | ||
| 247 | static ssize_t dgrp_dpa_read(struct file *file, char __user *buf, size_t count, | ||
| 248 | loff_t *ppos) | ||
| 249 | { | ||
| 250 | struct nd_struct *nd; | ||
| 251 | int n; | ||
| 252 | int r; | ||
| 253 | int offset = 0; | ||
| 254 | int res = 0; | ||
| 255 | ssize_t rtn; | ||
| 256 | unsigned long lock_flags; | ||
| 257 | |||
| 258 | /* | ||
| 259 | * Get the node pointer, and quit if it doesn't exist. | ||
| 260 | */ | ||
| 261 | nd = (struct nd_struct *)(file->private_data); | ||
| 262 | if (!nd) | ||
| 263 | return -ENXIO; | ||
| 264 | |||
| 265 | /* | ||
| 266 | * Wait for some data to appear in the buffer. | ||
| 267 | */ | ||
| 268 | |||
| 269 | spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags); | ||
| 270 | |||
| 271 | for (;;) { | ||
| 272 | n = (nd->nd_dpa_in - nd->nd_dpa_out) & DPA_MASK; | ||
| 273 | |||
| 274 | if (n != 0) | ||
| 275 | break; | ||
| 276 | |||
| 277 | nd->nd_dpa_flag |= DPA_WAIT_DATA; | ||
| 278 | |||
| 279 | spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags); | ||
| 280 | |||
| 281 | /* | ||
| 282 | * Go to sleep waiting until the condition becomes true. | ||
| 283 | */ | ||
| 284 | rtn = wait_event_interruptible(nd->nd_dpa_wqueue, | ||
| 285 | ((nd->nd_dpa_flag & DPA_WAIT_DATA) == 0)); | ||
| 286 | |||
| 287 | if (rtn) | ||
| 288 | return rtn; | ||
| 289 | |||
| 290 | spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags); | ||
| 291 | } | ||
| 292 | |||
| 293 | /* | ||
| 294 | * Read whatever is there. | ||
| 295 | */ | ||
| 296 | |||
| 297 | if (n > count) | ||
| 298 | n = count; | ||
| 299 | |||
| 300 | res = n; | ||
| 301 | |||
| 302 | r = DPA_MAX - nd->nd_dpa_out; | ||
| 303 | |||
| 304 | if (r <= n) { | ||
| 305 | |||
| 306 | spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags); | ||
| 307 | rtn = copy_to_user((void __user *)buf, | ||
| 308 | nd->nd_dpa_buf + nd->nd_dpa_out, r); | ||
| 309 | spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags); | ||
| 310 | |||
| 311 | if (rtn) { | ||
| 312 | rtn = -EFAULT; | ||
| 313 | goto done; | ||
| 314 | } | ||
| 315 | |||
| 316 | nd->nd_dpa_out = 0; | ||
| 317 | n -= r; | ||
| 318 | offset = r; | ||
| 319 | } | ||
| 320 | |||
| 321 | spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags); | ||
| 322 | rtn = copy_to_user((void __user *)buf + offset, | ||
| 323 | nd->nd_dpa_buf + nd->nd_dpa_out, n); | ||
| 324 | spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags); | ||
| 325 | |||
| 326 | if (rtn) { | ||
| 327 | rtn = -EFAULT; | ||
| 328 | goto done; | ||
| 329 | } | ||
| 330 | |||
| 331 | nd->nd_dpa_out += n; | ||
| 332 | |||
| 333 | *ppos += res; | ||
| 334 | |||
| 335 | rtn = res; | ||
| 336 | |||
| 337 | /* | ||
| 338 | * Wakeup any thread waiting for buffer space. | ||
| 339 | */ | ||
| 340 | |||
| 341 | n = (nd->nd_dpa_in - nd->nd_dpa_out) & DPA_MASK; | ||
| 342 | |||
| 343 | if (nd->nd_dpa_flag & DPA_WAIT_SPACE && | ||
| 344 | (DPA_MAX - n) > DPA_HIGH_WATER) { | ||
| 345 | nd->nd_dpa_flag &= ~DPA_WAIT_SPACE; | ||
| 346 | wake_up_interruptible(&nd->nd_dpa_wqueue); | ||
| 347 | } | ||
| 348 | |||
| 349 | done: | ||
| 350 | spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags); | ||
| 351 | return rtn; | ||
| 352 | } | ||
| 353 | |||
| 354 | static unsigned int dgrp_dpa_select(struct file *file, | ||
| 355 | struct poll_table_struct *table) | ||
| 356 | { | ||
| 357 | unsigned int retval = 0; | ||
| 358 | struct nd_struct *nd = file->private_data; | ||
| 359 | |||
| 360 | if (nd->nd_dpa_out != nd->nd_dpa_in) | ||
| 361 | retval |= POLLIN | POLLRDNORM; /* Conditionally readable */ | ||
| 362 | |||
| 363 | retval |= POLLOUT | POLLWRNORM; /* Always writeable */ | ||
| 364 | |||
| 365 | return retval; | ||
| 366 | } | ||
| 367 | |||
| 368 | static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd, | ||
| 369 | unsigned long arg) | ||
| 370 | { | ||
| 371 | |||
| 372 | struct nd_struct *nd; | ||
| 373 | struct digi_chan getchan; | ||
| 374 | struct digi_node getnode; | ||
| 375 | struct ch_struct *ch; | ||
| 376 | struct digi_debug setdebug; | ||
| 377 | struct digi_vpd vpd; | ||
| 378 | unsigned int port; | ||
| 379 | void __user *uarg = (void __user *) arg; | ||
| 380 | |||
| 381 | nd = file->private_data; | ||
| 382 | |||
| 383 | switch (cmd) { | ||
| 384 | case DIGI_GETCHAN: | ||
| 385 | if (copy_from_user(&getchan, uarg, sizeof(struct digi_chan))) | ||
| 386 | return -EFAULT; | ||
| 387 | |||
| 388 | port = getchan.ch_port; | ||
| 389 | |||
| 390 | if (port < 0 || port > nd->nd_chan_count) | ||
| 391 | return -EINVAL; | ||
| 392 | |||
| 393 | ch = nd->nd_chan + port; | ||
| 394 | |||
| 395 | getchan.ch_open = (ch->ch_open_count > 0) ? 1 : 0; | ||
| 396 | getchan.ch_txcount = ch->ch_txcount; | ||
| 397 | getchan.ch_rxcount = ch->ch_rxcount; | ||
| 398 | getchan.ch_s_brate = ch->ch_s_brate; | ||
| 399 | getchan.ch_s_estat = ch->ch_s_elast; | ||
| 400 | getchan.ch_s_cflag = ch->ch_s_cflag; | ||
| 401 | getchan.ch_s_iflag = ch->ch_s_iflag; | ||
| 402 | getchan.ch_s_oflag = ch->ch_s_oflag; | ||
| 403 | getchan.ch_s_xflag = ch->ch_s_xflag; | ||
| 404 | getchan.ch_s_mstat = ch->ch_s_mlast; | ||
| 405 | |||
| 406 | if (copy_to_user(uarg, &getchan, sizeof(struct digi_chan))) | ||
| 407 | return -EFAULT; | ||
| 408 | break; | ||
| 409 | |||
| 410 | |||
| 411 | case DIGI_GETNODE: | ||
| 412 | getnode.nd_state = (nd->nd_state & NS_READY) ? 1 : 0; | ||
| 413 | getnode.nd_chan_count = nd->nd_chan_count; | ||
| 414 | getnode.nd_tx_byte = nd->nd_tx_byte; | ||
| 415 | getnode.nd_rx_byte = nd->nd_rx_byte; | ||
| 416 | |||
| 417 | memset(&getnode.nd_ps_desc, 0, MAX_DESC_LEN); | ||
| 418 | strncpy(getnode.nd_ps_desc, nd->nd_ps_desc, MAX_DESC_LEN); | ||
| 419 | |||
| 420 | if (copy_to_user(uarg, &getnode, sizeof(struct digi_node))) | ||
| 421 | return -EFAULT; | ||
| 422 | break; | ||
| 423 | |||
| 424 | |||
| 425 | case DIGI_SETDEBUG: | ||
| 426 | if (copy_from_user(&setdebug, uarg, sizeof(struct digi_debug))) | ||
| 427 | return -EFAULT; | ||
| 428 | |||
| 429 | nd->nd_dpa_debug = setdebug.onoff; | ||
| 430 | nd->nd_dpa_port = setdebug.port; | ||
| 431 | break; | ||
| 432 | |||
| 433 | |||
| 434 | case DIGI_GETVPD: | ||
| 435 | if (nd->nd_vpd_len > 0) { | ||
| 436 | vpd.vpd_len = nd->nd_vpd_len; | ||
| 437 | memcpy(&vpd.vpd_data, &nd->nd_vpd, nd->nd_vpd_len); | ||
| 438 | } else { | ||
| 439 | vpd.vpd_len = 0; | ||
| 440 | } | ||
| 441 | |||
| 442 | if (copy_to_user(uarg, &vpd, sizeof(struct digi_vpd))) | ||
| 443 | return -EFAULT; | ||
| 444 | break; | ||
| 445 | } | ||
| 446 | |||
| 447 | return 0; | ||
| 448 | } | ||
| 449 | |||
| 450 | /** | ||
| 451 | * dgrp_dpa() -- send data to the device monitor queue | ||
| 452 | * @nd: pointer to a node structure | ||
| 453 | * @buf: buffer of data to copy to the monitoring buffer | ||
| 454 | * @len: number of bytes to transfer to the buffer | ||
| 455 | * | ||
| 456 | * Called by the net device routines to send data to the device | ||
| 457 | * monitor queue. If the device monitor buffer is too full to | ||
| 458 | * accept the data, it waits until the buffer is ready. | ||
| 459 | */ | ||
| 460 | static void dgrp_dpa(struct nd_struct *nd, u8 *buf, int nbuf) | ||
| 461 | { | ||
| 462 | int n; | ||
| 463 | int r; | ||
| 464 | unsigned long lock_flags; | ||
| 465 | |||
| 466 | /* | ||
| 467 | * Grab DPA lock. | ||
| 468 | */ | ||
| 469 | spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags); | ||
| 470 | |||
| 471 | /* | ||
| 472 | * Loop while data remains. | ||
| 473 | */ | ||
| 474 | while (nbuf > 0 && nd->nd_dpa_buf != NULL) { | ||
| 475 | |||
| 476 | n = (nd->nd_dpa_out - nd->nd_dpa_in - 1) & DPA_MASK; | ||
| 477 | |||
| 478 | /* | ||
| 479 | * Enforce flow control on the DPA device. | ||
| 480 | */ | ||
| 481 | if (n < (DPA_MAX - DPA_HIGH_WATER)) | ||
| 482 | nd->nd_dpa_flag |= DPA_WAIT_SPACE; | ||
| 483 | |||
| 484 | /* | ||
| 485 | * This should never happen, as the flow control above | ||
| 486 | * should have stopped things before they got to this point. | ||
| 487 | */ | ||
| 488 | if (n == 0) { | ||
| 489 | spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags); | ||
| 490 | return; | ||
| 491 | } | ||
| 492 | |||
| 493 | /* | ||
| 494 | * Copy as much data as will fit. | ||
| 495 | */ | ||
| 496 | |||
| 497 | if (n > nbuf) | ||
| 498 | n = nbuf; | ||
| 499 | |||
| 500 | r = DPA_MAX - nd->nd_dpa_in; | ||
| 501 | |||
| 502 | if (r <= n) { | ||
| 503 | memcpy(nd->nd_dpa_buf + nd->nd_dpa_in, buf, r); | ||
| 504 | |||
| 505 | n -= r; | ||
| 506 | |||
| 507 | nd->nd_dpa_in = 0; | ||
| 508 | |||
| 509 | buf += r; | ||
| 510 | nbuf -= r; | ||
| 511 | } | ||
| 512 | |||
| 513 | memcpy(nd->nd_dpa_buf + nd->nd_dpa_in, buf, n); | ||
| 514 | |||
| 515 | nd->nd_dpa_in += n; | ||
| 516 | |||
| 517 | buf += n; | ||
| 518 | nbuf -= n; | ||
| 519 | |||
| 520 | if (nd->nd_dpa_in >= DPA_MAX) | ||
| 521 | pr_info_ratelimited("%s - nd->nd_dpa_in (%i) >= DPA_MAX\n", | ||
| 522 | __func__, nd->nd_dpa_in); | ||
| 523 | |||
| 524 | /* | ||
| 525 | * Wakeup any thread waiting for data | ||
| 526 | */ | ||
| 527 | if (nd->nd_dpa_flag & DPA_WAIT_DATA) { | ||
| 528 | nd->nd_dpa_flag &= ~DPA_WAIT_DATA; | ||
| 529 | wake_up_interruptible(&nd->nd_dpa_wqueue); | ||
| 530 | } | ||
| 531 | } | ||
| 532 | |||
| 533 | /* | ||
| 534 | * Release the DPA lock. | ||
| 535 | */ | ||
| 536 | spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags); | ||
| 537 | } | ||
| 538 | |||
| 539 | /** | ||
| 540 | * dgrp_monitor_data() -- builds a DPA data packet | ||
| 541 | * @nd: pointer to a node structure | ||
| 542 | * @type: type of message to be logged in the DPA buffer | ||
| 543 | * @buf: buffer of data to be logged in the DPA buffer | ||
| 544 | * @size -- number of bytes in the "buf" buffer | ||
| 545 | */ | ||
| 546 | void dgrp_dpa_data(struct nd_struct *nd, int type, u8 *buf, int size) | ||
| 547 | { | ||
| 548 | u8 header[5]; | ||
| 549 | |||
| 550 | header[0] = type; | ||
| 551 | |||
| 552 | put_unaligned_be32(size, header + 1); | ||
| 553 | |||
| 554 | dgrp_dpa(nd, header, sizeof(header)); | ||
| 555 | dgrp_dpa(nd, buf, size); | ||
| 556 | } | ||
diff --git a/drivers/staging/dgrp/dgrp_driver.c b/drivers/staging/dgrp/dgrp_driver.c new file mode 100644 index 000000000000..6e4a0ebc0749 --- /dev/null +++ b/drivers/staging/dgrp/dgrp_driver.c | |||
| @@ -0,0 +1,110 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright 1999-2003 Digi International (www.digi.com) | ||
| 4 | * Jeff Randall | ||
| 5 | * James Puzzo <jamesp at digi dot com> | ||
| 6 | * Scott Kilau <Scott_Kilau at digi dot com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 11 | * any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the | ||
| 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | ||
| 16 | * PURPOSE. See the GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | */ | ||
| 19 | |||
| 20 | /* | ||
| 21 | * Driver specific includes | ||
| 22 | */ | ||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/slab.h> | ||
| 25 | #include <linux/tty.h> | ||
| 26 | #include <linux/init.h> | ||
| 27 | |||
| 28 | /* | ||
| 29 | * PortServer includes | ||
| 30 | */ | ||
| 31 | #include "dgrp_common.h" | ||
| 32 | |||
| 33 | |||
| 34 | MODULE_LICENSE("GPL"); | ||
| 35 | MODULE_AUTHOR("Digi International, http://www.digi.com"); | ||
| 36 | MODULE_DESCRIPTION("RealPort driver for Digi's ethernet-based serial connectivity product line"); | ||
| 37 | MODULE_VERSION(DIGI_VERSION); | ||
| 38 | |||
| 39 | struct list_head nd_struct_list; | ||
| 40 | struct dgrp_poll_data dgrp_poll_data; | ||
| 41 | |||
| 42 | int dgrp_rawreadok = 1; /* Bypass flipbuf on input */ | ||
| 43 | int dgrp_register_cudevices = 1;/* Turn on/off registering legacy cu devices */ | ||
| 44 | int dgrp_register_prdevices = 1;/* Turn on/off registering transparent print */ | ||
| 45 | int dgrp_poll_tick = 20; /* Poll interval - in ms */ | ||
| 46 | |||
| 47 | module_param_named(rawreadok, dgrp_rawreadok, int, 0644); | ||
| 48 | MODULE_PARM_DESC(rawreadok, "Bypass flip buffers on input"); | ||
| 49 | |||
| 50 | module_param_named(register_cudevices, dgrp_register_cudevices, int, 0644); | ||
| 51 | MODULE_PARM_DESC(register_cudevices, "Turn on/off registering legacy cu devices"); | ||
| 52 | |||
| 53 | module_param_named(register_prdevices, dgrp_register_prdevices, int, 0644); | ||
| 54 | MODULE_PARM_DESC(register_prdevices, "Turn on/off registering transparent print devices"); | ||
| 55 | |||
| 56 | module_param_named(pollrate, dgrp_poll_tick, int, 0644); | ||
| 57 | MODULE_PARM_DESC(pollrate, "Poll interval in ms"); | ||
| 58 | |||
| 59 | /* Driver load/unload functions */ | ||
| 60 | static int dgrp_init_module(void); | ||
| 61 | static void dgrp_cleanup_module(void); | ||
| 62 | |||
| 63 | module_init(dgrp_init_module); | ||
| 64 | module_exit(dgrp_cleanup_module); | ||
| 65 | |||
| 66 | /* | ||
| 67 | * init_module() | ||
| 68 | * | ||
| 69 | * Module load. This is where it all starts. | ||
| 70 | */ | ||
| 71 | static int dgrp_init_module(void) | ||
| 72 | { | ||
| 73 | INIT_LIST_HEAD(&nd_struct_list); | ||
| 74 | |||
| 75 | spin_lock_init(&dgrp_poll_data.poll_lock); | ||
| 76 | init_timer(&dgrp_poll_data.timer); | ||
| 77 | dgrp_poll_data.poll_tick = dgrp_poll_tick; | ||
| 78 | dgrp_poll_data.timer.function = dgrp_poll_handler; | ||
| 79 | dgrp_poll_data.timer.data = (unsigned long) &dgrp_poll_data; | ||
| 80 | |||
| 81 | dgrp_create_class_sysfs_files(); | ||
| 82 | |||
| 83 | dgrp_register_proc(); | ||
| 84 | |||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | |||
| 88 | |||
| 89 | /* | ||
| 90 | * Module unload. This is where it all ends. | ||
| 91 | */ | ||
| 92 | static void dgrp_cleanup_module(void) | ||
| 93 | { | ||
| 94 | struct nd_struct *nd, *next; | ||
| 95 | |||
| 96 | /* | ||
| 97 | * Attempting to free resources in backwards | ||
| 98 | * order of allocation, in case that helps | ||
| 99 | * memory pool fragmentation. | ||
| 100 | */ | ||
| 101 | dgrp_unregister_proc(); | ||
| 102 | |||
| 103 | dgrp_remove_class_sysfs_files(); | ||
| 104 | |||
| 105 | |||
| 106 | list_for_each_entry_safe(nd, next, &nd_struct_list, list) { | ||
| 107 | dgrp_tty_uninit(nd); | ||
| 108 | kfree(nd); | ||
| 109 | } | ||
| 110 | } | ||
diff --git a/drivers/staging/dgrp/dgrp_mon_ops.c b/drivers/staging/dgrp/dgrp_mon_ops.c new file mode 100644 index 000000000000..268dcb95204b --- /dev/null +++ b/drivers/staging/dgrp/dgrp_mon_ops.c | |||
| @@ -0,0 +1,346 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * Copyright 1999 Digi International (www.digi.com) | ||
| 4 | * James Puzzo <jamesp at digi dot com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 9 | * any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the | ||
| 13 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | ||
| 14 | * PURPOSE. See the GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* | ||
| 19 | * | ||
| 20 | * Filename: | ||
| 21 | * | ||
| 22 | * dgrp_mon_ops.c | ||
| 23 | * | ||
| 24 | * Description: | ||
| 25 | * | ||
| 26 | * Handle the file operations required for the "monitor" devices. | ||
| 27 | * Includes those functions required to register the "mon" devices | ||
| 28 | * in "/proc". | ||
| 29 | * | ||
| 30 | * Author: | ||
| 31 | * | ||
| 32 | * James A. Puzzo | ||
| 33 | * | ||
| 34 | */ | ||
| 35 | |||
| 36 | #include <linux/module.h> | ||
| 37 | #include <linux/tty.h> | ||
| 38 | #include <linux/sched.h> | ||
| 39 | #include <asm/unaligned.h> | ||
| 40 | #include <linux/proc_fs.h> | ||
| 41 | |||
| 42 | #include "dgrp_common.h" | ||
| 43 | |||
| 44 | /* File operation declarations */ | ||
| 45 | static int dgrp_mon_open(struct inode *, struct file *); | ||
| 46 | static int dgrp_mon_release(struct inode *, struct file *); | ||
| 47 | static ssize_t dgrp_mon_read(struct file *, char __user *, size_t, loff_t *); | ||
| 48 | static long dgrp_mon_ioctl(struct file *file, unsigned int cmd, | ||
| 49 | unsigned long arg); | ||
| 50 | |||
| 51 | static const struct file_operations mon_ops = { | ||
| 52 | .owner = THIS_MODULE, | ||
| 53 | .read = dgrp_mon_read, | ||
| 54 | .unlocked_ioctl = dgrp_mon_ioctl, | ||
| 55 | .open = dgrp_mon_open, | ||
| 56 | .release = dgrp_mon_release, | ||
| 57 | }; | ||
| 58 | |||
| 59 | static struct inode_operations mon_inode_ops = { | ||
| 60 | .permission = dgrp_inode_permission | ||
| 61 | }; | ||
| 62 | |||
| 63 | void dgrp_register_mon_hook(struct proc_dir_entry *de) | ||
| 64 | { | ||
| 65 | struct nd_struct *node = de->data; | ||
| 66 | |||
| 67 | de->proc_iops = &mon_inode_ops; | ||
| 68 | de->proc_fops = &mon_ops; | ||
| 69 | node->nd_mon_de = de; | ||
| 70 | sema_init(&node->nd_mon_semaphore, 1); | ||
| 71 | } | ||
| 72 | |||
| 73 | /** | ||
| 74 | * dgrp_mon_open() -- open /proc/dgrp/ports device for a PortServer | ||
| 75 | * @inode: struct inode * | ||
| 76 | * @file: struct file * | ||
| 77 | * | ||
| 78 | * Open function to open the /proc/dgrp/ports device for a PortServer. | ||
| 79 | */ | ||
| 80 | static int dgrp_mon_open(struct inode *inode, struct file *file) | ||
| 81 | { | ||
| 82 | struct nd_struct *nd; | ||
| 83 | struct proc_dir_entry *de; | ||
| 84 | struct timeval tv; | ||
| 85 | uint32_t time; | ||
| 86 | u8 *buf; | ||
| 87 | int rtn; | ||
| 88 | |||
| 89 | rtn = try_module_get(THIS_MODULE); | ||
| 90 | if (!rtn) | ||
| 91 | return -ENXIO; | ||
| 92 | |||
| 93 | rtn = 0; | ||
| 94 | |||
| 95 | if (!capable(CAP_SYS_ADMIN)) { | ||
| 96 | rtn = -EPERM; | ||
| 97 | goto done; | ||
| 98 | } | ||
| 99 | |||
| 100 | /* | ||
| 101 | * Make sure that the "private_data" field hasn't already been used. | ||
| 102 | */ | ||
| 103 | if (file->private_data) { | ||
| 104 | rtn = -EINVAL; | ||
| 105 | goto done; | ||
| 106 | } | ||
| 107 | |||
| 108 | /* | ||
| 109 | * Get the node pointer, and fail if it doesn't exist. | ||
| 110 | */ | ||
| 111 | de = PDE(inode); | ||
| 112 | if (!de) { | ||
| 113 | rtn = -ENXIO; | ||
| 114 | goto done; | ||
| 115 | } | ||
| 116 | |||
| 117 | nd = (struct nd_struct *)de->data; | ||
| 118 | if (!nd) { | ||
| 119 | rtn = -ENXIO; | ||
| 120 | goto done; | ||
| 121 | } | ||
| 122 | |||
| 123 | file->private_data = (void *) nd; | ||
| 124 | |||
| 125 | /* | ||
| 126 | * Allocate the monitor buffer. | ||
| 127 | */ | ||
| 128 | |||
| 129 | /* | ||
| 130 | * Grab the MON lock. | ||
| 131 | */ | ||
| 132 | down(&nd->nd_mon_semaphore); | ||
| 133 | |||
| 134 | if (nd->nd_mon_buf) { | ||
| 135 | rtn = -EBUSY; | ||
| 136 | goto done_up; | ||
| 137 | } | ||
| 138 | |||
| 139 | nd->nd_mon_buf = kmalloc(MON_MAX, GFP_KERNEL); | ||
| 140 | |||
| 141 | if (!nd->nd_mon_buf) { | ||
| 142 | rtn = -ENOMEM; | ||
| 143 | goto done_up; | ||
| 144 | } | ||
| 145 | |||
| 146 | /* | ||
| 147 | * Enter an RPDUMP file header into the buffer. | ||
| 148 | */ | ||
| 149 | |||
| 150 | buf = nd->nd_mon_buf; | ||
| 151 | |||
| 152 | strcpy(buf, RPDUMP_MAGIC); | ||
| 153 | buf += strlen(buf) + 1; | ||
| 154 | |||
| 155 | do_gettimeofday(&tv); | ||
| 156 | |||
| 157 | /* | ||
| 158 | * tv.tv_sec might be a 64 bit quantity. Pare | ||
| 159 | * it down to 32 bits before attempting to encode | ||
| 160 | * it. | ||
| 161 | */ | ||
| 162 | time = (uint32_t) (tv.tv_sec & 0xffffffff); | ||
| 163 | |||
| 164 | put_unaligned_be32(time, buf); | ||
| 165 | put_unaligned_be16(0, buf + 4); | ||
| 166 | buf += 6; | ||
| 167 | |||
| 168 | if (nd->nd_tx_module) { | ||
| 169 | buf[0] = RPDUMP_CLIENT; | ||
| 170 | put_unaligned_be32(0, buf + 1); | ||
| 171 | put_unaligned_be16(1, buf + 5); | ||
| 172 | buf[7] = 0xf0 + nd->nd_tx_module; | ||
| 173 | buf += 8; | ||
| 174 | } | ||
| 175 | |||
| 176 | if (nd->nd_rx_module) { | ||
| 177 | buf[0] = RPDUMP_SERVER; | ||
| 178 | put_unaligned_be32(0, buf + 1); | ||
| 179 | put_unaligned_be16(1, buf + 5); | ||
| 180 | buf[7] = 0xf0 + nd->nd_rx_module; | ||
| 181 | buf += 8; | ||
| 182 | } | ||
| 183 | |||
| 184 | nd->nd_mon_out = 0; | ||
| 185 | nd->nd_mon_in = buf - nd->nd_mon_buf; | ||
| 186 | nd->nd_mon_lbolt = jiffies; | ||
| 187 | |||
| 188 | done_up: | ||
| 189 | up(&nd->nd_mon_semaphore); | ||
| 190 | |||
| 191 | done: | ||
| 192 | if (rtn) | ||
| 193 | module_put(THIS_MODULE); | ||
| 194 | return rtn; | ||
| 195 | } | ||
| 196 | |||
| 197 | |||
| 198 | /** | ||
| 199 | * dgrp_mon_release() - Close the MON device for a particular PortServer | ||
| 200 | * @inode: struct inode * | ||
| 201 | * @file: struct file * | ||
| 202 | */ | ||
| 203 | static int dgrp_mon_release(struct inode *inode, struct file *file) | ||
| 204 | { | ||
| 205 | struct nd_struct *nd; | ||
| 206 | |||
| 207 | /* | ||
| 208 | * Get the node pointer, and quit if it doesn't exist. | ||
| 209 | */ | ||
| 210 | nd = (struct nd_struct *)(file->private_data); | ||
| 211 | if (!nd) | ||
| 212 | goto done; | ||
| 213 | |||
| 214 | /* | ||
| 215 | * Free the monitor buffer. | ||
| 216 | */ | ||
| 217 | |||
| 218 | down(&nd->nd_mon_semaphore); | ||
| 219 | |||
| 220 | kfree(nd->nd_mon_buf); | ||
| 221 | nd->nd_mon_buf = NULL; | ||
| 222 | nd->nd_mon_out = nd->nd_mon_in; | ||
| 223 | |||
| 224 | /* | ||
| 225 | * Wakeup any thread waiting for buffer space. | ||
| 226 | */ | ||
| 227 | |||
| 228 | if (nd->nd_mon_flag & MON_WAIT_SPACE) { | ||
| 229 | nd->nd_mon_flag &= ~MON_WAIT_SPACE; | ||
| 230 | wake_up_interruptible(&nd->nd_mon_wqueue); | ||
| 231 | } | ||
| 232 | |||
| 233 | up(&nd->nd_mon_semaphore); | ||
| 234 | |||
| 235 | /* | ||
| 236 | * Make sure there is no thread in the middle of writing a packet. | ||
| 237 | */ | ||
| 238 | down(&nd->nd_net_semaphore); | ||
| 239 | up(&nd->nd_net_semaphore); | ||
| 240 | |||
| 241 | done: | ||
| 242 | module_put(THIS_MODULE); | ||
| 243 | file->private_data = NULL; | ||
| 244 | return 0; | ||
| 245 | } | ||
| 246 | |||
| 247 | /** | ||
| 248 | * dgrp_mon_read() -- Copy data from the monitoring buffer to the user | ||
| 249 | */ | ||
| 250 | static ssize_t dgrp_mon_read(struct file *file, char __user *buf, size_t count, | ||
| 251 | loff_t *ppos) | ||
| 252 | { | ||
| 253 | struct nd_struct *nd; | ||
| 254 | int r; | ||
| 255 | int offset = 0; | ||
| 256 | int res = 0; | ||
| 257 | ssize_t rtn; | ||
| 258 | |||
| 259 | /* | ||
| 260 | * Get the node pointer, and quit if it doesn't exist. | ||
| 261 | */ | ||
| 262 | nd = (struct nd_struct *)(file->private_data); | ||
| 263 | if (!nd) | ||
| 264 | return -ENXIO; | ||
| 265 | |||
| 266 | /* | ||
| 267 | * Wait for some data to appear in the buffer. | ||
| 268 | */ | ||
| 269 | |||
| 270 | down(&nd->nd_mon_semaphore); | ||
| 271 | |||
| 272 | for (;;) { | ||
| 273 | res = (nd->nd_mon_in - nd->nd_mon_out) & MON_MASK; | ||
| 274 | |||
| 275 | if (res) | ||
| 276 | break; | ||
| 277 | |||
| 278 | nd->nd_mon_flag |= MON_WAIT_DATA; | ||
| 279 | |||
| 280 | up(&nd->nd_mon_semaphore); | ||
| 281 | |||
| 282 | /* | ||
| 283 | * Go to sleep waiting until the condition becomes true. | ||
| 284 | */ | ||
| 285 | rtn = wait_event_interruptible(nd->nd_mon_wqueue, | ||
| 286 | ((nd->nd_mon_flag & MON_WAIT_DATA) == 0)); | ||
| 287 | |||
| 288 | if (rtn) | ||
| 289 | return rtn; | ||
| 290 | |||
| 291 | down(&nd->nd_mon_semaphore); | ||
| 292 | } | ||
| 293 | |||
| 294 | /* | ||
| 295 | * Read whatever is there. | ||
| 296 | */ | ||
| 297 | |||
| 298 | if (res > count) | ||
| 299 | res = count; | ||
| 300 | |||
| 301 | r = MON_MAX - nd->nd_mon_out; | ||
| 302 | |||
| 303 | if (r <= res) { | ||
| 304 | rtn = copy_to_user((void __user *)buf, | ||
| 305 | nd->nd_mon_buf + nd->nd_mon_out, r); | ||
| 306 | if (rtn) { | ||
| 307 | up(&nd->nd_mon_semaphore); | ||
| 308 | return -EFAULT; | ||
| 309 | } | ||
| 310 | |||
| 311 | nd->nd_mon_out = 0; | ||
| 312 | res -= r; | ||
| 313 | offset = r; | ||
| 314 | } | ||
| 315 | |||
| 316 | rtn = copy_to_user((void __user *) buf + offset, | ||
| 317 | nd->nd_mon_buf + nd->nd_mon_out, res); | ||
| 318 | if (rtn) { | ||
| 319 | up(&nd->nd_mon_semaphore); | ||
| 320 | return -EFAULT; | ||
| 321 | } | ||
| 322 | |||
| 323 | nd->nd_mon_out += res; | ||
| 324 | |||
| 325 | *ppos += res; | ||
| 326 | |||
| 327 | up(&nd->nd_mon_semaphore); | ||
| 328 | |||
| 329 | /* | ||
| 330 | * Wakeup any thread waiting for buffer space. | ||
| 331 | */ | ||
| 332 | |||
| 333 | if (nd->nd_mon_flag & MON_WAIT_SPACE) { | ||
| 334 | nd->nd_mon_flag &= ~MON_WAIT_SPACE; | ||
| 335 | wake_up_interruptible(&nd->nd_mon_wqueue); | ||
| 336 | } | ||
| 337 | |||
| 338 | return res; | ||
| 339 | } | ||
| 340 | |||
| 341 | /* ioctl is not valid on monitor device */ | ||
| 342 | static long dgrp_mon_ioctl(struct file *file, unsigned int cmd, | ||
| 343 | unsigned long arg) | ||
| 344 | { | ||
| 345 | return -EINVAL; | ||
| 346 | } | ||
diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c new file mode 100644 index 000000000000..ab839ea3b44c --- /dev/null +++ b/drivers/staging/dgrp/dgrp_net_ops.c | |||
| @@ -0,0 +1,3737 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright 1999 Digi International (www.digi.com) | ||
| 4 | * James Puzzo <jamesp at digi dot com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 9 | * any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the | ||
| 13 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | ||
| 14 | * PURPOSE. See the GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* | ||
| 19 | * | ||
| 20 | * Filename: | ||
| 21 | * | ||
| 22 | * dgrp_net_ops.c | ||
| 23 | * | ||
| 24 | * Description: | ||
| 25 | * | ||
| 26 | * Handle the file operations required for the "network" devices. | ||
| 27 | * Includes those functions required to register the "net" devices | ||
| 28 | * in "/proc". | ||
| 29 | * | ||
| 30 | * Author: | ||
| 31 | * | ||
| 32 | * James A. Puzzo | ||
| 33 | * | ||
| 34 | */ | ||
| 35 | |||
| 36 | #include <linux/module.h> | ||
| 37 | #include <linux/proc_fs.h> | ||
| 38 | #include <linux/types.h> | ||
| 39 | #include <linux/string.h> | ||
| 40 | #include <linux/tty.h> | ||
| 41 | #include <linux/tty_flip.h> | ||
| 42 | #include <linux/spinlock.h> | ||
| 43 | #include <linux/poll.h> | ||
| 44 | #include <linux/sched.h> | ||
| 45 | #include <linux/ratelimit.h> | ||
| 46 | #include <asm/unaligned.h> | ||
| 47 | |||
| 48 | #define MYFLIPLEN TBUF_MAX | ||
| 49 | |||
| 50 | #include "dgrp_common.h" | ||
| 51 | |||
| 52 | #define TTY_FLIPBUF_SIZE 512 | ||
| 53 | #define DEVICE_NAME_SIZE 50 | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Generic helper function declarations | ||
| 57 | */ | ||
| 58 | static void parity_scan(struct ch_struct *ch, unsigned char *cbuf, | ||
| 59 | unsigned char *fbuf, int *len); | ||
| 60 | |||
| 61 | /* | ||
| 62 | * File operation declarations | ||
| 63 | */ | ||
| 64 | static int dgrp_net_open(struct inode *, struct file *); | ||
| 65 | static int dgrp_net_release(struct inode *, struct file *); | ||
| 66 | static ssize_t dgrp_net_read(struct file *, char __user *, size_t, loff_t *); | ||
| 67 | static ssize_t dgrp_net_write(struct file *, const char __user *, size_t, | ||
| 68 | loff_t *); | ||
| 69 | static long dgrp_net_ioctl(struct file *file, unsigned int cmd, | ||
| 70 | unsigned long arg); | ||
| 71 | static unsigned int dgrp_net_select(struct file *file, | ||
| 72 | struct poll_table_struct *table); | ||
| 73 | |||
| 74 | static const struct file_operations net_ops = { | ||
| 75 | .owner = THIS_MODULE, | ||
| 76 | .read = dgrp_net_read, | ||
| 77 | .write = dgrp_net_write, | ||
| 78 | .poll = dgrp_net_select, | ||
| 79 | .unlocked_ioctl = dgrp_net_ioctl, | ||
| 80 | .open = dgrp_net_open, | ||
| 81 | .release = dgrp_net_release, | ||
| 82 | }; | ||
| 83 | |||
| 84 | static struct inode_operations net_inode_ops = { | ||
| 85 | .permission = dgrp_inode_permission | ||
| 86 | }; | ||
| 87 | |||
| 88 | void dgrp_register_net_hook(struct proc_dir_entry *de) | ||
| 89 | { | ||
| 90 | struct nd_struct *node = de->data; | ||
| 91 | |||
| 92 | de->proc_iops = &net_inode_ops; | ||
| 93 | de->proc_fops = &net_ops; | ||
| 94 | node->nd_net_de = de; | ||
| 95 | sema_init(&node->nd_net_semaphore, 1); | ||
| 96 | node->nd_state = NS_CLOSED; | ||
| 97 | dgrp_create_node_class_sysfs_files(node); | ||
| 98 | } | ||
| 99 | |||
| 100 | |||
| 101 | /** | ||
| 102 | * dgrp_dump() -- prints memory for debugging purposes. | ||
| 103 | * @mem: Memory location which should be printed to the console | ||
| 104 | * @len: Number of bytes to be dumped | ||
| 105 | */ | ||
| 106 | static void dgrp_dump(u8 *mem, int len) | ||
| 107 | { | ||
| 108 | int i; | ||
| 109 | |||
| 110 | pr_debug("dgrp dump length = %d, data = ", len); | ||
| 111 | for (i = 0; i < len; ++i) | ||
| 112 | pr_debug("%.2x ", mem[i]); | ||
| 113 | pr_debug("\n"); | ||
| 114 | } | ||
| 115 | |||
| 116 | /** | ||
| 117 | * dgrp_read_data_block() -- Read a data block | ||
| 118 | * @ch: struct ch_struct * | ||
| 119 | * @flipbuf: u8 * | ||
| 120 | * @flipbuf_size: size of flipbuf | ||
| 121 | */ | ||
| 122 | static void dgrp_read_data_block(struct ch_struct *ch, u8 *flipbuf, | ||
| 123 | int flipbuf_size) | ||
| 124 | { | ||
| 125 | int t; | ||
| 126 | int n; | ||
| 127 | |||
| 128 | if (flipbuf_size <= 0) | ||
| 129 | return; | ||
| 130 | |||
| 131 | t = RBUF_MAX - ch->ch_rout; | ||
| 132 | n = flipbuf_size; | ||
| 133 | |||
| 134 | if (n >= t) { | ||
| 135 | memcpy(flipbuf, ch->ch_rbuf + ch->ch_rout, t); | ||
| 136 | flipbuf += t; | ||
| 137 | n -= t; | ||
| 138 | ch->ch_rout = 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | memcpy(flipbuf, ch->ch_rbuf + ch->ch_rout, n); | ||
| 142 | flipbuf += n; | ||
| 143 | ch->ch_rout += n; | ||
| 144 | } | ||
| 145 | |||
| 146 | |||
| 147 | /** | ||
| 148 | * dgrp_input() -- send data to the line disipline | ||
| 149 | * @ch: pointer to channel struct | ||
| 150 | * | ||
| 151 | * Copys the rbuf to the flipbuf and sends to line discipline. | ||
| 152 | * Sends input buffer data to the line discipline. | ||
| 153 | * | ||
| 154 | * There are several modes to consider here: | ||
| 155 | * rawreadok, tty->real_raw, and IF_PARMRK | ||
| 156 | */ | ||
| 157 | static void dgrp_input(struct ch_struct *ch) | ||
| 158 | { | ||
| 159 | struct nd_struct *nd; | ||
| 160 | struct tty_struct *tty; | ||
| 161 | int remain; | ||
| 162 | int data_len; | ||
| 163 | int len; | ||
| 164 | int flip_len; | ||
| 165 | int tty_count; | ||
| 166 | ulong lock_flags; | ||
| 167 | struct tty_ldisc *ld; | ||
| 168 | u8 *myflipbuf; | ||
| 169 | u8 *myflipflagbuf; | ||
| 170 | |||
| 171 | if (!ch) | ||
| 172 | return; | ||
| 173 | |||
| 174 | nd = ch->ch_nd; | ||
| 175 | |||
| 176 | if (!nd) | ||
| 177 | return; | ||
| 178 | |||
| 179 | spin_lock_irqsave(&nd->nd_lock, lock_flags); | ||
| 180 | |||
| 181 | myflipbuf = nd->nd_inputbuf; | ||
| 182 | myflipflagbuf = nd->nd_inputflagbuf; | ||
| 183 | |||
| 184 | if (!ch->ch_open_count) { | ||
| 185 | ch->ch_rout = ch->ch_rin; | ||
| 186 | goto out; | ||
| 187 | } | ||
| 188 | |||
| 189 | if (ch->ch_tun.un_flag & UN_CLOSING) { | ||
| 190 | ch->ch_rout = ch->ch_rin; | ||
| 191 | goto out; | ||
| 192 | } | ||
| 193 | |||
| 194 | tty = (ch->ch_tun).un_tty; | ||
| 195 | |||
| 196 | |||
| 197 | if (!tty || tty->magic != TTY_MAGIC) { | ||
| 198 | ch->ch_rout = ch->ch_rin; | ||
| 199 | goto out; | ||
| 200 | } | ||
| 201 | |||
| 202 | tty_count = tty->count; | ||
| 203 | if (!tty_count) { | ||
| 204 | ch->ch_rout = ch->ch_rin; | ||
| 205 | goto out; | ||
| 206 | } | ||
| 207 | |||
| 208 | if (tty->closing || test_bit(TTY_CLOSING, &tty->flags)) { | ||
| 209 | ch->ch_rout = ch->ch_rin; | ||
| 210 | goto out; | ||
| 211 | } | ||
| 212 | |||
| 213 | spin_unlock_irqrestore(&nd->nd_lock, lock_flags); | ||
| 214 | |||
| 215 | /* Decide how much data we can send into the tty layer */ | ||
| 216 | if (dgrp_rawreadok && tty->real_raw) | ||
| 217 | flip_len = MYFLIPLEN; | ||
| 218 | else | ||
| 219 | flip_len = TTY_FLIPBUF_SIZE; | ||
| 220 | |||
| 221 | /* data_len should be the number of chars that we read in */ | ||
| 222 | data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK; | ||
| 223 | remain = data_len; | ||
| 224 | |||
| 225 | /* len is the amount of data we are going to transfer here */ | ||
| 226 | len = min(data_len, flip_len); | ||
| 227 | |||
| 228 | /* take into consideration length of ldisc */ | ||
| 229 | len = min(len, (N_TTY_BUF_SIZE - 1) - tty->read_cnt); | ||
| 230 | |||
| 231 | ld = tty_ldisc_ref(tty); | ||
| 232 | |||
| 233 | /* | ||
| 234 | * If we were unable to get a reference to the ld, | ||
| 235 | * don't flush our buffer, and act like the ld doesn't | ||
| 236 | * have any space to put the data right now. | ||
| 237 | */ | ||
| 238 | if (!ld) { | ||
| 239 | len = 0; | ||
| 240 | } else if (!ld->ops->receive_buf) { | ||
| 241 | spin_lock_irqsave(&nd->nd_lock, lock_flags); | ||
| 242 | ch->ch_rout = ch->ch_rin; | ||
| 243 | spin_unlock_irqrestore(&nd->nd_lock, lock_flags); | ||
| 244 | len = 0; | ||
| 245 | } | ||
| 246 | |||
| 247 | /* Check DPA flow control */ | ||
| 248 | if ((nd->nd_dpa_debug) && | ||
| 249 | (nd->nd_dpa_flag & DPA_WAIT_SPACE) && | ||
| 250 | (nd->nd_dpa_port == MINOR(tty_devnum(ch->ch_tun.un_tty)))) | ||
| 251 | len = 0; | ||
| 252 | |||
| 253 | if ((len) && !(ch->ch_flag & CH_RXSTOP)) { | ||
| 254 | |||
| 255 | dgrp_read_data_block(ch, myflipbuf, len); | ||
| 256 | |||
| 257 | /* | ||
| 258 | * In high performance mode, we don't have to update | ||
| 259 | * flag_buf or any of the counts or pointers into flip buf. | ||
| 260 | */ | ||
| 261 | if (!dgrp_rawreadok || !tty->real_raw) { | ||
| 262 | if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty)) | ||
| 263 | parity_scan(ch, myflipbuf, myflipflagbuf, &len); | ||
| 264 | else | ||
| 265 | memset(myflipflagbuf, TTY_NORMAL, len); | ||
| 266 | } | ||
| 267 | |||
| 268 | if ((nd->nd_dpa_debug) && | ||
| 269 | (nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty))))) | ||
| 270 | dgrp_dpa_data(nd, 1, myflipbuf, len); | ||
| 271 | |||
| 272 | /* | ||
| 273 | * If we're doing raw reads, jam it right into the | ||
| 274 | * line disc bypassing the flip buffers. | ||
| 275 | */ | ||
| 276 | if (dgrp_rawreadok && tty->real_raw) | ||
| 277 | ld->ops->receive_buf(tty, myflipbuf, NULL, len); | ||
| 278 | else { | ||
| 279 | len = tty_buffer_request_room(tty, len); | ||
| 280 | tty_insert_flip_string_flags(tty, myflipbuf, | ||
| 281 | myflipflagbuf, len); | ||
| 282 | |||
| 283 | /* Tell the tty layer its okay to "eat" the data now */ | ||
| 284 | tty_flip_buffer_push(tty); | ||
| 285 | } | ||
| 286 | |||
| 287 | ch->ch_rxcount += len; | ||
| 288 | } | ||
| 289 | |||
| 290 | if (ld) | ||
| 291 | tty_ldisc_deref(ld); | ||
| 292 | |||
| 293 | /* | ||
| 294 | * Wake up any sleepers (maybe dgrp close) that might be waiting | ||
| 295 | * for a channel flag state change. | ||
| 296 | */ | ||
| 297 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 298 | return; | ||
| 299 | |||
| 300 | out: | ||
| 301 | spin_unlock_irqrestore(&nd->nd_lock, lock_flags); | ||
| 302 | } | ||
| 303 | |||
| 304 | |||
| 305 | /* | ||
| 306 | * parity_scan | ||
| 307 | * | ||
| 308 | * Loop to inspect each single character or 0xFF escape. | ||
| 309 | * | ||
| 310 | * if PARMRK & ~DOSMODE: | ||
| 311 | * 0xFF 0xFF Normal 0xFF character, escaped | ||
| 312 | * to eliminate confusion. | ||
| 313 | * 0xFF 0x00 0x00 Break | ||
| 314 | * 0xFF 0x00 CC Error character CC. | ||
| 315 | * CC Normal character CC. | ||
| 316 | * | ||
| 317 | * if PARMRK & DOSMODE: | ||
| 318 | * 0xFF 0x18 0x00 Break | ||
| 319 | * 0xFF 0x08 0x00 Framing Error | ||
| 320 | * 0xFF 0x04 0x00 Parity error | ||
| 321 | * 0xFF 0x0C 0x00 Both Framing and Parity error | ||
| 322 | * | ||
| 323 | * TODO: do we need to do the XMODEM, XOFF, XON, XANY processing?? | ||
| 324 | * as per protocol | ||
| 325 | */ | ||
| 326 | static void parity_scan(struct ch_struct *ch, unsigned char *cbuf, | ||
| 327 | unsigned char *fbuf, int *len) | ||
| 328 | { | ||
| 329 | int l = *len; | ||
| 330 | int count = 0; | ||
| 331 | int DOS = ((ch->ch_iflag & IF_DOSMODE) == 0 ? 0 : 1); | ||
| 332 | unsigned char *cout; /* character buffer */ | ||
| 333 | unsigned char *fout; /* flag buffer */ | ||
| 334 | unsigned char *in; | ||
| 335 | unsigned char c; | ||
| 336 | |||
| 337 | in = cbuf; | ||
| 338 | cout = cbuf; | ||
| 339 | fout = fbuf; | ||
| 340 | |||
| 341 | while (l--) { | ||
| 342 | c = *in; | ||
| 343 | in++; | ||
| 344 | |||
| 345 | switch (ch->ch_pscan_state) { | ||
| 346 | default: | ||
| 347 | /* reset to sanity and fall through */ | ||
| 348 | ch->ch_pscan_state = 0 ; | ||
| 349 | |||
| 350 | case 0: | ||
| 351 | /* No FF seen yet */ | ||
| 352 | if (c == 0xff) /* delete this character from stream */ | ||
| 353 | ch->ch_pscan_state = 1; | ||
| 354 | else { | ||
| 355 | *cout++ = c; | ||
| 356 | *fout++ = TTY_NORMAL; | ||
| 357 | count += 1; | ||
| 358 | } | ||
| 359 | break; | ||
| 360 | |||
| 361 | case 1: | ||
| 362 | /* first FF seen */ | ||
| 363 | if (c == 0xff) { | ||
| 364 | /* doubled ff, transform to single ff */ | ||
| 365 | *cout++ = c; | ||
| 366 | *fout++ = TTY_NORMAL; | ||
| 367 | count += 1; | ||
| 368 | ch->ch_pscan_state = 0; | ||
| 369 | } else { | ||
| 370 | /* save value examination in next state */ | ||
| 371 | ch->ch_pscan_savechar = c; | ||
| 372 | ch->ch_pscan_state = 2; | ||
| 373 | } | ||
| 374 | break; | ||
| 375 | |||
| 376 | case 2: | ||
| 377 | /* third character of ff sequence */ | ||
| 378 | *cout++ = c; | ||
| 379 | if (DOS) { | ||
| 380 | if (ch->ch_pscan_savechar & 0x10) | ||
| 381 | *fout++ = TTY_BREAK; | ||
| 382 | else if (ch->ch_pscan_savechar & 0x08) | ||
| 383 | *fout++ = TTY_FRAME; | ||
| 384 | else | ||
| 385 | /* | ||
| 386 | * either marked as a parity error, | ||
| 387 | * indeterminate, or not in DOSMODE | ||
| 388 | * call it a parity error | ||
| 389 | */ | ||
| 390 | *fout++ = TTY_PARITY; | ||
| 391 | } else { | ||
| 392 | /* case FF XX ?? where XX is not 00 */ | ||
| 393 | if (ch->ch_pscan_savechar & 0xff) { | ||
| 394 | /* this should not happen */ | ||
| 395 | pr_info("%s: parity_scan: error unexpected byte\n", | ||
| 396 | __func__); | ||
| 397 | *fout++ = TTY_PARITY; | ||
| 398 | } | ||
| 399 | /* case FF 00 XX where XX is not 00 */ | ||
| 400 | else if (c == 0xff) | ||
| 401 | *fout++ = TTY_PARITY; | ||
| 402 | /* case FF 00 00 */ | ||
| 403 | else | ||
| 404 | *fout++ = TTY_BREAK; | ||
| 405 | |||
| 406 | } | ||
| 407 | count += 1; | ||
| 408 | ch->ch_pscan_state = 0; | ||
| 409 | } | ||
| 410 | } | ||
| 411 | *len = count; | ||
| 412 | } | ||
| 413 | |||
| 414 | |||
| 415 | /** | ||
| 416 | * dgrp_net_idle() -- Idle the network connection | ||
| 417 | * @nd: pointer to node structure to idle | ||
| 418 | */ | ||
| 419 | static void dgrp_net_idle(struct nd_struct *nd) | ||
| 420 | { | ||
| 421 | struct ch_struct *ch; | ||
| 422 | int i; | ||
| 423 | |||
| 424 | nd->nd_tx_work = 1; | ||
| 425 | |||
| 426 | nd->nd_state = NS_IDLE; | ||
| 427 | nd->nd_flag = 0; | ||
| 428 | |||
| 429 | for (i = nd->nd_seq_out; ; i = (i + 1) & SEQ_MASK) { | ||
| 430 | if (!nd->nd_seq_wait[i]) { | ||
| 431 | nd->nd_seq_wait[i] = 0; | ||
| 432 | wake_up_interruptible(&nd->nd_seq_wque[i]); | ||
| 433 | } | ||
| 434 | |||
| 435 | if (i == nd->nd_seq_in) | ||
| 436 | break; | ||
| 437 | } | ||
| 438 | |||
| 439 | nd->nd_seq_out = nd->nd_seq_in; | ||
| 440 | |||
| 441 | nd->nd_unack = 0; | ||
| 442 | nd->nd_remain = 0; | ||
| 443 | |||
| 444 | nd->nd_tx_module = 0x10; | ||
| 445 | nd->nd_rx_module = 0x00; | ||
| 446 | |||
| 447 | for (i = 0, ch = nd->nd_chan; i < CHAN_MAX; i++, ch++) { | ||
| 448 | ch->ch_state = CS_IDLE; | ||
| 449 | |||
| 450 | ch->ch_otype = 0; | ||
| 451 | ch->ch_otype_waiting = 0; | ||
| 452 | } | ||
| 453 | } | ||
| 454 | |||
| 455 | /* | ||
| 456 | * Increase the number of channels, waking up any | ||
| 457 | * threads that might be waiting for the channels | ||
| 458 | * to appear. | ||
| 459 | */ | ||
| 460 | static void increase_channel_count(struct nd_struct *nd, int n) | ||
| 461 | { | ||
| 462 | struct ch_struct *ch; | ||
| 463 | struct device *classp; | ||
| 464 | char name[DEVICE_NAME_SIZE]; | ||
| 465 | int ret; | ||
| 466 | u8 *buf; | ||
| 467 | int i; | ||
| 468 | |||
| 469 | for (i = nd->nd_chan_count; i < n; ++i) { | ||
| 470 | ch = nd->nd_chan + i; | ||
| 471 | |||
| 472 | /* FIXME: return a useful error instead! */ | ||
| 473 | buf = kmalloc(TBUF_MAX, GFP_KERNEL); | ||
| 474 | if (!buf) | ||
| 475 | return; | ||
| 476 | |||
| 477 | if (ch->ch_tbuf) | ||
| 478 | pr_info_ratelimited("%s - ch_tbuf was not NULL\n", | ||
| 479 | __func__); | ||
| 480 | |||
| 481 | ch->ch_tbuf = buf; | ||
| 482 | |||
| 483 | buf = kmalloc(RBUF_MAX, GFP_KERNEL); | ||
| 484 | if (!buf) | ||
| 485 | return; | ||
| 486 | |||
| 487 | if (ch->ch_rbuf) | ||
| 488 | pr_info("%s - ch_rbuf was not NULL\n", | ||
| 489 | __func__); | ||
| 490 | ch->ch_rbuf = buf; | ||
| 491 | |||
| 492 | classp = tty_port_register_device(&ch->port, | ||
| 493 | nd->nd_serial_ttdriver, i, | ||
| 494 | NULL); | ||
| 495 | |||
| 496 | ch->ch_tun.un_sysfs = classp; | ||
| 497 | snprintf(name, DEVICE_NAME_SIZE, "tty_%d", i); | ||
| 498 | |||
| 499 | dgrp_create_tty_sysfs(&ch->ch_tun, classp); | ||
| 500 | ret = sysfs_create_link(&nd->nd_class_dev->kobj, | ||
| 501 | &classp->kobj, name); | ||
| 502 | |||
| 503 | /* NOTE: We don't support "cu" devices anymore, | ||
| 504 | * so you will notice we don't register them | ||
| 505 | * here anymore. */ | ||
| 506 | if (dgrp_register_prdevices) { | ||
| 507 | classp = tty_register_device(nd->nd_xprint_ttdriver, | ||
| 508 | i, NULL); | ||
| 509 | ch->ch_pun.un_sysfs = classp; | ||
| 510 | snprintf(name, DEVICE_NAME_SIZE, "pr_%d", i); | ||
| 511 | |||
| 512 | dgrp_create_tty_sysfs(&ch->ch_pun, classp); | ||
| 513 | ret = sysfs_create_link(&nd->nd_class_dev->kobj, | ||
| 514 | &classp->kobj, name); | ||
| 515 | } | ||
| 516 | |||
| 517 | nd->nd_chan_count = i + 1; | ||
| 518 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 519 | } | ||
| 520 | } | ||
| 521 | |||
| 522 | /* | ||
| 523 | * Decrease the number of channels, and wake up any threads that might | ||
| 524 | * be waiting on the channels that vanished. | ||
| 525 | */ | ||
| 526 | static void decrease_channel_count(struct nd_struct *nd, int n) | ||
| 527 | { | ||
| 528 | struct ch_struct *ch; | ||
| 529 | char name[DEVICE_NAME_SIZE]; | ||
| 530 | int i; | ||
| 531 | |||
| 532 | for (i = nd->nd_chan_count - 1; i >= n; --i) { | ||
| 533 | ch = nd->nd_chan + i; | ||
| 534 | |||
| 535 | /* | ||
| 536 | * Make any open ports inoperative. | ||
| 537 | */ | ||
| 538 | ch->ch_state = CS_IDLE; | ||
| 539 | |||
| 540 | ch->ch_otype = 0; | ||
| 541 | ch->ch_otype_waiting = 0; | ||
| 542 | |||
| 543 | /* | ||
| 544 | * Only "HANGUP" if we care about carrier | ||
| 545 | * transitions and we are already open. | ||
| 546 | */ | ||
| 547 | if (ch->ch_open_count != 0) { | ||
| 548 | ch->ch_flag |= CH_HANGUP; | ||
| 549 | dgrp_carrier(ch); | ||
| 550 | } | ||
| 551 | |||
| 552 | /* | ||
| 553 | * Unlike the CH_HANGUP flag above, use another | ||
| 554 | * flag to indicate to the RealPort state machine | ||
| 555 | * that this port has disappeared. | ||
| 556 | */ | ||
| 557 | if (ch->ch_open_count != 0) | ||
| 558 | ch->ch_flag |= CH_PORT_GONE; | ||
| 559 | |||
| 560 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 561 | |||
| 562 | nd->nd_chan_count = i; | ||
| 563 | |||
| 564 | kfree(ch->ch_tbuf); | ||
| 565 | ch->ch_tbuf = NULL; | ||
| 566 | |||
| 567 | kfree(ch->ch_rbuf); | ||
| 568 | ch->ch_rbuf = NULL; | ||
| 569 | |||
| 570 | nd->nd_chan_count = i; | ||
| 571 | |||
| 572 | dgrp_remove_tty_sysfs(ch->ch_tun.un_sysfs); | ||
| 573 | snprintf(name, DEVICE_NAME_SIZE, "tty_%d", i); | ||
| 574 | sysfs_remove_link(&nd->nd_class_dev->kobj, name); | ||
| 575 | tty_unregister_device(nd->nd_serial_ttdriver, i); | ||
| 576 | |||
| 577 | /* | ||
| 578 | * NOTE: We don't support "cu" devices anymore, so don't | ||
| 579 | * unregister them here anymore. | ||
| 580 | */ | ||
| 581 | |||
| 582 | if (dgrp_register_prdevices) { | ||
| 583 | dgrp_remove_tty_sysfs(ch->ch_pun.un_sysfs); | ||
| 584 | snprintf(name, DEVICE_NAME_SIZE, "pr_%d", i); | ||
| 585 | sysfs_remove_link(&nd->nd_class_dev->kobj, name); | ||
| 586 | tty_unregister_device(nd->nd_xprint_ttdriver, i); | ||
| 587 | } | ||
| 588 | } | ||
| 589 | } | ||
| 590 | |||
| 591 | /** | ||
| 592 | * dgrp_chan_count() -- Adjust the node channel count. | ||
| 593 | * @nd: pointer to a node structure | ||
| 594 | * @n: new value for channel count | ||
| 595 | * | ||
| 596 | * Adjusts the node channel count. If new ports have appeared, it tries | ||
| 597 | * to signal those processes that might have been waiting for ports to | ||
| 598 | * appear. If ports have disappeared it tries to signal those processes | ||
| 599 | * that might be hung waiting for a response for the now non-existant port. | ||
| 600 | */ | ||
| 601 | static void dgrp_chan_count(struct nd_struct *nd, int n) | ||
| 602 | { | ||
| 603 | if (n == nd->nd_chan_count) | ||
| 604 | return; | ||
| 605 | |||
| 606 | if (n > nd->nd_chan_count) | ||
| 607 | increase_channel_count(nd, n); | ||
| 608 | |||
| 609 | if (n < nd->nd_chan_count) | ||
| 610 | decrease_channel_count(nd, n); | ||
| 611 | } | ||
| 612 | |||
| 613 | /** | ||
| 614 | * dgrp_monitor() -- send data to the device monitor queue | ||
| 615 | * @nd: pointer to a node structure | ||
| 616 | * @buf: data to copy to the monitoring buffer | ||
| 617 | * @len: number of bytes to transfer to the buffer | ||
| 618 | * | ||
| 619 | * Called by the net device routines to send data to the device | ||
| 620 | * monitor queue. If the device monitor buffer is too full to | ||
| 621 | * accept the data, it waits until the buffer is ready. | ||
| 622 | */ | ||
| 623 | static void dgrp_monitor(struct nd_struct *nd, u8 *buf, int len) | ||
| 624 | { | ||
| 625 | int n; | ||
| 626 | int r; | ||
| 627 | int rtn; | ||
| 628 | |||
| 629 | /* | ||
| 630 | * Grab monitor lock. | ||
| 631 | */ | ||
| 632 | down(&nd->nd_mon_semaphore); | ||
| 633 | |||
| 634 | /* | ||
| 635 | * Loop while data remains. | ||
| 636 | */ | ||
| 637 | while ((len > 0) && (nd->nd_mon_buf)) { | ||
| 638 | /* | ||
| 639 | * Determine the amount of available space left in the | ||
| 640 | * buffer. If there's none, wait until some appears. | ||
| 641 | */ | ||
| 642 | |||
| 643 | n = (nd->nd_mon_out - nd->nd_mon_in - 1) & MON_MASK; | ||
| 644 | |||
| 645 | if (!n) { | ||
| 646 | nd->nd_mon_flag |= MON_WAIT_SPACE; | ||
| 647 | |||
| 648 | up(&nd->nd_mon_semaphore); | ||
| 649 | |||
| 650 | /* | ||
| 651 | * Go to sleep waiting until the condition becomes true. | ||
| 652 | */ | ||
| 653 | rtn = wait_event_interruptible(nd->nd_mon_wqueue, | ||
| 654 | ((nd->nd_mon_flag & MON_WAIT_SPACE) == 0)); | ||
| 655 | |||
| 656 | /* FIXME: really ignore rtn? */ | ||
| 657 | |||
| 658 | /* | ||
| 659 | * We can't exit here if we receive a signal, since | ||
| 660 | * to do so would trash the debug stream. | ||
| 661 | */ | ||
| 662 | |||
| 663 | down(&nd->nd_mon_semaphore); | ||
| 664 | |||
| 665 | continue; | ||
| 666 | } | ||
| 667 | |||
| 668 | /* | ||
| 669 | * Copy as much data as will fit. | ||
| 670 | */ | ||
| 671 | |||
| 672 | if (n > len) | ||
| 673 | n = len; | ||
| 674 | |||
| 675 | r = MON_MAX - nd->nd_mon_in; | ||
| 676 | |||
| 677 | if (r <= n) { | ||
| 678 | memcpy(nd->nd_mon_buf + nd->nd_mon_in, buf, r); | ||
| 679 | |||
| 680 | n -= r; | ||
| 681 | |||
| 682 | nd->nd_mon_in = 0; | ||
| 683 | |||
| 684 | buf += r; | ||
| 685 | len -= r; | ||
| 686 | } | ||
| 687 | |||
| 688 | memcpy(nd->nd_mon_buf + nd->nd_mon_in, buf, n); | ||
| 689 | |||
| 690 | nd->nd_mon_in += n; | ||
| 691 | |||
| 692 | buf += n; | ||
| 693 | len -= n; | ||
| 694 | |||
| 695 | if (nd->nd_mon_in >= MON_MAX) | ||
| 696 | pr_info_ratelimited("%s - nd_mon_in (%i) >= MON_MAX\n", | ||
| 697 | __func__, nd->nd_mon_in); | ||
| 698 | |||
| 699 | /* | ||
| 700 | * Wakeup any thread waiting for data | ||
| 701 | */ | ||
| 702 | |||
| 703 | if (nd->nd_mon_flag & MON_WAIT_DATA) { | ||
| 704 | nd->nd_mon_flag &= ~MON_WAIT_DATA; | ||
| 705 | wake_up_interruptible(&nd->nd_mon_wqueue); | ||
| 706 | } | ||
| 707 | } | ||
| 708 | |||
| 709 | /* | ||
| 710 | * Release the monitor lock. | ||
| 711 | */ | ||
| 712 | up(&nd->nd_mon_semaphore); | ||
| 713 | } | ||
| 714 | |||
| 715 | /** | ||
| 716 | * dgrp_encode_time() -- Encodes rpdump time into a 4-byte quantity. | ||
| 717 | * @nd: pointer to a node structure | ||
| 718 | * @buf: destination buffer | ||
| 719 | * | ||
| 720 | * Encodes "rpdump" time into a 4-byte quantity. Time is measured since | ||
| 721 | * open. | ||
| 722 | */ | ||
| 723 | static void dgrp_encode_time(struct nd_struct *nd, u8 *buf) | ||
| 724 | { | ||
| 725 | ulong t; | ||
| 726 | |||
| 727 | /* | ||
| 728 | * Convert time in HZ since open to time in milliseconds | ||
| 729 | * since open. | ||
| 730 | */ | ||
| 731 | t = jiffies - nd->nd_mon_lbolt; | ||
| 732 | t = 1000 * (t / HZ) + 1000 * (t % HZ) / HZ; | ||
| 733 | |||
| 734 | put_unaligned_be32((uint)(t & 0xffffffff), buf); | ||
| 735 | } | ||
| 736 | |||
| 737 | |||
| 738 | |||
| 739 | /** | ||
| 740 | * dgrp_monitor_message() -- Builds a rpdump style message. | ||
| 741 | * @nd: pointer to a node structure | ||
| 742 | * @message: destination buffer | ||
| 743 | */ | ||
| 744 | static void dgrp_monitor_message(struct nd_struct *nd, char *message) | ||
| 745 | { | ||
| 746 | u8 header[7]; | ||
| 747 | int n; | ||
| 748 | |||
| 749 | header[0] = RPDUMP_MESSAGE; | ||
| 750 | |||
| 751 | dgrp_encode_time(nd, header + 1); | ||
| 752 | |||
| 753 | n = strlen(message); | ||
| 754 | |||
| 755 | put_unaligned_be16(n, header + 5); | ||
| 756 | |||
| 757 | dgrp_monitor(nd, header, sizeof(header)); | ||
| 758 | dgrp_monitor(nd, (u8 *) message, n); | ||
| 759 | } | ||
| 760 | |||
| 761 | |||
| 762 | |||
| 763 | /** | ||
| 764 | * dgrp_monitor_reset() -- Note a reset in the monitoring buffer. | ||
| 765 | * @nd: pointer to a node structure | ||
| 766 | */ | ||
| 767 | static void dgrp_monitor_reset(struct nd_struct *nd) | ||
| 768 | { | ||
| 769 | u8 header[5]; | ||
| 770 | |||
| 771 | header[0] = RPDUMP_RESET; | ||
| 772 | |||
| 773 | dgrp_encode_time(nd, header + 1); | ||
| 774 | |||
| 775 | dgrp_monitor(nd, header, sizeof(header)); | ||
| 776 | } | ||
| 777 | |||
| 778 | /** | ||
| 779 | * dgrp_monitor_data() -- builds a monitor data packet | ||
| 780 | * @nd: pointer to a node structure | ||
| 781 | * @type: type of message to be logged | ||
| 782 | * @buf: data to be logged | ||
| 783 | * @size: number of bytes in the buffer | ||
| 784 | */ | ||
| 785 | static void dgrp_monitor_data(struct nd_struct *nd, u8 type, u8 *buf, int size) | ||
| 786 | { | ||
| 787 | u8 header[7]; | ||
| 788 | |||
| 789 | header[0] = type; | ||
| 790 | |||
| 791 | dgrp_encode_time(nd, header + 1); | ||
| 792 | |||
| 793 | put_unaligned_be16(size, header + 5); | ||
| 794 | |||
| 795 | dgrp_monitor(nd, header, sizeof(header)); | ||
| 796 | dgrp_monitor(nd, buf, size); | ||
| 797 | } | ||
| 798 | |||
| 799 | static int alloc_nd_buffers(struct nd_struct *nd) | ||
| 800 | { | ||
| 801 | |||
| 802 | nd->nd_iobuf = NULL; | ||
| 803 | nd->nd_writebuf = NULL; | ||
| 804 | nd->nd_inputbuf = NULL; | ||
| 805 | nd->nd_inputflagbuf = NULL; | ||
| 806 | |||
| 807 | /* | ||
| 808 | * Allocate the network read/write buffer. | ||
| 809 | */ | ||
| 810 | nd->nd_iobuf = kzalloc(UIO_MAX + 10, GFP_KERNEL); | ||
| 811 | if (!nd->nd_iobuf) | ||
| 812 | goto out_err; | ||
| 813 | |||
| 814 | /* | ||
| 815 | * Allocate a buffer for doing the copy from user space to | ||
| 816 | * kernel space in the write routines. | ||
| 817 | */ | ||
| 818 | nd->nd_writebuf = kzalloc(WRITEBUFLEN, GFP_KERNEL); | ||
| 819 | if (!nd->nd_writebuf) | ||
| 820 | goto out_err; | ||
| 821 | |||
| 822 | /* | ||
| 823 | * Allocate a buffer for doing the copy from kernel space to | ||
| 824 | * tty buffer space in the read routines. | ||
| 825 | */ | ||
| 826 | nd->nd_inputbuf = kzalloc(MYFLIPLEN, GFP_KERNEL); | ||
| 827 | if (!nd->nd_inputbuf) | ||
| 828 | goto out_err; | ||
| 829 | |||
| 830 | /* | ||
| 831 | * Allocate a buffer for doing the copy from kernel space to | ||
| 832 | * tty buffer space in the read routines. | ||
| 833 | */ | ||
| 834 | nd->nd_inputflagbuf = kzalloc(MYFLIPLEN, GFP_KERNEL); | ||
| 835 | if (!nd->nd_inputflagbuf) | ||
| 836 | goto out_err; | ||
| 837 | |||
| 838 | return 0; | ||
| 839 | |||
| 840 | out_err: | ||
| 841 | kfree(nd->nd_iobuf); | ||
| 842 | kfree(nd->nd_writebuf); | ||
| 843 | kfree(nd->nd_inputbuf); | ||
| 844 | kfree(nd->nd_inputflagbuf); | ||
| 845 | return -ENOMEM; | ||
| 846 | } | ||
| 847 | |||
| 848 | /* | ||
| 849 | * dgrp_net_open() -- Open the NET device for a particular PortServer | ||
| 850 | */ | ||
| 851 | static int dgrp_net_open(struct inode *inode, struct file *file) | ||
| 852 | { | ||
| 853 | struct nd_struct *nd; | ||
| 854 | struct proc_dir_entry *de; | ||
| 855 | ulong lock_flags; | ||
| 856 | int rtn; | ||
| 857 | |||
| 858 | rtn = try_module_get(THIS_MODULE); | ||
| 859 | if (!rtn) | ||
| 860 | return -EAGAIN; | ||
| 861 | |||
| 862 | if (!capable(CAP_SYS_ADMIN)) { | ||
| 863 | rtn = -EPERM; | ||
| 864 | goto done; | ||
| 865 | } | ||
| 866 | |||
| 867 | /* | ||
| 868 | * Make sure that the "private_data" field hasn't already been used. | ||
| 869 | */ | ||
| 870 | if (file->private_data) { | ||
| 871 | rtn = -EINVAL; | ||
| 872 | goto done; | ||
| 873 | } | ||
| 874 | |||
| 875 | /* | ||
| 876 | * Get the node pointer, and fail if it doesn't exist. | ||
| 877 | */ | ||
| 878 | de = PDE(inode); | ||
| 879 | if (!de) { | ||
| 880 | rtn = -ENXIO; | ||
| 881 | goto done; | ||
| 882 | } | ||
| 883 | |||
| 884 | nd = (struct nd_struct *) de->data; | ||
| 885 | if (!nd) { | ||
| 886 | rtn = -ENXIO; | ||
| 887 | goto done; | ||
| 888 | } | ||
| 889 | |||
| 890 | file->private_data = (void *) nd; | ||
| 891 | |||
| 892 | /* | ||
| 893 | * Grab the NET lock. | ||
| 894 | */ | ||
| 895 | down(&nd->nd_net_semaphore); | ||
| 896 | |||
| 897 | if (nd->nd_state != NS_CLOSED) { | ||
| 898 | rtn = -EBUSY; | ||
| 899 | goto unlock; | ||
| 900 | } | ||
| 901 | |||
| 902 | /* | ||
| 903 | * Initialize the link speed parameters. | ||
| 904 | */ | ||
| 905 | |||
| 906 | nd->nd_link.lk_fast_rate = UIO_MAX; | ||
| 907 | nd->nd_link.lk_slow_rate = UIO_MAX; | ||
| 908 | |||
| 909 | nd->nd_link.lk_fast_delay = 1000; | ||
| 910 | nd->nd_link.lk_slow_delay = 1000; | ||
| 911 | |||
| 912 | nd->nd_link.lk_header_size = 46; | ||
| 913 | |||
| 914 | |||
| 915 | rtn = alloc_nd_buffers(nd); | ||
| 916 | if (rtn) | ||
| 917 | goto unlock; | ||
| 918 | |||
| 919 | /* | ||
| 920 | * The port is now open, so move it to the IDLE state | ||
| 921 | */ | ||
| 922 | dgrp_net_idle(nd); | ||
| 923 | |||
| 924 | nd->nd_tx_time = jiffies; | ||
| 925 | |||
| 926 | /* | ||
| 927 | * If the polling routing is not running, start it running here | ||
| 928 | */ | ||
| 929 | spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags); | ||
| 930 | |||
| 931 | if (!dgrp_poll_data.node_active_count) { | ||
| 932 | dgrp_poll_data.node_active_count = 2; | ||
| 933 | dgrp_poll_data.timer.expires = jiffies + | ||
| 934 | dgrp_poll_tick * HZ / 1000; | ||
| 935 | add_timer(&dgrp_poll_data.timer); | ||
| 936 | } | ||
| 937 | |||
| 938 | spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags); | ||
| 939 | |||
| 940 | dgrp_monitor_message(nd, "Net Open"); | ||
| 941 | |||
| 942 | unlock: | ||
| 943 | /* | ||
| 944 | * Release the NET lock. | ||
| 945 | */ | ||
| 946 | up(&nd->nd_net_semaphore); | ||
| 947 | |||
| 948 | done: | ||
| 949 | if (rtn) | ||
| 950 | module_put(THIS_MODULE); | ||
| 951 | |||
| 952 | return rtn; | ||
| 953 | } | ||
| 954 | |||
| 955 | /* dgrp_net_release() -- close the NET device for a particular PortServer */ | ||
| 956 | static int dgrp_net_release(struct inode *inode, struct file *file) | ||
| 957 | { | ||
| 958 | struct nd_struct *nd; | ||
| 959 | ulong lock_flags; | ||
| 960 | |||
| 961 | nd = (struct nd_struct *)(file->private_data); | ||
| 962 | if (!nd) | ||
| 963 | goto done; | ||
| 964 | |||
| 965 | /* TODO : historical locking placeholder */ | ||
| 966 | /* | ||
| 967 | * In the HPUX version of the RealPort driver (which served as a basis | ||
| 968 | * for this driver) this locking code was used. Saved if ever we need | ||
| 969 | * to review the locking under Linux. | ||
| 970 | */ | ||
| 971 | /* spinlock(&nd->nd_lock); */ | ||
| 972 | |||
| 973 | |||
| 974 | /* | ||
| 975 | * Grab the NET lock. | ||
| 976 | */ | ||
| 977 | down(&nd->nd_net_semaphore); | ||
| 978 | |||
| 979 | /* | ||
| 980 | * Before "closing" the internal connection, make sure all | ||
| 981 | * ports are "idle". | ||
| 982 | */ | ||
| 983 | dgrp_net_idle(nd); | ||
| 984 | |||
| 985 | nd->nd_state = NS_CLOSED; | ||
| 986 | nd->nd_flag = 0; | ||
| 987 | |||
| 988 | /* | ||
| 989 | * TODO ... must the wait queue be reset on close? | ||
| 990 | * should any pending waiters be reset? | ||
| 991 | * Let's decide to assert that the waitq is empty... and see | ||
| 992 | * how soon we break. | ||
| 993 | */ | ||
| 994 | if (waitqueue_active(&nd->nd_tx_waitq)) | ||
| 995 | pr_info("%s - expected waitqueue_active to be false\n", | ||
| 996 | __func__); | ||
| 997 | |||
| 998 | nd->nd_send = 0; | ||
| 999 | |||
| 1000 | kfree(nd->nd_iobuf); | ||
| 1001 | nd->nd_iobuf = NULL; | ||
| 1002 | |||
| 1003 | /* TODO : historical locking placeholder */ | ||
| 1004 | /* | ||
| 1005 | * In the HPUX version of the RealPort driver (which served as a basis | ||
| 1006 | * for this driver) this locking code was used. Saved if ever we need | ||
| 1007 | * to review the locking under Linux. | ||
| 1008 | */ | ||
| 1009 | /* spinunlock( &nd->nd_lock ); */ | ||
| 1010 | |||
| 1011 | |||
| 1012 | kfree(nd->nd_writebuf); | ||
| 1013 | nd->nd_writebuf = NULL; | ||
| 1014 | |||
| 1015 | kfree(nd->nd_inputbuf); | ||
| 1016 | nd->nd_inputbuf = NULL; | ||
| 1017 | |||
| 1018 | kfree(nd->nd_inputflagbuf); | ||
| 1019 | nd->nd_inputflagbuf = NULL; | ||
| 1020 | |||
| 1021 | /* TODO : historical locking placeholder */ | ||
| 1022 | /* | ||
| 1023 | * In the HPUX version of the RealPort driver (which served as a basis | ||
| 1024 | * for this driver) this locking code was used. Saved if ever we need | ||
| 1025 | * to review the locking under Linux. | ||
| 1026 | */ | ||
| 1027 | /* spinlock(&nd->nd_lock); */ | ||
| 1028 | |||
| 1029 | /* | ||
| 1030 | * Set the active port count to zero. | ||
| 1031 | */ | ||
| 1032 | dgrp_chan_count(nd, 0); | ||
| 1033 | |||
| 1034 | /* TODO : historical locking placeholder */ | ||
| 1035 | /* | ||
| 1036 | * In the HPUX version of the RealPort driver (which served as a basis | ||
| 1037 | * for this driver) this locking code was used. Saved if ever we need | ||
| 1038 | * to review the locking under Linux. | ||
| 1039 | */ | ||
| 1040 | /* spinunlock(&nd->nd_lock); */ | ||
| 1041 | |||
| 1042 | /* | ||
| 1043 | * Release the NET lock. | ||
| 1044 | */ | ||
| 1045 | up(&nd->nd_net_semaphore); | ||
| 1046 | |||
| 1047 | /* | ||
| 1048 | * Cause the poller to stop scheduling itself if this is | ||
| 1049 | * the last active node. | ||
| 1050 | */ | ||
| 1051 | spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags); | ||
| 1052 | |||
| 1053 | if (dgrp_poll_data.node_active_count == 2) { | ||
| 1054 | del_timer(&dgrp_poll_data.timer); | ||
| 1055 | dgrp_poll_data.node_active_count = 0; | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags); | ||
| 1059 | |||
| 1060 | done: | ||
| 1061 | down(&nd->nd_net_semaphore); | ||
| 1062 | |||
| 1063 | dgrp_monitor_message(nd, "Net Close"); | ||
| 1064 | |||
| 1065 | up(&nd->nd_net_semaphore); | ||
| 1066 | |||
| 1067 | module_put(THIS_MODULE); | ||
| 1068 | file->private_data = NULL; | ||
| 1069 | return 0; | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | /* used in dgrp_send to setup command header */ | ||
| 1073 | static inline u8 *set_cmd_header(u8 *b, u8 port, u8 cmd) | ||
| 1074 | { | ||
| 1075 | *b++ = 0xb0 + (port & 0x0f); | ||
| 1076 | *b++ = cmd; | ||
| 1077 | return b; | ||
| 1078 | } | ||
| 1079 | |||
| 1080 | /** | ||
| 1081 | * dgrp_send() -- build a packet for transmission to the server | ||
| 1082 | * @nd: pointer to a node structure | ||
| 1083 | * @tmax: maximum bytes to transmit | ||
| 1084 | * | ||
| 1085 | * returns number of bytes sent | ||
| 1086 | */ | ||
| 1087 | static int dgrp_send(struct nd_struct *nd, long tmax) | ||
| 1088 | { | ||
| 1089 | struct ch_struct *ch = nd->nd_chan; | ||
| 1090 | u8 *b; | ||
| 1091 | u8 *buf; | ||
| 1092 | u8 *mbuf; | ||
| 1093 | u8 port; | ||
| 1094 | int mod; | ||
| 1095 | long send; | ||
| 1096 | int maxport; | ||
| 1097 | long lastport = -1; | ||
| 1098 | ushort rwin; | ||
| 1099 | long in; | ||
| 1100 | ushort n; | ||
| 1101 | long t; | ||
| 1102 | long ttotal; | ||
| 1103 | long tchan; | ||
| 1104 | long tsend; | ||
| 1105 | ushort tsafe; | ||
| 1106 | long work; | ||
| 1107 | long send_sync; | ||
| 1108 | long wanted_sync_port = -1; | ||
| 1109 | ushort tdata[CHAN_MAX]; | ||
| 1110 | long used_buffer; | ||
| 1111 | |||
| 1112 | mbuf = nd->nd_iobuf + UIO_BASE; | ||
| 1113 | buf = b = mbuf; | ||
| 1114 | |||
| 1115 | send_sync = nd->nd_link.lk_slow_rate < UIO_MAX; | ||
| 1116 | |||
| 1117 | ttotal = 0; | ||
| 1118 | tchan = 0; | ||
| 1119 | |||
| 1120 | memset(tdata, 0, sizeof(tdata)); | ||
| 1121 | |||
| 1122 | |||
| 1123 | /* | ||
| 1124 | * If there are any outstanding requests to be serviced, | ||
| 1125 | * service them here. | ||
| 1126 | */ | ||
| 1127 | if (nd->nd_send & NR_PASSWORD) { | ||
| 1128 | |||
| 1129 | /* | ||
| 1130 | * Send Password response. | ||
| 1131 | */ | ||
| 1132 | |||
| 1133 | b[0] = 0xfc; | ||
| 1134 | b[1] = 0x20; | ||
| 1135 | put_unaligned_be16(strlen(nd->password), b + 2); | ||
| 1136 | b += 4; | ||
| 1137 | b += strlen(nd->password); | ||
| 1138 | nd->nd_send &= ~(NR_PASSWORD); | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | |||
| 1142 | /* | ||
| 1143 | * Loop over all modules to generate commands, and determine | ||
| 1144 | * the amount of data queued for transmit. | ||
| 1145 | */ | ||
| 1146 | |||
| 1147 | for (mod = 0, port = 0; port < nd->nd_chan_count; mod++) { | ||
| 1148 | /* | ||
| 1149 | * If this is not the current module, enter a module select | ||
| 1150 | * code in the buffer. | ||
| 1151 | */ | ||
| 1152 | |||
| 1153 | if (mod != nd->nd_tx_module) | ||
| 1154 | mbuf = ++b; | ||
| 1155 | |||
| 1156 | /* | ||
| 1157 | * Loop to process one module. | ||
| 1158 | */ | ||
| 1159 | |||
| 1160 | maxport = port + 16; | ||
| 1161 | |||
| 1162 | if (maxport > nd->nd_chan_count) | ||
| 1163 | maxport = nd->nd_chan_count; | ||
| 1164 | |||
| 1165 | for (; port < maxport; port++, ch++) { | ||
| 1166 | /* | ||
| 1167 | * Switch based on channel state. | ||
| 1168 | */ | ||
| 1169 | |||
| 1170 | switch (ch->ch_state) { | ||
| 1171 | /* | ||
| 1172 | * Send requests when the port is closed, and there | ||
| 1173 | * are no Open, Close or Cancel requests expected. | ||
| 1174 | */ | ||
| 1175 | |||
| 1176 | case CS_IDLE: | ||
| 1177 | /* | ||
| 1178 | * Wait until any open error code | ||
| 1179 | * has been delivered to all | ||
| 1180 | * associated ports. | ||
| 1181 | */ | ||
| 1182 | |||
| 1183 | if (ch->ch_open_error) { | ||
| 1184 | if (ch->ch_wait_count[ch->ch_otype]) { | ||
| 1185 | work = 1; | ||
| 1186 | break; | ||
| 1187 | } | ||
| 1188 | |||
| 1189 | ch->ch_open_error = 0; | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | /* | ||
| 1193 | * Wait until the channel HANGUP flag is reset | ||
| 1194 | * before sending the first open. We can only | ||
| 1195 | * get to this state after a server disconnect. | ||
| 1196 | */ | ||
| 1197 | |||
| 1198 | if ((ch->ch_flag & CH_HANGUP) != 0) | ||
| 1199 | break; | ||
| 1200 | |||
| 1201 | /* | ||
| 1202 | * If recovering from a TCP disconnect, or if | ||
| 1203 | * there is an immediate open pending, send an | ||
| 1204 | * Immediate Open request. | ||
| 1205 | */ | ||
| 1206 | if ((ch->ch_flag & CH_PORT_GONE) || | ||
| 1207 | ch->ch_wait_count[OTYPE_IMMEDIATE] != 0) { | ||
| 1208 | b = set_cmd_header(b, port, 10); | ||
| 1209 | *b++ = 0; | ||
| 1210 | |||
| 1211 | ch->ch_state = CS_WAIT_OPEN; | ||
| 1212 | ch->ch_otype = OTYPE_IMMEDIATE; | ||
| 1213 | break; | ||
| 1214 | } | ||
| 1215 | |||
| 1216 | /* | ||
| 1217 | * If there is no Persistent or Incoming Open on the wait | ||
| 1218 | * list in the server, and a thread is waiting for a | ||
| 1219 | * Persistent or Incoming Open, send a Persistent or Incoming | ||
| 1220 | * Open Request. | ||
| 1221 | */ | ||
| 1222 | if (ch->ch_otype_waiting == 0) { | ||
| 1223 | if (ch->ch_wait_count[OTYPE_PERSISTENT] != 0) { | ||
| 1224 | b = set_cmd_header(b, port, 10); | ||
| 1225 | *b++ = 1; | ||
| 1226 | |||
| 1227 | ch->ch_state = CS_WAIT_OPEN; | ||
| 1228 | ch->ch_otype = OTYPE_PERSISTENT; | ||
| 1229 | } else if (ch->ch_wait_count[OTYPE_INCOMING] != 0) { | ||
| 1230 | b = set_cmd_header(b, port, 10); | ||
| 1231 | *b++ = 2; | ||
| 1232 | |||
| 1233 | ch->ch_state = CS_WAIT_OPEN; | ||
| 1234 | ch->ch_otype = OTYPE_INCOMING; | ||
| 1235 | } | ||
| 1236 | break; | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | /* | ||
| 1240 | * If a Persistent or Incoming Open is pending in | ||
| 1241 | * the server, but there is no longer an open | ||
| 1242 | * thread waiting for it, cancel the request. | ||
| 1243 | */ | ||
| 1244 | |||
| 1245 | if (ch->ch_wait_count[ch->ch_otype_waiting] == 0) { | ||
| 1246 | b = set_cmd_header(b, port, 10); | ||
| 1247 | *b++ = 4; | ||
| 1248 | |||
| 1249 | ch->ch_state = CS_WAIT_CANCEL; | ||
| 1250 | ch->ch_otype = ch->ch_otype_waiting; | ||
| 1251 | } | ||
| 1252 | break; | ||
| 1253 | |||
| 1254 | /* | ||
| 1255 | * Send port parameter queries. | ||
| 1256 | */ | ||
| 1257 | case CS_SEND_QUERY: | ||
| 1258 | /* | ||
| 1259 | * Clear out all FEP state that might remain | ||
| 1260 | * from the last connection. | ||
| 1261 | */ | ||
| 1262 | |||
| 1263 | ch->ch_flag |= CH_PARAM; | ||
| 1264 | |||
| 1265 | ch->ch_flag &= ~CH_RX_FLUSH; | ||
| 1266 | |||
| 1267 | ch->ch_expect = 0; | ||
| 1268 | |||
| 1269 | ch->ch_s_tin = 0; | ||
| 1270 | ch->ch_s_tpos = 0; | ||
| 1271 | ch->ch_s_tsize = 0; | ||
| 1272 | ch->ch_s_treq = 0; | ||
| 1273 | ch->ch_s_elast = 0; | ||
| 1274 | |||
| 1275 | ch->ch_s_rin = 0; | ||
| 1276 | ch->ch_s_rwin = 0; | ||
| 1277 | ch->ch_s_rsize = 0; | ||
| 1278 | |||
| 1279 | ch->ch_s_tmax = 0; | ||
| 1280 | ch->ch_s_ttime = 0; | ||
| 1281 | ch->ch_s_rmax = 0; | ||
| 1282 | ch->ch_s_rtime = 0; | ||
| 1283 | ch->ch_s_rlow = 0; | ||
| 1284 | ch->ch_s_rhigh = 0; | ||
| 1285 | |||
| 1286 | ch->ch_s_brate = 0; | ||
| 1287 | ch->ch_s_iflag = 0; | ||
| 1288 | ch->ch_s_cflag = 0; | ||
| 1289 | ch->ch_s_oflag = 0; | ||
| 1290 | ch->ch_s_xflag = 0; | ||
| 1291 | |||
| 1292 | ch->ch_s_mout = 0; | ||
| 1293 | ch->ch_s_mflow = 0; | ||
| 1294 | ch->ch_s_mctrl = 0; | ||
| 1295 | ch->ch_s_xon = 0; | ||
| 1296 | ch->ch_s_xoff = 0; | ||
| 1297 | ch->ch_s_lnext = 0; | ||
| 1298 | ch->ch_s_xxon = 0; | ||
| 1299 | ch->ch_s_xxoff = 0; | ||
| 1300 | |||
| 1301 | /* Send Sequence Request */ | ||
| 1302 | b = set_cmd_header(b, port, 14); | ||
| 1303 | |||
| 1304 | /* Configure Event Conditions Packet */ | ||
| 1305 | b = set_cmd_header(b, port, 42); | ||
| 1306 | put_unaligned_be16(0x02c0, b); | ||
| 1307 | b += 2; | ||
| 1308 | *b++ = (DM_DTR | DM_RTS | DM_CTS | | ||
| 1309 | DM_DSR | DM_RI | DM_CD); | ||
| 1310 | |||
| 1311 | /* Send Status Request */ | ||
| 1312 | b = set_cmd_header(b, port, 16); | ||
| 1313 | |||
| 1314 | /* Send Buffer Request */ | ||
| 1315 | b = set_cmd_header(b, port, 20); | ||
| 1316 | |||
| 1317 | /* Send Port Capability Request */ | ||
| 1318 | b = set_cmd_header(b, port, 22); | ||
| 1319 | |||
| 1320 | ch->ch_expect = (RR_SEQUENCE | | ||
| 1321 | RR_STATUS | | ||
| 1322 | RR_BUFFER | | ||
| 1323 | RR_CAPABILITY); | ||
| 1324 | |||
| 1325 | ch->ch_state = CS_WAIT_QUERY; | ||
| 1326 | |||
| 1327 | /* Raise modem signals */ | ||
| 1328 | b = set_cmd_header(b, port, 44); | ||
| 1329 | |||
| 1330 | if (ch->ch_flag & CH_PORT_GONE) | ||
| 1331 | ch->ch_s_mout = ch->ch_mout; | ||
| 1332 | else | ||
| 1333 | ch->ch_s_mout = ch->ch_mout = DM_DTR | DM_RTS; | ||
| 1334 | |||
| 1335 | *b++ = ch->ch_mout; | ||
| 1336 | *b++ = ch->ch_s_mflow = 0; | ||
| 1337 | *b++ = ch->ch_s_mctrl = ch->ch_mctrl = 0; | ||
| 1338 | |||
| 1339 | if (ch->ch_flag & CH_PORT_GONE) | ||
| 1340 | ch->ch_flag &= ~CH_PORT_GONE; | ||
| 1341 | |||
| 1342 | break; | ||
| 1343 | |||
| 1344 | /* | ||
| 1345 | * Handle normal open and ready mode. | ||
| 1346 | */ | ||
| 1347 | |||
| 1348 | case CS_READY: | ||
| 1349 | |||
| 1350 | /* | ||
| 1351 | * If the port is not open, and there are no | ||
| 1352 | * no longer any ports requesting an open, | ||
| 1353 | * then close the port. | ||
| 1354 | */ | ||
| 1355 | |||
| 1356 | if (ch->ch_open_count == 0 && | ||
| 1357 | ch->ch_wait_count[ch->ch_otype] == 0) { | ||
| 1358 | goto send_close; | ||
| 1359 | } | ||
| 1360 | |||
| 1361 | /* | ||
| 1362 | * Process waiting input. | ||
| 1363 | * | ||
| 1364 | * If there is no one to read it, discard the data. | ||
| 1365 | * | ||
| 1366 | * Otherwise if we are not in fastcook mode, or if there is a | ||
| 1367 | * fastcook thread waiting for data, send the data to the | ||
| 1368 | * line discipline. | ||
| 1369 | */ | ||
| 1370 | if (ch->ch_rin != ch->ch_rout) { | ||
| 1371 | if (ch->ch_tun.un_open_count == 0 || | ||
| 1372 | (ch->ch_tun.un_flag & UN_CLOSING) || | ||
| 1373 | (ch->ch_cflag & CF_CREAD) == 0) { | ||
| 1374 | ch->ch_rout = ch->ch_rin; | ||
| 1375 | } else if ((ch->ch_flag & CH_FAST_READ) == 0 || | ||
| 1376 | ch->ch_inwait != 0) { | ||
| 1377 | dgrp_input(ch); | ||
| 1378 | |||
| 1379 | if (ch->ch_rin != ch->ch_rout) | ||
| 1380 | work = 1; | ||
| 1381 | } | ||
| 1382 | } | ||
| 1383 | |||
| 1384 | /* | ||
| 1385 | * Handle receive flush, and changes to | ||
| 1386 | * server port parameters. | ||
| 1387 | */ | ||
| 1388 | |||
| 1389 | if (ch->ch_flag & (CH_RX_FLUSH | CH_PARAM)) { | ||
| 1390 | /* | ||
| 1391 | * If we are in receive flush mode, | ||
| 1392 | * and enough data has gone by, reset | ||
| 1393 | * receive flush mode. | ||
| 1394 | */ | ||
| 1395 | if (ch->ch_flag & CH_RX_FLUSH) { | ||
| 1396 | if (((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) > | ||
| 1397 | ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) | ||
| 1398 | ch->ch_flag &= ~CH_RX_FLUSH; | ||
| 1399 | else | ||
| 1400 | work = 1; | ||
| 1401 | } | ||
| 1402 | |||
| 1403 | /* | ||
| 1404 | * Send TMAX, TTIME. | ||
| 1405 | */ | ||
| 1406 | |||
| 1407 | if (ch->ch_s_tmax != ch->ch_tmax || | ||
| 1408 | ch->ch_s_ttime != ch->ch_ttime) { | ||
| 1409 | b = set_cmd_header(b, port, 48); | ||
| 1410 | |||
| 1411 | ch->ch_s_tmax = ch->ch_tmax; | ||
| 1412 | ch->ch_s_ttime = ch->ch_ttime; | ||
| 1413 | |||
| 1414 | put_unaligned_be16(ch->ch_s_tmax, | ||
| 1415 | b); | ||
| 1416 | b += 2; | ||
| 1417 | |||
| 1418 | put_unaligned_be16(ch->ch_s_ttime, | ||
| 1419 | b); | ||
| 1420 | b += 2; | ||
| 1421 | } | ||
| 1422 | |||
| 1423 | /* | ||
| 1424 | * Send RLOW, RHIGH. | ||
| 1425 | */ | ||
| 1426 | |||
| 1427 | if (ch->ch_s_rlow != ch->ch_rlow || | ||
| 1428 | ch->ch_s_rhigh != ch->ch_rhigh) { | ||
| 1429 | b = set_cmd_header(b, port, 45); | ||
| 1430 | |||
| 1431 | ch->ch_s_rlow = ch->ch_rlow; | ||
| 1432 | ch->ch_s_rhigh = ch->ch_rhigh; | ||
| 1433 | |||
| 1434 | put_unaligned_be16(ch->ch_s_rlow, | ||
| 1435 | b); | ||
| 1436 | b += 2; | ||
| 1437 | |||
| 1438 | put_unaligned_be16(ch->ch_s_rhigh, | ||
| 1439 | b); | ||
| 1440 | b += 2; | ||
| 1441 | } | ||
| 1442 | |||
| 1443 | /* | ||
| 1444 | * Send BRATE, CFLAG, IFLAG, | ||
| 1445 | * OFLAG, XFLAG. | ||
| 1446 | */ | ||
| 1447 | |||
| 1448 | if (ch->ch_s_brate != ch->ch_brate || | ||
| 1449 | ch->ch_s_cflag != ch->ch_cflag || | ||
| 1450 | ch->ch_s_iflag != ch->ch_iflag || | ||
| 1451 | ch->ch_s_oflag != ch->ch_oflag || | ||
| 1452 | ch->ch_s_xflag != ch->ch_xflag) { | ||
| 1453 | b = set_cmd_header(b, port, 40); | ||
| 1454 | |||
| 1455 | ch->ch_s_brate = ch->ch_brate; | ||
| 1456 | ch->ch_s_cflag = ch->ch_cflag; | ||
| 1457 | ch->ch_s_iflag = ch->ch_iflag; | ||
| 1458 | ch->ch_s_oflag = ch->ch_oflag; | ||
| 1459 | ch->ch_s_xflag = ch->ch_xflag; | ||
| 1460 | |||
| 1461 | put_unaligned_be16(ch->ch_s_brate, | ||
| 1462 | b); | ||
| 1463 | b += 2; | ||
| 1464 | |||
| 1465 | put_unaligned_be16(ch->ch_s_cflag, | ||
| 1466 | b); | ||
| 1467 | b += 2; | ||
| 1468 | |||
| 1469 | put_unaligned_be16(ch->ch_s_iflag, | ||
| 1470 | b); | ||
| 1471 | b += 2; | ||
| 1472 | |||
| 1473 | put_unaligned_be16(ch->ch_s_oflag, | ||
| 1474 | b); | ||
| 1475 | b += 2; | ||
| 1476 | |||
| 1477 | put_unaligned_be16(ch->ch_s_xflag, | ||
| 1478 | b); | ||
| 1479 | b += 2; | ||
| 1480 | } | ||
| 1481 | |||
| 1482 | /* | ||
| 1483 | * Send MOUT, MFLOW, MCTRL. | ||
| 1484 | */ | ||
| 1485 | |||
| 1486 | if (ch->ch_s_mout != ch->ch_mout || | ||
| 1487 | ch->ch_s_mflow != ch->ch_mflow || | ||
| 1488 | ch->ch_s_mctrl != ch->ch_mctrl) { | ||
| 1489 | b = set_cmd_header(b, port, 44); | ||
| 1490 | |||
| 1491 | *b++ = ch->ch_s_mout = ch->ch_mout; | ||
| 1492 | *b++ = ch->ch_s_mflow = ch->ch_mflow; | ||
| 1493 | *b++ = ch->ch_s_mctrl = ch->ch_mctrl; | ||
| 1494 | } | ||
| 1495 | |||
| 1496 | /* | ||
| 1497 | * Send Flow control characters. | ||
| 1498 | */ | ||
| 1499 | |||
| 1500 | if (ch->ch_s_xon != ch->ch_xon || | ||
| 1501 | ch->ch_s_xoff != ch->ch_xoff || | ||
| 1502 | ch->ch_s_lnext != ch->ch_lnext || | ||
| 1503 | ch->ch_s_xxon != ch->ch_xxon || | ||
| 1504 | ch->ch_s_xxoff != ch->ch_xxoff) { | ||
| 1505 | b = set_cmd_header(b, port, 46); | ||
| 1506 | |||
| 1507 | *b++ = ch->ch_s_xon = ch->ch_xon; | ||
| 1508 | *b++ = ch->ch_s_xoff = ch->ch_xoff; | ||
| 1509 | *b++ = ch->ch_s_lnext = ch->ch_lnext; | ||
| 1510 | *b++ = ch->ch_s_xxon = ch->ch_xxon; | ||
| 1511 | *b++ = ch->ch_s_xxoff = ch->ch_xxoff; | ||
| 1512 | } | ||
| 1513 | |||
| 1514 | /* | ||
| 1515 | * Send RMAX, RTIME. | ||
| 1516 | */ | ||
| 1517 | |||
| 1518 | if (ch->ch_s_rmax != ch->ch_rmax || | ||
| 1519 | ch->ch_s_rtime != ch->ch_rtime) { | ||
| 1520 | b = set_cmd_header(b, port, 47); | ||
| 1521 | |||
| 1522 | ch->ch_s_rmax = ch->ch_rmax; | ||
| 1523 | ch->ch_s_rtime = ch->ch_rtime; | ||
| 1524 | |||
| 1525 | put_unaligned_be16(ch->ch_s_rmax, | ||
| 1526 | b); | ||
| 1527 | b += 2; | ||
| 1528 | |||
| 1529 | put_unaligned_be16(ch->ch_s_rtime, | ||
| 1530 | b); | ||
| 1531 | b += 2; | ||
| 1532 | } | ||
| 1533 | |||
| 1534 | ch->ch_flag &= ~CH_PARAM; | ||
| 1535 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 1536 | } | ||
| 1537 | |||
| 1538 | |||
| 1539 | /* | ||
| 1540 | * Handle action commands. | ||
| 1541 | */ | ||
| 1542 | |||
| 1543 | if (ch->ch_send != 0) { | ||
| 1544 | /* int send = ch->ch_send & ~ch->ch_expect; */ | ||
| 1545 | send = ch->ch_send & ~ch->ch_expect; | ||
| 1546 | |||
| 1547 | /* Send character immediate */ | ||
| 1548 | if ((send & RR_TX_ICHAR) != 0) { | ||
| 1549 | b = set_cmd_header(b, port, 60); | ||
| 1550 | |||
| 1551 | *b++ = ch->ch_xon; | ||
| 1552 | ch->ch_expect |= RR_TX_ICHAR; | ||
| 1553 | } | ||
| 1554 | |||
| 1555 | /* BREAK request */ | ||
| 1556 | if ((send & RR_TX_BREAK) != 0) { | ||
| 1557 | if (ch->ch_break_time != 0) { | ||
| 1558 | b = set_cmd_header(b, port, 61); | ||
| 1559 | put_unaligned_be16(ch->ch_break_time, | ||
| 1560 | b); | ||
| 1561 | b += 2; | ||
| 1562 | |||
| 1563 | ch->ch_expect |= RR_TX_BREAK; | ||
| 1564 | ch->ch_break_time = 0; | ||
| 1565 | } else { | ||
| 1566 | ch->ch_send &= ~RR_TX_BREAK; | ||
| 1567 | ch->ch_flag &= ~CH_TX_BREAK; | ||
| 1568 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 1569 | } | ||
| 1570 | } | ||
| 1571 | |||
| 1572 | /* | ||
| 1573 | * Flush input/output buffers. | ||
| 1574 | */ | ||
| 1575 | |||
| 1576 | if ((send & (RR_RX_FLUSH | RR_TX_FLUSH)) != 0) { | ||
| 1577 | b = set_cmd_header(b, port, 62); | ||
| 1578 | |||
| 1579 | *b++ = ((send & RR_TX_FLUSH) == 0 ? 1 : | ||
| 1580 | (send & RR_RX_FLUSH) == 0 ? 2 : 3); | ||
| 1581 | |||
| 1582 | if (send & RR_RX_FLUSH) { | ||
| 1583 | ch->ch_flush_seq = nd->nd_seq_in; | ||
| 1584 | ch->ch_flag |= CH_RX_FLUSH; | ||
| 1585 | work = 1; | ||
| 1586 | send_sync = 1; | ||
| 1587 | wanted_sync_port = port; | ||
| 1588 | } | ||
| 1589 | |||
| 1590 | ch->ch_send &= ~(RR_RX_FLUSH | RR_TX_FLUSH); | ||
| 1591 | } | ||
| 1592 | |||
| 1593 | /* Pause input/output */ | ||
| 1594 | if ((send & (RR_RX_STOP | RR_TX_STOP)) != 0) { | ||
| 1595 | b = set_cmd_header(b, port, 63); | ||
| 1596 | *b = 0; | ||
| 1597 | |||
| 1598 | if ((send & RR_TX_STOP) != 0) | ||
| 1599 | *b |= EV_OPU; | ||
| 1600 | |||
| 1601 | if ((send & RR_RX_STOP) != 0) | ||
| 1602 | *b |= EV_IPU; | ||
| 1603 | |||
| 1604 | b++; | ||
| 1605 | |||
| 1606 | ch->ch_send &= ~(RR_RX_STOP | RR_TX_STOP); | ||
| 1607 | } | ||
| 1608 | |||
| 1609 | /* Start input/output */ | ||
| 1610 | if ((send & (RR_RX_START | RR_TX_START)) != 0) { | ||
| 1611 | b = set_cmd_header(b, port, 64); | ||
| 1612 | *b = 0; | ||
| 1613 | |||
| 1614 | if ((send & RR_TX_START) != 0) | ||
| 1615 | *b |= EV_OPU | EV_OPS | EV_OPX; | ||
| 1616 | |||
| 1617 | if ((send & RR_RX_START) != 0) | ||
| 1618 | *b |= EV_IPU | EV_IPS; | ||
| 1619 | |||
| 1620 | b++; | ||
| 1621 | |||
| 1622 | ch->ch_send &= ~(RR_RX_START | RR_TX_START); | ||
| 1623 | } | ||
| 1624 | } | ||
| 1625 | |||
| 1626 | |||
| 1627 | /* | ||
| 1628 | * Send a window sequence to acknowledge received data. | ||
| 1629 | */ | ||
| 1630 | |||
| 1631 | rwin = (ch->ch_s_rin + | ||
| 1632 | ((ch->ch_rout - ch->ch_rin - 1) & RBUF_MASK)); | ||
| 1633 | |||
| 1634 | n = (rwin - ch->ch_s_rwin) & 0xffff; | ||
| 1635 | |||
| 1636 | if (n >= RBUF_MAX / 4) { | ||
| 1637 | b[0] = 0xa0 + (port & 0xf); | ||
| 1638 | ch->ch_s_rwin = rwin; | ||
| 1639 | put_unaligned_be16(rwin, b + 1); | ||
| 1640 | b += 3; | ||
| 1641 | } | ||
| 1642 | |||
| 1643 | /* | ||
| 1644 | * If the terminal is waiting on LOW | ||
| 1645 | * water or EMPTY, and the condition | ||
| 1646 | * is now satisfied, call the line | ||
| 1647 | * discipline to put more data in the | ||
| 1648 | * buffer. | ||
| 1649 | */ | ||
| 1650 | |||
| 1651 | n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK; | ||
| 1652 | |||
| 1653 | if ((ch->ch_tun.un_flag & (UN_EMPTY|UN_LOW)) != 0) { | ||
| 1654 | if ((ch->ch_tun.un_flag & UN_LOW) != 0 ? | ||
| 1655 | (n <= TBUF_LOW) : | ||
| 1656 | (n == 0 && ch->ch_s_tpos == ch->ch_s_tin)) { | ||
| 1657 | ch->ch_tun.un_flag &= ~(UN_EMPTY|UN_LOW); | ||
| 1658 | |||
| 1659 | if (waitqueue_active(&((ch->ch_tun.un_tty)->write_wait))) | ||
| 1660 | wake_up_interruptible(&((ch->ch_tun.un_tty)->write_wait)); | ||
| 1661 | tty_wakeup(ch->ch_tun.un_tty); | ||
| 1662 | n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK; | ||
| 1663 | } | ||
| 1664 | } | ||
| 1665 | |||
| 1666 | /* | ||
| 1667 | * If the printer is waiting on LOW | ||
| 1668 | * water, TIME, EMPTY or PWAIT, and is | ||
| 1669 | * now ready to put more data in the | ||
| 1670 | * buffer, call the line discipline to | ||
| 1671 | * do the job. | ||
| 1672 | */ | ||
| 1673 | |||
| 1674 | if (ch->ch_pun.un_open_count && | ||
| 1675 | (ch->ch_pun.un_flag & | ||
| 1676 | (UN_EMPTY|UN_TIME|UN_LOW|UN_PWAIT)) != 0) { | ||
| 1677 | |||
| 1678 | if ((ch->ch_pun.un_flag & UN_LOW) != 0 ? | ||
| 1679 | (n <= TBUF_LOW) : | ||
| 1680 | (ch->ch_pun.un_flag & UN_TIME) != 0 ? | ||
| 1681 | ((jiffies - ch->ch_waketime) >= 0) : | ||
| 1682 | (n == 0 && ch->ch_s_tpos == ch->ch_s_tin) && | ||
| 1683 | ((ch->ch_pun.un_flag & UN_EMPTY) != 0 || | ||
| 1684 | ((ch->ch_tun.un_open_count && | ||
| 1685 | ch->ch_tun.un_tty->ops->chars_in_buffer) ? | ||
| 1686 | (ch->ch_tun.un_tty->ops->chars_in_buffer)(ch->ch_tun.un_tty) == 0 | ||
| 1687 | : 1 | ||
| 1688 | ) | ||
| 1689 | )) { | ||
| 1690 | ch->ch_pun.un_flag &= ~(UN_EMPTY | UN_TIME | UN_LOW | UN_PWAIT); | ||
| 1691 | |||
| 1692 | if (waitqueue_active(&((ch->ch_pun.un_tty)->write_wait))) | ||
| 1693 | wake_up_interruptible(&((ch->ch_pun.un_tty)->write_wait)); | ||
| 1694 | tty_wakeup(ch->ch_pun.un_tty); | ||
| 1695 | n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK; | ||
| 1696 | |||
| 1697 | } else if ((ch->ch_pun.un_flag & UN_TIME) != 0) { | ||
| 1698 | work = 1; | ||
| 1699 | } | ||
| 1700 | } | ||
| 1701 | |||
| 1702 | |||
| 1703 | /* | ||
| 1704 | * Determine the max number of bytes | ||
| 1705 | * this port can send, including | ||
| 1706 | * packet header overhead. | ||
| 1707 | */ | ||
| 1708 | |||
| 1709 | t = ((ch->ch_s_tsize + ch->ch_s_tpos - ch->ch_s_tin) & 0xffff); | ||
| 1710 | |||
| 1711 | if (n > t) | ||
| 1712 | n = t; | ||
| 1713 | |||
| 1714 | if (n != 0) { | ||
| 1715 | n += (n <= 8 ? 1 : n <= 255 ? 2 : 3); | ||
| 1716 | |||
| 1717 | tdata[tchan++] = n; | ||
| 1718 | ttotal += n; | ||
| 1719 | } | ||
| 1720 | break; | ||
| 1721 | |||
| 1722 | /* | ||
| 1723 | * Close the port. | ||
| 1724 | */ | ||
| 1725 | |||
| 1726 | send_close: | ||
| 1727 | case CS_SEND_CLOSE: | ||
| 1728 | b = set_cmd_header(b, port, 10); | ||
| 1729 | if (ch->ch_otype == OTYPE_IMMEDIATE) | ||
| 1730 | *b++ = 3; | ||
| 1731 | else | ||
| 1732 | *b++ = 4; | ||
| 1733 | |||
| 1734 | ch->ch_state = CS_WAIT_CLOSE; | ||
| 1735 | break; | ||
| 1736 | |||
| 1737 | /* | ||
| 1738 | * Wait for a previous server request. | ||
| 1739 | */ | ||
| 1740 | |||
| 1741 | case CS_WAIT_OPEN: | ||
| 1742 | case CS_WAIT_CANCEL: | ||
| 1743 | case CS_WAIT_FAIL: | ||
| 1744 | case CS_WAIT_QUERY: | ||
| 1745 | case CS_WAIT_CLOSE: | ||
| 1746 | break; | ||
| 1747 | |||
| 1748 | default: | ||
| 1749 | pr_info("%s - unexpected channel state (%i)\n", | ||
| 1750 | __func__, ch->ch_state); | ||
| 1751 | } | ||
| 1752 | } | ||
| 1753 | |||
| 1754 | /* | ||
| 1755 | * If a module select code is needed, drop one in. If space | ||
| 1756 | * was reserved for one, but none is needed, recover the space. | ||
| 1757 | */ | ||
| 1758 | |||
| 1759 | if (mod != nd->nd_tx_module) { | ||
| 1760 | if (b != mbuf) { | ||
| 1761 | mbuf[-1] = 0xf0 | mod; | ||
| 1762 | nd->nd_tx_module = mod; | ||
| 1763 | } else { | ||
| 1764 | b--; | ||
| 1765 | } | ||
| 1766 | } | ||
| 1767 | } | ||
| 1768 | |||
| 1769 | /* | ||
| 1770 | * Adjust "tmax" so that under worst case conditions we do | ||
| 1771 | * not overflow either the daemon buffer or the internal | ||
| 1772 | * buffer in the loop that follows. Leave a safe area | ||
| 1773 | * of 64 bytes so we start getting asserts before we start | ||
| 1774 | * losing data or clobbering memory. | ||
| 1775 | */ | ||
| 1776 | |||
| 1777 | n = UIO_MAX - UIO_BASE; | ||
| 1778 | |||
| 1779 | if (tmax > n) | ||
| 1780 | tmax = n; | ||
| 1781 | |||
| 1782 | tmax -= 64; | ||
| 1783 | |||
| 1784 | tsafe = tmax; | ||
| 1785 | |||
| 1786 | /* | ||
| 1787 | * Allocate space for 5 Module Selects, 1 Sequence Request, | ||
| 1788 | * and 1 Set TREQ for each active channel. | ||
| 1789 | */ | ||
| 1790 | |||
| 1791 | tmax -= 5 + 3 + 4 * nd->nd_chan_count; | ||
| 1792 | |||
| 1793 | /* | ||
| 1794 | * Further reduce "tmax" to the available transmit credit. | ||
| 1795 | * Note that this is a soft constraint; The transmit credit | ||
| 1796 | * can go negative for a time and then recover. | ||
| 1797 | */ | ||
| 1798 | |||
| 1799 | n = nd->nd_tx_deposit - nd->nd_tx_charge - nd->nd_link.lk_header_size; | ||
| 1800 | |||
| 1801 | if (tmax > n) | ||
| 1802 | tmax = n; | ||
| 1803 | |||
| 1804 | /* | ||
| 1805 | * Finally reduce tmax by the number of bytes already in | ||
| 1806 | * the buffer. | ||
| 1807 | */ | ||
| 1808 | |||
| 1809 | tmax -= b - buf; | ||
| 1810 | |||
| 1811 | /* | ||
| 1812 | * Suspend data transmit unless every ready channel can send | ||
| 1813 | * at least 1 character. | ||
| 1814 | */ | ||
| 1815 | if (tmax < 2 * nd->nd_chan_count) { | ||
| 1816 | tsend = 1; | ||
| 1817 | |||
| 1818 | } else if (tchan > 1 && ttotal > tmax) { | ||
| 1819 | |||
| 1820 | /* | ||
| 1821 | * If transmit is limited by the credit budget, find the | ||
| 1822 | * largest number of characters we can send without driving | ||
| 1823 | * the credit negative. | ||
| 1824 | */ | ||
| 1825 | |||
| 1826 | long tm = tmax; | ||
| 1827 | int tc = tchan; | ||
| 1828 | int try; | ||
| 1829 | |||
| 1830 | tsend = tm / tc; | ||
| 1831 | |||
| 1832 | for (try = 0; try < 3; try++) { | ||
| 1833 | int i; | ||
| 1834 | int c = 0; | ||
| 1835 | |||
| 1836 | for (i = 0; i < tc; i++) { | ||
| 1837 | if (tsend < tdata[i]) | ||
| 1838 | tdata[c++] = tdata[i]; | ||
| 1839 | else | ||
| 1840 | tm -= tdata[i]; | ||
| 1841 | } | ||
| 1842 | |||
| 1843 | if (c == tc) | ||
| 1844 | break; | ||
| 1845 | |||
| 1846 | tsend = tm / c; | ||
| 1847 | |||
| 1848 | if (c == 1) | ||
| 1849 | break; | ||
| 1850 | |||
| 1851 | tc = c; | ||
| 1852 | } | ||
| 1853 | |||
| 1854 | tsend = tm / nd->nd_chan_count; | ||
| 1855 | |||
| 1856 | if (tsend < 2) | ||
| 1857 | tsend = 1; | ||
| 1858 | |||
| 1859 | } else { | ||
| 1860 | /* | ||
| 1861 | * If no budgetary constraints, or only one channel ready | ||
| 1862 | * to send, set the character limit to the remaining | ||
| 1863 | * buffer size. | ||
| 1864 | */ | ||
| 1865 | |||
| 1866 | tsend = tmax; | ||
| 1867 | } | ||
| 1868 | |||
| 1869 | tsend -= (tsend <= 9) ? 1 : (tsend <= 257) ? 2 : 3; | ||
| 1870 | |||
| 1871 | /* | ||
| 1872 | * Loop over all channels, sending queued data. | ||
| 1873 | */ | ||
| 1874 | |||
| 1875 | port = 0; | ||
| 1876 | ch = nd->nd_chan; | ||
| 1877 | used_buffer = tmax; | ||
| 1878 | |||
| 1879 | for (mod = 0; port < nd->nd_chan_count; mod++) { | ||
| 1880 | /* | ||
| 1881 | * If this is not the current module, enter a module select | ||
| 1882 | * code in the buffer. | ||
| 1883 | */ | ||
| 1884 | |||
| 1885 | if (mod != nd->nd_tx_module) | ||
| 1886 | mbuf = ++b; | ||
| 1887 | |||
| 1888 | /* | ||
| 1889 | * Loop to process one module. | ||
| 1890 | */ | ||
| 1891 | |||
| 1892 | maxport = port + 16; | ||
| 1893 | |||
| 1894 | if (maxport > nd->nd_chan_count) | ||
| 1895 | maxport = nd->nd_chan_count; | ||
| 1896 | |||
| 1897 | for (; port < maxport; port++, ch++) { | ||
| 1898 | if (ch->ch_state != CS_READY) | ||
| 1899 | continue; | ||
| 1900 | |||
| 1901 | lastport = port; | ||
| 1902 | |||
| 1903 | n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK; | ||
| 1904 | |||
| 1905 | /* | ||
| 1906 | * If there is data that can be sent, send it. | ||
| 1907 | */ | ||
| 1908 | |||
| 1909 | if (n != 0 && used_buffer > 0) { | ||
| 1910 | t = (ch->ch_s_tsize + ch->ch_s_tpos - ch->ch_s_tin) & 0xffff; | ||
| 1911 | |||
| 1912 | if (n > t) | ||
| 1913 | n = t; | ||
| 1914 | |||
| 1915 | if (n > tsend) { | ||
| 1916 | work = 1; | ||
| 1917 | n = tsend; | ||
| 1918 | } | ||
| 1919 | |||
| 1920 | if (n > used_buffer) { | ||
| 1921 | work = 1; | ||
| 1922 | n = used_buffer; | ||
| 1923 | } | ||
| 1924 | |||
| 1925 | if (n <= 0) | ||
| 1926 | continue; | ||
| 1927 | |||
| 1928 | /* | ||
| 1929 | * Create the correct size transmit header, | ||
| 1930 | * depending on the amount of data to transmit. | ||
| 1931 | */ | ||
| 1932 | |||
| 1933 | if (n <= 8) { | ||
| 1934 | |||
| 1935 | b[0] = ((n - 1) << 4) + (port & 0xf); | ||
| 1936 | b += 1; | ||
| 1937 | |||
| 1938 | } else if (n <= 255) { | ||
| 1939 | |||
| 1940 | b[0] = 0x80 + (port & 0xf); | ||
| 1941 | b[1] = n; | ||
| 1942 | b += 2; | ||
| 1943 | |||
| 1944 | } else { | ||
| 1945 | |||
| 1946 | b[0] = 0x90 + (port & 0xf); | ||
| 1947 | put_unaligned_be16(n, b + 1); | ||
| 1948 | b += 3; | ||
| 1949 | } | ||
| 1950 | |||
| 1951 | ch->ch_s_tin = (ch->ch_s_tin + n) & 0xffff; | ||
| 1952 | |||
| 1953 | /* | ||
| 1954 | * Copy transmit data to the packet. | ||
| 1955 | */ | ||
| 1956 | |||
| 1957 | t = TBUF_MAX - ch->ch_tout; | ||
| 1958 | |||
| 1959 | if (n >= t) { | ||
| 1960 | memcpy(b, ch->ch_tbuf + ch->ch_tout, t); | ||
| 1961 | b += t; | ||
| 1962 | n -= t; | ||
| 1963 | used_buffer -= t; | ||
| 1964 | ch->ch_tout = 0; | ||
| 1965 | } | ||
| 1966 | |||
| 1967 | memcpy(b, ch->ch_tbuf + ch->ch_tout, n); | ||
| 1968 | b += n; | ||
| 1969 | used_buffer -= n; | ||
| 1970 | ch->ch_tout += n; | ||
| 1971 | n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK; | ||
| 1972 | } | ||
| 1973 | |||
| 1974 | /* | ||
| 1975 | * Wake any terminal unit process waiting in the | ||
| 1976 | * dgrp_write routine for low water. | ||
| 1977 | */ | ||
| 1978 | |||
| 1979 | if (n > TBUF_LOW) | ||
| 1980 | continue; | ||
| 1981 | |||
| 1982 | if ((ch->ch_flag & CH_LOW) != 0) { | ||
| 1983 | ch->ch_flag &= ~CH_LOW; | ||
| 1984 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 1985 | } | ||
| 1986 | |||
| 1987 | /* selwakeup tty_sel */ | ||
| 1988 | if (ch->ch_tun.un_open_count) { | ||
| 1989 | struct tty_struct *tty = (ch->ch_tun.un_tty); | ||
| 1990 | |||
| 1991 | if (waitqueue_active(&tty->write_wait)) | ||
| 1992 | wake_up_interruptible(&tty->write_wait); | ||
| 1993 | |||
| 1994 | tty_wakeup(tty); | ||
| 1995 | } | ||
| 1996 | |||
| 1997 | if (ch->ch_pun.un_open_count) { | ||
| 1998 | struct tty_struct *tty = (ch->ch_pun.un_tty); | ||
| 1999 | |||
| 2000 | if (waitqueue_active(&tty->write_wait)) | ||
| 2001 | wake_up_interruptible(&tty->write_wait); | ||
| 2002 | |||
| 2003 | tty_wakeup(tty); | ||
| 2004 | } | ||
| 2005 | |||
| 2006 | /* | ||
| 2007 | * Do EMPTY processing. | ||
| 2008 | */ | ||
| 2009 | |||
| 2010 | if (n != 0) | ||
| 2011 | continue; | ||
| 2012 | |||
| 2013 | if ((ch->ch_flag & (CH_EMPTY | CH_DRAIN)) != 0 || | ||
| 2014 | (ch->ch_pun.un_flag & UN_EMPTY) != 0) { | ||
| 2015 | /* | ||
| 2016 | * If there is still data in the server, ask the server | ||
| 2017 | * to notify us when its all gone. | ||
| 2018 | */ | ||
| 2019 | |||
| 2020 | if (ch->ch_s_treq != ch->ch_s_tin) { | ||
| 2021 | b = set_cmd_header(b, port, 43); | ||
| 2022 | |||
| 2023 | ch->ch_s_treq = ch->ch_s_tin; | ||
| 2024 | put_unaligned_be16(ch->ch_s_treq, | ||
| 2025 | b); | ||
| 2026 | b += 2; | ||
| 2027 | } | ||
| 2028 | |||
| 2029 | /* | ||
| 2030 | * If there is a thread waiting for buffer empty, | ||
| 2031 | * and we are truly empty, wake the thread. | ||
| 2032 | */ | ||
| 2033 | |||
| 2034 | else if ((ch->ch_flag & CH_EMPTY) != 0 && | ||
| 2035 | (ch->ch_send & RR_TX_BREAK) == 0) { | ||
| 2036 | ch->ch_flag &= ~CH_EMPTY; | ||
| 2037 | |||
| 2038 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 2039 | } | ||
| 2040 | } | ||
| 2041 | } | ||
| 2042 | |||
| 2043 | /* | ||
| 2044 | * If a module select code is needed, drop one in. If space | ||
| 2045 | * was reserved for one, but none is needed, recover the space. | ||
| 2046 | */ | ||
| 2047 | |||
| 2048 | if (mod != nd->nd_tx_module) { | ||
| 2049 | if (b != mbuf) { | ||
| 2050 | mbuf[-1] = 0xf0 | mod; | ||
| 2051 | nd->nd_tx_module = mod; | ||
| 2052 | } else { | ||
| 2053 | b--; | ||
| 2054 | } | ||
| 2055 | } | ||
| 2056 | } | ||
| 2057 | |||
| 2058 | /* | ||
| 2059 | * Send a synchronization sequence associated with the last open | ||
| 2060 | * channel that sent data, and remember the time when the data was | ||
| 2061 | * sent. | ||
| 2062 | */ | ||
| 2063 | |||
| 2064 | in = nd->nd_seq_in; | ||
| 2065 | |||
| 2066 | if ((send_sync || nd->nd_seq_wait[in] != 0) && lastport >= 0) { | ||
| 2067 | u8 *bb = b; | ||
| 2068 | |||
| 2069 | /* | ||
| 2070 | * Attempt the use the port that really wanted the sync. | ||
| 2071 | * This gets around a race condition where the "lastport" is in | ||
| 2072 | * the middle of the close() routine, and by the time we | ||
| 2073 | * send this command, it will have already acked the close, and | ||
| 2074 | * thus not send the sync response. | ||
| 2075 | */ | ||
| 2076 | if (wanted_sync_port >= 0) | ||
| 2077 | lastport = wanted_sync_port; | ||
| 2078 | /* | ||
| 2079 | * Set a flag just in case the port is in the middle of a close, | ||
| 2080 | * it will not be permitted to actually close until we get an | ||
| 2081 | * sync response, and clear the flag there. | ||
| 2082 | */ | ||
| 2083 | ch = nd->nd_chan + lastport; | ||
| 2084 | ch->ch_flag |= CH_WAITING_SYNC; | ||
| 2085 | |||
| 2086 | mod = lastport >> 4; | ||
| 2087 | |||
| 2088 | if (mod != nd->nd_tx_module) { | ||
| 2089 | bb[0] = 0xf0 + mod; | ||
| 2090 | bb += 1; | ||
| 2091 | |||
| 2092 | nd->nd_tx_module = mod; | ||
| 2093 | } | ||
| 2094 | |||
| 2095 | bb = set_cmd_header(bb, lastport, 12); | ||
| 2096 | *bb++ = in; | ||
| 2097 | |||
| 2098 | nd->nd_seq_size[in] = bb - buf; | ||
| 2099 | nd->nd_seq_time[in] = jiffies; | ||
| 2100 | |||
| 2101 | if (++in >= SEQ_MAX) | ||
| 2102 | in = 0; | ||
| 2103 | |||
| 2104 | if (in != nd->nd_seq_out) { | ||
| 2105 | b = bb; | ||
| 2106 | nd->nd_seq_in = in; | ||
| 2107 | nd->nd_unack += b - buf; | ||
| 2108 | } | ||
| 2109 | } | ||
| 2110 | |||
| 2111 | /* | ||
| 2112 | * If there are no open ports, a sync cannot be sent. | ||
| 2113 | * There is nothing left to wait for anyway, so wake any | ||
| 2114 | * thread waiting for an acknowledgement. | ||
| 2115 | */ | ||
| 2116 | |||
| 2117 | else if (nd->nd_seq_wait[in] != 0) { | ||
| 2118 | nd->nd_seq_wait[in] = 0; | ||
| 2119 | |||
| 2120 | wake_up_interruptible(&nd->nd_seq_wque[in]); | ||
| 2121 | } | ||
| 2122 | |||
| 2123 | /* | ||
| 2124 | * If there is no traffic for an interval of IDLE_MAX, then | ||
| 2125 | * send a single byte packet. | ||
| 2126 | */ | ||
| 2127 | |||
| 2128 | if (b != buf) { | ||
| 2129 | nd->nd_tx_time = jiffies; | ||
| 2130 | } else if ((ulong)(jiffies - nd->nd_tx_time) >= IDLE_MAX) { | ||
| 2131 | *b++ = 0xf0 | nd->nd_tx_module; | ||
| 2132 | nd->nd_tx_time = jiffies; | ||
| 2133 | } | ||
| 2134 | |||
| 2135 | n = b - buf; | ||
| 2136 | |||
| 2137 | if (n >= tsafe) | ||
| 2138 | pr_info("%s - n(%i) >= tsafe(%i)\n", | ||
| 2139 | __func__, n, tsafe); | ||
| 2140 | |||
| 2141 | if (tsend < 0) | ||
| 2142 | dgrp_dump(buf, n); | ||
| 2143 | |||
| 2144 | nd->nd_tx_work = work; | ||
| 2145 | |||
| 2146 | return n; | ||
| 2147 | } | ||
| 2148 | |||
| 2149 | /* | ||
| 2150 | * dgrp_net_read() | ||
| 2151 | * Data to be sent TO the PortServer from the "async." half of the driver. | ||
| 2152 | */ | ||
| 2153 | static ssize_t dgrp_net_read(struct file *file, char __user *buf, size_t count, | ||
| 2154 | loff_t *ppos) | ||
| 2155 | { | ||
| 2156 | struct nd_struct *nd; | ||
| 2157 | long n; | ||
| 2158 | u8 *local_buf; | ||
| 2159 | u8 *b; | ||
| 2160 | ssize_t rtn; | ||
| 2161 | |||
| 2162 | /* | ||
| 2163 | * Get the node pointer, and quit if it doesn't exist. | ||
| 2164 | */ | ||
| 2165 | nd = (struct nd_struct *)(file->private_data); | ||
| 2166 | if (!nd) | ||
| 2167 | return -ENXIO; | ||
| 2168 | |||
| 2169 | if (count < UIO_MIN) | ||
| 2170 | return -EINVAL; | ||
| 2171 | |||
| 2172 | /* | ||
| 2173 | * Only one read/write operation may be in progress at | ||
| 2174 | * any given time. | ||
| 2175 | */ | ||
| 2176 | |||
| 2177 | /* | ||
| 2178 | * Grab the NET lock. | ||
| 2179 | */ | ||
| 2180 | down(&nd->nd_net_semaphore); | ||
| 2181 | |||
| 2182 | nd->nd_read_count++; | ||
| 2183 | |||
| 2184 | nd->nd_tx_ready = 0; | ||
| 2185 | |||
| 2186 | /* | ||
| 2187 | * Determine the effective size of the buffer. | ||
| 2188 | */ | ||
| 2189 | |||
| 2190 | if (nd->nd_remain > UIO_BASE) | ||
| 2191 | pr_info_ratelimited("%s - nd_remain(%i) > UIO_BASE\n", | ||
| 2192 | __func__, nd->nd_remain); | ||
| 2193 | |||
| 2194 | b = local_buf = nd->nd_iobuf + UIO_BASE; | ||
| 2195 | |||
| 2196 | /* | ||
| 2197 | * Generate data according to the node state. | ||
| 2198 | */ | ||
| 2199 | |||
| 2200 | switch (nd->nd_state) { | ||
| 2201 | /* | ||
| 2202 | * Initialize the connection. | ||
| 2203 | */ | ||
| 2204 | |||
| 2205 | case NS_IDLE: | ||
| 2206 | if (nd->nd_mon_buf) | ||
| 2207 | dgrp_monitor_reset(nd); | ||
| 2208 | |||
| 2209 | /* | ||
| 2210 | * Request a Product ID Packet. | ||
| 2211 | */ | ||
| 2212 | |||
| 2213 | b[0] = 0xfb; | ||
| 2214 | b[1] = 0x01; | ||
| 2215 | b += 2; | ||
| 2216 | |||
| 2217 | nd->nd_expect |= NR_IDENT; | ||
| 2218 | |||
| 2219 | /* | ||
| 2220 | * Request a Server Capability ID Response. | ||
| 2221 | */ | ||
| 2222 | |||
| 2223 | b[0] = 0xfb; | ||
| 2224 | b[1] = 0x02; | ||
| 2225 | b += 2; | ||
| 2226 | |||
| 2227 | nd->nd_expect |= NR_CAPABILITY; | ||
| 2228 | |||
| 2229 | /* | ||
| 2230 | * Request a Server VPD Response. | ||
| 2231 | */ | ||
| 2232 | |||
| 2233 | b[0] = 0xfb; | ||
| 2234 | b[1] = 0x18; | ||
| 2235 | b += 2; | ||
| 2236 | |||
| 2237 | nd->nd_expect |= NR_VPD; | ||
| 2238 | |||
| 2239 | nd->nd_state = NS_WAIT_QUERY; | ||
| 2240 | break; | ||
| 2241 | |||
| 2242 | /* | ||
| 2243 | * We do serious communication with the server only in | ||
| 2244 | * the READY state. | ||
| 2245 | */ | ||
| 2246 | |||
| 2247 | case NS_READY: | ||
| 2248 | b = dgrp_send(nd, count) + local_buf; | ||
| 2249 | break; | ||
| 2250 | |||
| 2251 | /* | ||
| 2252 | * Send off an error after receiving a bogus message | ||
| 2253 | * from the server. | ||
| 2254 | */ | ||
| 2255 | |||
| 2256 | case NS_SEND_ERROR: | ||
| 2257 | n = strlen(nd->nd_error); | ||
| 2258 | |||
| 2259 | b[0] = 0xff; | ||
| 2260 | b[1] = n; | ||
| 2261 | memcpy(b + 2, nd->nd_error, n); | ||
| 2262 | b += 2 + n; | ||
| 2263 | |||
| 2264 | dgrp_net_idle(nd); | ||
| 2265 | /* | ||
| 2266 | * Set the active port count to zero. | ||
| 2267 | */ | ||
| 2268 | dgrp_chan_count(nd, 0); | ||
| 2269 | break; | ||
| 2270 | |||
| 2271 | default: | ||
| 2272 | break; | ||
| 2273 | } | ||
| 2274 | |||
| 2275 | n = b - local_buf; | ||
| 2276 | |||
| 2277 | if (n != 0) { | ||
| 2278 | nd->nd_send_count++; | ||
| 2279 | |||
| 2280 | nd->nd_tx_byte += n + nd->nd_link.lk_header_size; | ||
| 2281 | nd->nd_tx_charge += n + nd->nd_link.lk_header_size; | ||
| 2282 | } | ||
| 2283 | |||
| 2284 | rtn = copy_to_user((void __user *)buf, local_buf, n); | ||
| 2285 | if (rtn) { | ||
| 2286 | rtn = -EFAULT; | ||
| 2287 | goto done; | ||
| 2288 | } | ||
| 2289 | |||
| 2290 | *ppos += n; | ||
| 2291 | |||
| 2292 | rtn = n; | ||
| 2293 | |||
| 2294 | if (nd->nd_mon_buf) | ||
| 2295 | dgrp_monitor_data(nd, RPDUMP_CLIENT, local_buf, n); | ||
| 2296 | |||
| 2297 | /* | ||
| 2298 | * Release the NET lock. | ||
| 2299 | */ | ||
| 2300 | done: | ||
| 2301 | up(&nd->nd_net_semaphore); | ||
| 2302 | |||
| 2303 | return rtn; | ||
| 2304 | } | ||
| 2305 | |||
| 2306 | /** | ||
| 2307 | * dgrp_receive() -- decode data packets received from the remote PortServer. | ||
| 2308 | * @nd: pointer to a node structure | ||
| 2309 | */ | ||
| 2310 | static void dgrp_receive(struct nd_struct *nd) | ||
| 2311 | { | ||
| 2312 | struct ch_struct *ch; | ||
| 2313 | u8 *buf; | ||
| 2314 | u8 *b; | ||
| 2315 | u8 *dbuf; | ||
| 2316 | char *error; | ||
| 2317 | long port; | ||
| 2318 | long dlen; | ||
| 2319 | long plen; | ||
| 2320 | long remain; | ||
| 2321 | long n; | ||
| 2322 | long mlast; | ||
| 2323 | long elast; | ||
| 2324 | long mstat; | ||
| 2325 | long estat; | ||
| 2326 | |||
| 2327 | char ID[3]; | ||
| 2328 | |||
| 2329 | nd->nd_tx_time = jiffies; | ||
| 2330 | |||
| 2331 | ID_TO_CHAR(nd->nd_ID, ID); | ||
| 2332 | |||
| 2333 | b = buf = nd->nd_iobuf; | ||
| 2334 | remain = nd->nd_remain; | ||
| 2335 | |||
| 2336 | /* | ||
| 2337 | * Loop to process Realport protocol packets. | ||
| 2338 | */ | ||
| 2339 | |||
| 2340 | while (remain > 0) { | ||
| 2341 | int n0 = b[0] >> 4; | ||
| 2342 | int n1 = b[0] & 0x0f; | ||
| 2343 | |||
| 2344 | if (n0 <= 12) { | ||
| 2345 | port = (nd->nd_rx_module << 4) + n1; | ||
| 2346 | |||
| 2347 | if (port >= nd->nd_chan_count) { | ||
| 2348 | error = "Improper Port Number"; | ||
| 2349 | goto prot_error; | ||
| 2350 | } | ||
| 2351 | |||
| 2352 | ch = nd->nd_chan + port; | ||
| 2353 | } else { | ||
| 2354 | port = -1; | ||
| 2355 | ch = NULL; | ||
| 2356 | } | ||
| 2357 | |||
| 2358 | /* | ||
| 2359 | * Process by major packet type. | ||
| 2360 | */ | ||
| 2361 | |||
| 2362 | switch (n0) { | ||
| 2363 | |||
| 2364 | /* | ||
| 2365 | * Process 1-byte header data packet. | ||
| 2366 | */ | ||
| 2367 | |||
| 2368 | case 0: | ||
| 2369 | case 1: | ||
| 2370 | case 2: | ||
| 2371 | case 3: | ||
| 2372 | case 4: | ||
| 2373 | case 5: | ||
| 2374 | case 6: | ||
| 2375 | case 7: | ||
| 2376 | dlen = n0 + 1; | ||
| 2377 | plen = dlen + 1; | ||
| 2378 | |||
| 2379 | dbuf = b + 1; | ||
| 2380 | goto data; | ||
| 2381 | |||
| 2382 | /* | ||
| 2383 | * Process 2-byte header data packet. | ||
| 2384 | */ | ||
| 2385 | |||
| 2386 | case 8: | ||
| 2387 | if (remain < 3) | ||
| 2388 | goto done; | ||
| 2389 | |||
| 2390 | dlen = b[1]; | ||
| 2391 | plen = dlen + 2; | ||
| 2392 | |||
| 2393 | dbuf = b + 2; | ||
| 2394 | goto data; | ||
| 2395 | |||
| 2396 | /* | ||
| 2397 | * Process 3-byte header data packet. | ||
| 2398 | */ | ||
| 2399 | |||
| 2400 | case 9: | ||
| 2401 | if (remain < 4) | ||
| 2402 | goto done; | ||
| 2403 | |||
| 2404 | dlen = get_unaligned_be16(b + 1); | ||
| 2405 | plen = dlen + 3; | ||
| 2406 | |||
| 2407 | dbuf = b + 3; | ||
| 2408 | |||
| 2409 | /* | ||
| 2410 | * Common packet handling code. | ||
| 2411 | */ | ||
| 2412 | |||
| 2413 | data: | ||
| 2414 | nd->nd_tx_work = 1; | ||
| 2415 | |||
| 2416 | /* | ||
| 2417 | * Otherwise data should appear only when we are | ||
| 2418 | * in the CS_READY state. | ||
| 2419 | */ | ||
| 2420 | |||
| 2421 | if (ch->ch_state < CS_READY) { | ||
| 2422 | error = "Data received before RWIN established"; | ||
| 2423 | goto prot_error; | ||
| 2424 | } | ||
| 2425 | |||
| 2426 | /* | ||
| 2427 | * Assure that the data received is within the | ||
| 2428 | * allowable window. | ||
| 2429 | */ | ||
| 2430 | |||
| 2431 | n = (ch->ch_s_rwin - ch->ch_s_rin) & 0xffff; | ||
| 2432 | |||
| 2433 | if (dlen > n) { | ||
| 2434 | error = "Receive data overrun"; | ||
| 2435 | goto prot_error; | ||
| 2436 | } | ||
| 2437 | |||
| 2438 | /* | ||
| 2439 | * If we received 3 or less characters, | ||
| 2440 | * assume it is a human typing, and set RTIME | ||
| 2441 | * to 10 milliseconds. | ||
| 2442 | * | ||
| 2443 | * If we receive 10 or more characters, | ||
| 2444 | * assume its not a human typing, and set RTIME | ||
| 2445 | * to 100 milliseconds. | ||
| 2446 | */ | ||
| 2447 | |||
| 2448 | if (ch->ch_edelay != DGRP_RTIME) { | ||
| 2449 | if (ch->ch_rtime != ch->ch_edelay) { | ||
| 2450 | ch->ch_rtime = ch->ch_edelay; | ||
| 2451 | ch->ch_flag |= CH_PARAM; | ||
| 2452 | } | ||
| 2453 | } else if (dlen <= 3) { | ||
| 2454 | if (ch->ch_rtime != 10) { | ||
| 2455 | ch->ch_rtime = 10; | ||
| 2456 | ch->ch_flag |= CH_PARAM; | ||
| 2457 | } | ||
| 2458 | } else { | ||
| 2459 | if (ch->ch_rtime != DGRP_RTIME) { | ||
| 2460 | ch->ch_rtime = DGRP_RTIME; | ||
| 2461 | ch->ch_flag |= CH_PARAM; | ||
| 2462 | } | ||
| 2463 | } | ||
| 2464 | |||
| 2465 | /* | ||
| 2466 | * If a portion of the packet is outside the | ||
| 2467 | * buffer, shorten the effective length of the | ||
| 2468 | * data packet to be the amount of data received. | ||
| 2469 | */ | ||
| 2470 | |||
| 2471 | if (remain < plen) | ||
| 2472 | dlen -= plen - remain; | ||
| 2473 | |||
| 2474 | /* | ||
| 2475 | * Detect if receive flush is now complete. | ||
| 2476 | */ | ||
| 2477 | |||
| 2478 | if ((ch->ch_flag & CH_RX_FLUSH) != 0 && | ||
| 2479 | ((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >= | ||
| 2480 | ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) { | ||
| 2481 | ch->ch_flag &= ~CH_RX_FLUSH; | ||
| 2482 | } | ||
| 2483 | |||
| 2484 | /* | ||
| 2485 | * If we are ready to receive, move the data into | ||
| 2486 | * the receive buffer. | ||
| 2487 | */ | ||
| 2488 | |||
| 2489 | ch->ch_s_rin = (ch->ch_s_rin + dlen) & 0xffff; | ||
| 2490 | |||
| 2491 | if (ch->ch_state == CS_READY && | ||
| 2492 | (ch->ch_tun.un_open_count != 0) && | ||
| 2493 | (ch->ch_tun.un_flag & UN_CLOSING) == 0 && | ||
| 2494 | (ch->ch_cflag & CF_CREAD) != 0 && | ||
| 2495 | (ch->ch_flag & (CH_BAUD0 | CH_RX_FLUSH)) == 0 && | ||
| 2496 | (ch->ch_send & RR_RX_FLUSH) == 0) { | ||
| 2497 | |||
| 2498 | if (ch->ch_rin + dlen >= RBUF_MAX) { | ||
| 2499 | n = RBUF_MAX - ch->ch_rin; | ||
| 2500 | |||
| 2501 | memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, n); | ||
| 2502 | |||
| 2503 | ch->ch_rin = 0; | ||
| 2504 | dbuf += n; | ||
| 2505 | dlen -= n; | ||
| 2506 | } | ||
| 2507 | |||
| 2508 | memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, dlen); | ||
| 2509 | |||
| 2510 | ch->ch_rin += dlen; | ||
| 2511 | |||
| 2512 | |||
| 2513 | /* | ||
| 2514 | * If we are not in fastcook mode, or | ||
| 2515 | * if there is a fastcook thread | ||
| 2516 | * waiting for data, send the data to | ||
| 2517 | * the line discipline. | ||
| 2518 | */ | ||
| 2519 | |||
| 2520 | if ((ch->ch_flag & CH_FAST_READ) == 0 || | ||
| 2521 | ch->ch_inwait != 0) { | ||
| 2522 | dgrp_input(ch); | ||
| 2523 | } | ||
| 2524 | |||
| 2525 | /* | ||
| 2526 | * If there is a read thread waiting | ||
| 2527 | * in select, and we are in fastcook | ||
| 2528 | * mode, wake him up. | ||
| 2529 | */ | ||
| 2530 | |||
| 2531 | if (waitqueue_active(&ch->ch_tun.un_tty->read_wait) && | ||
| 2532 | (ch->ch_flag & CH_FAST_READ) != 0) | ||
| 2533 | wake_up_interruptible(&ch->ch_tun.un_tty->read_wait); | ||
| 2534 | |||
| 2535 | /* | ||
| 2536 | * Wake any thread waiting in the | ||
| 2537 | * fastcook loop. | ||
| 2538 | */ | ||
| 2539 | |||
| 2540 | if ((ch->ch_flag & CH_INPUT) != 0) { | ||
| 2541 | ch->ch_flag &= ~CH_INPUT; | ||
| 2542 | |||
| 2543 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 2544 | } | ||
| 2545 | } | ||
| 2546 | |||
| 2547 | /* | ||
| 2548 | * Fabricate and insert a data packet header to | ||
| 2549 | * preceed the remaining data when it comes in. | ||
| 2550 | */ | ||
| 2551 | |||
| 2552 | if (remain < plen) { | ||
| 2553 | dlen = plen - remain; | ||
| 2554 | b = buf; | ||
| 2555 | |||
| 2556 | b[0] = 0x90 + n1; | ||
| 2557 | put_unaligned_be16(dlen, b + 1); | ||
| 2558 | |||
| 2559 | remain = 3; | ||
| 2560 | goto done; | ||
| 2561 | } | ||
| 2562 | break; | ||
| 2563 | |||
| 2564 | /* | ||
| 2565 | * Handle Window Sequence packets. | ||
| 2566 | */ | ||
| 2567 | |||
| 2568 | case 10: | ||
| 2569 | plen = 3; | ||
| 2570 | if (remain < plen) | ||
| 2571 | goto done; | ||
| 2572 | |||
| 2573 | nd->nd_tx_work = 1; | ||
| 2574 | |||
| 2575 | { | ||
| 2576 | ushort tpos = get_unaligned_be16(b + 1); | ||
| 2577 | |||
| 2578 | ushort ack = (tpos - ch->ch_s_tpos) & 0xffff; | ||
| 2579 | ushort unack = (ch->ch_s_tin - ch->ch_s_tpos) & 0xffff; | ||
| 2580 | ushort notify = (ch->ch_s_treq - ch->ch_s_tpos) & 0xffff; | ||
| 2581 | |||
| 2582 | if (ch->ch_state < CS_READY || ack > unack) { | ||
| 2583 | error = "Improper Window Sequence"; | ||
| 2584 | goto prot_error; | ||
| 2585 | } | ||
| 2586 | |||
| 2587 | ch->ch_s_tpos = tpos; | ||
| 2588 | |||
| 2589 | if (notify <= ack) | ||
| 2590 | ch->ch_s_treq = tpos; | ||
| 2591 | } | ||
| 2592 | break; | ||
| 2593 | |||
| 2594 | /* | ||
| 2595 | * Handle Command response packets. | ||
| 2596 | */ | ||
| 2597 | |||
| 2598 | case 11: | ||
| 2599 | |||
| 2600 | /* | ||
| 2601 | * RealPort engine fix - 03/11/2004 | ||
| 2602 | * | ||
| 2603 | * This check did not used to be here. | ||
| 2604 | * | ||
| 2605 | * We were using b[1] without verifying that the data | ||
| 2606 | * is actually there and valid. On a split packet, it | ||
| 2607 | * might not be yet. | ||
| 2608 | * | ||
| 2609 | * NOTE: I have never actually seen the failure happen | ||
| 2610 | * under Linux, but since I have seen it occur | ||
| 2611 | * under both Solaris and HP-UX, the assumption | ||
| 2612 | * is that it *could* happen here as well... | ||
| 2613 | */ | ||
| 2614 | if (remain < 2) | ||
| 2615 | goto done; | ||
| 2616 | |||
| 2617 | |||
| 2618 | switch (b[1]) { | ||
| 2619 | |||
| 2620 | /* | ||
| 2621 | * Handle Open Response. | ||
| 2622 | */ | ||
| 2623 | |||
| 2624 | case 11: | ||
| 2625 | plen = 6; | ||
| 2626 | if (remain < plen) | ||
| 2627 | goto done; | ||
| 2628 | |||
| 2629 | nd->nd_tx_work = 1; | ||
| 2630 | |||
| 2631 | { | ||
| 2632 | int req = b[2]; | ||
| 2633 | int resp = b[3]; | ||
| 2634 | port = get_unaligned_be16(b + 4); | ||
| 2635 | |||
| 2636 | if (port >= nd->nd_chan_count) { | ||
| 2637 | error = "Open channel number out of range"; | ||
| 2638 | goto prot_error; | ||
| 2639 | } | ||
| 2640 | |||
| 2641 | ch = nd->nd_chan + port; | ||
| 2642 | |||
| 2643 | /* | ||
| 2644 | * How we handle an open response depends primarily | ||
| 2645 | * on our current channel state. | ||
| 2646 | */ | ||
| 2647 | |||
| 2648 | switch (ch->ch_state) { | ||
| 2649 | case CS_IDLE: | ||
| 2650 | |||
| 2651 | /* | ||
| 2652 | * Handle a delayed open. | ||
| 2653 | */ | ||
| 2654 | |||
| 2655 | if (ch->ch_otype_waiting != 0 && | ||
| 2656 | req == ch->ch_otype_waiting && | ||
| 2657 | resp == 0) { | ||
| 2658 | ch->ch_otype = req; | ||
| 2659 | ch->ch_otype_waiting = 0; | ||
| 2660 | ch->ch_state = CS_SEND_QUERY; | ||
| 2661 | break; | ||
| 2662 | } | ||
| 2663 | goto open_error; | ||
| 2664 | |||
| 2665 | case CS_WAIT_OPEN: | ||
| 2666 | |||
| 2667 | /* | ||
| 2668 | * Handle the open response. | ||
| 2669 | */ | ||
| 2670 | |||
| 2671 | if (req == ch->ch_otype) { | ||
| 2672 | switch (resp) { | ||
| 2673 | |||
| 2674 | /* | ||
| 2675 | * On successful response, open the | ||
| 2676 | * port and proceed normally. | ||
| 2677 | */ | ||
| 2678 | |||
| 2679 | case 0: | ||
| 2680 | ch->ch_state = CS_SEND_QUERY; | ||
| 2681 | break; | ||
| 2682 | |||
| 2683 | /* | ||
| 2684 | * On a busy response to a persistent open, | ||
| 2685 | * remember that the open is pending. | ||
| 2686 | */ | ||
| 2687 | |||
| 2688 | case 1: | ||
| 2689 | case 2: | ||
| 2690 | if (req != OTYPE_IMMEDIATE) { | ||
| 2691 | ch->ch_otype_waiting = req; | ||
| 2692 | ch->ch_state = CS_IDLE; | ||
| 2693 | break; | ||
| 2694 | } | ||
| 2695 | |||
| 2696 | /* | ||
| 2697 | * Otherwise the server open failed. If | ||
| 2698 | * the Unix port is open, hang it up. | ||
| 2699 | */ | ||
| 2700 | |||
| 2701 | default: | ||
| 2702 | if (ch->ch_open_count != 0) { | ||
| 2703 | ch->ch_flag |= CH_HANGUP; | ||
| 2704 | dgrp_carrier(ch); | ||
| 2705 | ch->ch_state = CS_IDLE; | ||
| 2706 | break; | ||
| 2707 | } | ||
| 2708 | |||
| 2709 | ch->ch_open_error = resp; | ||
| 2710 | ch->ch_state = CS_IDLE; | ||
| 2711 | |||
| 2712 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 2713 | } | ||
| 2714 | break; | ||
| 2715 | } | ||
| 2716 | |||
| 2717 | /* | ||
| 2718 | * Handle delayed response arrival preceeding | ||
| 2719 | * the open response we are waiting for. | ||
| 2720 | */ | ||
| 2721 | |||
| 2722 | if (ch->ch_otype_waiting != 0 && | ||
| 2723 | req == ch->ch_otype_waiting && | ||
| 2724 | resp == 0) { | ||
| 2725 | ch->ch_otype = ch->ch_otype_waiting; | ||
| 2726 | ch->ch_otype_waiting = 0; | ||
| 2727 | ch->ch_state = CS_WAIT_FAIL; | ||
| 2728 | break; | ||
| 2729 | } | ||
| 2730 | goto open_error; | ||
| 2731 | |||
| 2732 | |||
| 2733 | case CS_WAIT_FAIL: | ||
| 2734 | |||
| 2735 | /* | ||
| 2736 | * Handle response to immediate open arriving | ||
| 2737 | * after a delayed open success. | ||
| 2738 | */ | ||
| 2739 | |||
| 2740 | if (req == OTYPE_IMMEDIATE) { | ||
| 2741 | ch->ch_state = CS_SEND_QUERY; | ||
| 2742 | break; | ||
| 2743 | } | ||
| 2744 | goto open_error; | ||
| 2745 | |||
| 2746 | |||
| 2747 | case CS_WAIT_CANCEL: | ||
| 2748 | /* | ||
| 2749 | * Handle delayed open response arriving before | ||
| 2750 | * the cancel response. | ||
| 2751 | */ | ||
| 2752 | |||
| 2753 | if (req == ch->ch_otype_waiting && | ||
| 2754 | resp == 0) { | ||
| 2755 | ch->ch_otype_waiting = 0; | ||
| 2756 | break; | ||
| 2757 | } | ||
| 2758 | |||
| 2759 | /* | ||
| 2760 | * Handle cancel response. | ||
| 2761 | */ | ||
| 2762 | |||
| 2763 | if (req == 4 && resp == 0) { | ||
| 2764 | ch->ch_otype_waiting = 0; | ||
| 2765 | ch->ch_state = CS_IDLE; | ||
| 2766 | break; | ||
| 2767 | } | ||
| 2768 | goto open_error; | ||
| 2769 | |||
| 2770 | |||
| 2771 | case CS_WAIT_CLOSE: | ||
| 2772 | /* | ||
| 2773 | * Handle a successful response to a port | ||
| 2774 | * close. | ||
| 2775 | */ | ||
| 2776 | |||
| 2777 | if (req >= 3) { | ||
| 2778 | ch->ch_state = CS_IDLE; | ||
| 2779 | break; | ||
| 2780 | } | ||
| 2781 | goto open_error; | ||
| 2782 | |||
| 2783 | open_error: | ||
| 2784 | default: | ||
| 2785 | { | ||
| 2786 | error = "Improper Open Response"; | ||
| 2787 | goto prot_error; | ||
| 2788 | } | ||
| 2789 | } | ||
| 2790 | } | ||
| 2791 | break; | ||
| 2792 | |||
| 2793 | /* | ||
| 2794 | * Handle Synchronize Response. | ||
| 2795 | */ | ||
| 2796 | |||
| 2797 | case 13: | ||
| 2798 | plen = 3; | ||
| 2799 | if (remain < plen) | ||
| 2800 | goto done; | ||
| 2801 | { | ||
| 2802 | int seq = b[2]; | ||
| 2803 | int s; | ||
| 2804 | |||
| 2805 | /* | ||
| 2806 | * If channel was waiting for this sync response, | ||
| 2807 | * unset the flag, and wake up anyone waiting | ||
| 2808 | * on the event. | ||
| 2809 | */ | ||
| 2810 | if (ch->ch_flag & CH_WAITING_SYNC) { | ||
| 2811 | ch->ch_flag &= ~(CH_WAITING_SYNC); | ||
| 2812 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 2813 | } | ||
| 2814 | |||
| 2815 | if (((seq - nd->nd_seq_out) & SEQ_MASK) >= | ||
| 2816 | ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) { | ||
| 2817 | break; | ||
| 2818 | } | ||
| 2819 | |||
| 2820 | for (s = nd->nd_seq_out;; s = (s + 1) & SEQ_MASK) { | ||
| 2821 | if (nd->nd_seq_wait[s] != 0) { | ||
| 2822 | nd->nd_seq_wait[s] = 0; | ||
| 2823 | |||
| 2824 | wake_up_interruptible(&nd->nd_seq_wque[s]); | ||
| 2825 | } | ||
| 2826 | |||
| 2827 | nd->nd_unack -= nd->nd_seq_size[s]; | ||
| 2828 | |||
| 2829 | if (s == seq) | ||
| 2830 | break; | ||
| 2831 | } | ||
| 2832 | |||
| 2833 | nd->nd_seq_out = (seq + 1) & SEQ_MASK; | ||
| 2834 | } | ||
| 2835 | break; | ||
| 2836 | |||
| 2837 | /* | ||
| 2838 | * Handle Sequence Response. | ||
| 2839 | */ | ||
| 2840 | |||
| 2841 | case 15: | ||
| 2842 | plen = 6; | ||
| 2843 | if (remain < plen) | ||
| 2844 | goto done; | ||
| 2845 | |||
| 2846 | { | ||
| 2847 | /* Record that we have received the Sequence | ||
| 2848 | * Response, but we aren't interested in the | ||
| 2849 | * sequence numbers. We were using RIN like it | ||
| 2850 | * was ROUT and that was causing problems, | ||
| 2851 | * fixed 7-13-2001 David Fries. See comment in | ||
| 2852 | * drp.h for ch_s_rin variable. | ||
| 2853 | int rin = get_unaligned_be16(b + 2); | ||
| 2854 | int tpos = get_unaligned_be16(b + 4); | ||
| 2855 | */ | ||
| 2856 | |||
| 2857 | ch->ch_send &= ~RR_SEQUENCE; | ||
| 2858 | ch->ch_expect &= ~RR_SEQUENCE; | ||
| 2859 | } | ||
| 2860 | goto check_query; | ||
| 2861 | |||
| 2862 | /* | ||
| 2863 | * Handle Status Response. | ||
| 2864 | */ | ||
| 2865 | |||
| 2866 | case 17: | ||
| 2867 | plen = 5; | ||
| 2868 | if (remain < plen) | ||
| 2869 | goto done; | ||
| 2870 | |||
| 2871 | { | ||
| 2872 | ch->ch_s_elast = get_unaligned_be16(b + 2); | ||
| 2873 | ch->ch_s_mlast = b[4]; | ||
| 2874 | |||
| 2875 | ch->ch_expect &= ~RR_STATUS; | ||
| 2876 | ch->ch_send &= ~RR_STATUS; | ||
| 2877 | |||
| 2878 | /* | ||
| 2879 | * CH_PHYS_CD is cleared because something _could_ be | ||
| 2880 | * waiting for the initial sense of carrier... and if | ||
| 2881 | * carrier is high immediately, we want to be sure to | ||
| 2882 | * wake them as soon as possible. | ||
| 2883 | */ | ||
| 2884 | ch->ch_flag &= ~CH_PHYS_CD; | ||
| 2885 | |||
| 2886 | dgrp_carrier(ch); | ||
| 2887 | } | ||
| 2888 | goto check_query; | ||
| 2889 | |||
| 2890 | /* | ||
| 2891 | * Handle Line Error Response. | ||
| 2892 | */ | ||
| 2893 | |||
| 2894 | case 19: | ||
| 2895 | plen = 14; | ||
| 2896 | if (remain < plen) | ||
| 2897 | goto done; | ||
| 2898 | |||
| 2899 | break; | ||
| 2900 | |||
| 2901 | /* | ||
| 2902 | * Handle Buffer Response. | ||
| 2903 | */ | ||
| 2904 | |||
| 2905 | case 21: | ||
| 2906 | plen = 6; | ||
| 2907 | if (remain < plen) | ||
| 2908 | goto done; | ||
| 2909 | |||
| 2910 | { | ||
| 2911 | ch->ch_s_rsize = get_unaligned_be16(b + 2); | ||
| 2912 | ch->ch_s_tsize = get_unaligned_be16(b + 4); | ||
| 2913 | |||
| 2914 | ch->ch_send &= ~RR_BUFFER; | ||
| 2915 | ch->ch_expect &= ~RR_BUFFER; | ||
| 2916 | } | ||
| 2917 | goto check_query; | ||
| 2918 | |||
| 2919 | /* | ||
| 2920 | * Handle Port Capability Response. | ||
| 2921 | */ | ||
| 2922 | |||
| 2923 | case 23: | ||
| 2924 | plen = 32; | ||
| 2925 | if (remain < plen) | ||
| 2926 | goto done; | ||
| 2927 | |||
| 2928 | { | ||
| 2929 | ch->ch_send &= ~RR_CAPABILITY; | ||
| 2930 | ch->ch_expect &= ~RR_CAPABILITY; | ||
| 2931 | } | ||
| 2932 | |||
| 2933 | /* | ||
| 2934 | * When all queries are complete, set those parameters | ||
| 2935 | * derived from the query results, then transition | ||
| 2936 | * to the READY state. | ||
| 2937 | */ | ||
| 2938 | |||
| 2939 | check_query: | ||
| 2940 | if (ch->ch_state == CS_WAIT_QUERY && | ||
| 2941 | (ch->ch_expect & (RR_SEQUENCE | | ||
| 2942 | RR_STATUS | | ||
| 2943 | RR_BUFFER | | ||
| 2944 | RR_CAPABILITY)) == 0) { | ||
| 2945 | ch->ch_tmax = ch->ch_s_tsize / 4; | ||
| 2946 | |||
| 2947 | if (ch->ch_edelay == DGRP_TTIME) | ||
| 2948 | ch->ch_ttime = DGRP_TTIME; | ||
| 2949 | else | ||
| 2950 | ch->ch_ttime = ch->ch_edelay; | ||
| 2951 | |||
| 2952 | ch->ch_rmax = ch->ch_s_rsize / 4; | ||
| 2953 | |||
| 2954 | if (ch->ch_edelay == DGRP_RTIME) | ||
| 2955 | ch->ch_rtime = DGRP_RTIME; | ||
| 2956 | else | ||
| 2957 | ch->ch_rtime = ch->ch_edelay; | ||
| 2958 | |||
| 2959 | ch->ch_rlow = 2 * ch->ch_s_rsize / 8; | ||
| 2960 | ch->ch_rhigh = 6 * ch->ch_s_rsize / 8; | ||
| 2961 | |||
| 2962 | ch->ch_state = CS_READY; | ||
| 2963 | |||
| 2964 | nd->nd_tx_work = 1; | ||
| 2965 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 2966 | |||
| 2967 | } | ||
| 2968 | break; | ||
| 2969 | |||
| 2970 | default: | ||
| 2971 | goto decode_error; | ||
| 2972 | } | ||
| 2973 | break; | ||
| 2974 | |||
| 2975 | /* | ||
| 2976 | * Handle Events. | ||
| 2977 | */ | ||
| 2978 | |||
| 2979 | case 12: | ||
| 2980 | plen = 4; | ||
| 2981 | if (remain < plen) | ||
| 2982 | goto done; | ||
| 2983 | |||
| 2984 | mlast = ch->ch_s_mlast; | ||
| 2985 | elast = ch->ch_s_elast; | ||
| 2986 | |||
| 2987 | mstat = ch->ch_s_mlast = b[1]; | ||
| 2988 | estat = ch->ch_s_elast = get_unaligned_be16(b + 2); | ||
| 2989 | |||
| 2990 | /* | ||
| 2991 | * Handle modem changes. | ||
| 2992 | */ | ||
| 2993 | |||
| 2994 | if (((mstat ^ mlast) & DM_CD) != 0) | ||
| 2995 | dgrp_carrier(ch); | ||
| 2996 | |||
| 2997 | |||
| 2998 | /* | ||
| 2999 | * Handle received break. | ||
| 3000 | */ | ||
| 3001 | |||
| 3002 | if ((estat & ~elast & EV_RXB) != 0 && | ||
| 3003 | (ch->ch_tun.un_open_count != 0) && | ||
| 3004 | I_BRKINT(ch->ch_tun.un_tty) && | ||
| 3005 | !(I_IGNBRK(ch->ch_tun.un_tty))) { | ||
| 3006 | |||
| 3007 | tty_buffer_request_room(ch->ch_tun.un_tty, 1); | ||
| 3008 | tty_insert_flip_char(ch->ch_tun.un_tty, 0, TTY_BREAK); | ||
| 3009 | tty_flip_buffer_push(ch->ch_tun.un_tty); | ||
| 3010 | |||
| 3011 | } | ||
| 3012 | |||
| 3013 | /* | ||
| 3014 | * On transmit break complete, if more break traffic | ||
| 3015 | * is waiting then send it. Otherwise wake any threads | ||
| 3016 | * waiting for transmitter empty. | ||
| 3017 | */ | ||
| 3018 | |||
| 3019 | if ((~estat & elast & EV_TXB) != 0 && | ||
| 3020 | (ch->ch_expect & RR_TX_BREAK) != 0) { | ||
| 3021 | |||
| 3022 | nd->nd_tx_work = 1; | ||
| 3023 | |||
| 3024 | ch->ch_expect &= ~RR_TX_BREAK; | ||
| 3025 | |||
| 3026 | if (ch->ch_break_time != 0) { | ||
| 3027 | ch->ch_send |= RR_TX_BREAK; | ||
| 3028 | } else { | ||
| 3029 | ch->ch_send &= ~RR_TX_BREAK; | ||
| 3030 | ch->ch_flag &= ~CH_TX_BREAK; | ||
| 3031 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 3032 | } | ||
| 3033 | } | ||
| 3034 | break; | ||
| 3035 | |||
| 3036 | case 13: | ||
| 3037 | case 14: | ||
| 3038 | error = "Unrecognized command"; | ||
| 3039 | goto prot_error; | ||
| 3040 | |||
| 3041 | /* | ||
| 3042 | * Decode Special Codes. | ||
| 3043 | */ | ||
| 3044 | |||
| 3045 | case 15: | ||
| 3046 | switch (n1) { | ||
| 3047 | /* | ||
| 3048 | * One byte module select. | ||
| 3049 | */ | ||
| 3050 | |||
| 3051 | case 0: | ||
| 3052 | case 1: | ||
| 3053 | case 2: | ||
| 3054 | case 3: | ||
| 3055 | case 4: | ||
| 3056 | case 5: | ||
| 3057 | case 6: | ||
| 3058 | case 7: | ||
| 3059 | plen = 1; | ||
| 3060 | nd->nd_rx_module = n1; | ||
| 3061 | break; | ||
| 3062 | |||
| 3063 | /* | ||
| 3064 | * Two byte module select. | ||
| 3065 | */ | ||
| 3066 | |||
| 3067 | case 8: | ||
| 3068 | plen = 2; | ||
| 3069 | if (remain < plen) | ||
| 3070 | goto done; | ||
| 3071 | |||
| 3072 | nd->nd_rx_module = b[1]; | ||
| 3073 | break; | ||
| 3074 | |||
| 3075 | /* | ||
| 3076 | * ID Request packet. | ||
| 3077 | */ | ||
| 3078 | |||
| 3079 | case 11: | ||
| 3080 | if (remain < 4) | ||
| 3081 | goto done; | ||
| 3082 | |||
| 3083 | plen = get_unaligned_be16(b + 2); | ||
| 3084 | |||
| 3085 | if (plen < 12 || plen > 1000) { | ||
| 3086 | error = "Response Packet length error"; | ||
| 3087 | goto prot_error; | ||
| 3088 | } | ||
| 3089 | |||
| 3090 | nd->nd_tx_work = 1; | ||
| 3091 | |||
| 3092 | switch (b[1]) { | ||
| 3093 | /* | ||
| 3094 | * Echo packet. | ||
| 3095 | */ | ||
| 3096 | |||
| 3097 | case 0: | ||
| 3098 | nd->nd_send |= NR_ECHO; | ||
| 3099 | break; | ||
| 3100 | |||
| 3101 | /* | ||
| 3102 | * ID Response packet. | ||
| 3103 | */ | ||
| 3104 | |||
| 3105 | case 1: | ||
| 3106 | nd->nd_send |= NR_IDENT; | ||
| 3107 | break; | ||
| 3108 | |||
| 3109 | /* | ||
| 3110 | * ID Response packet. | ||
| 3111 | */ | ||
| 3112 | |||
| 3113 | case 32: | ||
| 3114 | nd->nd_send |= NR_PASSWORD; | ||
| 3115 | break; | ||
| 3116 | |||
| 3117 | } | ||
| 3118 | break; | ||
| 3119 | |||
| 3120 | /* | ||
| 3121 | * Various node-level response packets. | ||
| 3122 | */ | ||
| 3123 | |||
| 3124 | case 12: | ||
| 3125 | if (remain < 4) | ||
| 3126 | goto done; | ||
| 3127 | |||
| 3128 | plen = get_unaligned_be16(b + 2); | ||
| 3129 | |||
| 3130 | if (plen < 4 || plen > 1000) { | ||
| 3131 | error = "Response Packet length error"; | ||
| 3132 | goto prot_error; | ||
| 3133 | } | ||
| 3134 | |||
| 3135 | nd->nd_tx_work = 1; | ||
| 3136 | |||
| 3137 | switch (b[1]) { | ||
| 3138 | /* | ||
| 3139 | * Echo packet. | ||
| 3140 | */ | ||
| 3141 | |||
| 3142 | case 0: | ||
| 3143 | nd->nd_expect &= ~NR_ECHO; | ||
| 3144 | break; | ||
| 3145 | |||
| 3146 | /* | ||
| 3147 | * Product Response Packet. | ||
| 3148 | */ | ||
| 3149 | |||
| 3150 | case 1: | ||
| 3151 | { | ||
| 3152 | int desclen; | ||
| 3153 | |||
| 3154 | nd->nd_hw_ver = (b[8] << 8) | b[9]; | ||
| 3155 | nd->nd_sw_ver = (b[10] << 8) | b[11]; | ||
| 3156 | nd->nd_hw_id = b[6]; | ||
| 3157 | desclen = ((plen - 12) > MAX_DESC_LEN) ? MAX_DESC_LEN : | ||
| 3158 | plen - 12; | ||
| 3159 | |||
| 3160 | if (desclen <= 0) { | ||
| 3161 | error = "Response Packet desclen error"; | ||
| 3162 | goto prot_error; | ||
| 3163 | } | ||
| 3164 | |||
| 3165 | strncpy(nd->nd_ps_desc, b + 12, desclen); | ||
| 3166 | nd->nd_ps_desc[desclen] = 0; | ||
| 3167 | } | ||
| 3168 | |||
| 3169 | nd->nd_expect &= ~NR_IDENT; | ||
| 3170 | break; | ||
| 3171 | |||
| 3172 | /* | ||
| 3173 | * Capability Response Packet. | ||
| 3174 | */ | ||
| 3175 | |||
| 3176 | case 2: | ||
| 3177 | { | ||
| 3178 | int nn = get_unaligned_be16(b + 4); | ||
| 3179 | |||
| 3180 | if (nn > CHAN_MAX) | ||
| 3181 | nn = CHAN_MAX; | ||
| 3182 | |||
| 3183 | dgrp_chan_count(nd, nn); | ||
| 3184 | } | ||
| 3185 | |||
| 3186 | nd->nd_expect &= ~NR_CAPABILITY; | ||
| 3187 | break; | ||
| 3188 | |||
| 3189 | /* | ||
| 3190 | * VPD Response Packet. | ||
| 3191 | */ | ||
| 3192 | |||
| 3193 | case 15: | ||
| 3194 | /* | ||
| 3195 | * NOTE: case 15 is here ONLY because the EtherLite | ||
| 3196 | * is broken, and sends a response to 24 back as 15. | ||
| 3197 | * To resolve this, the EtherLite firmware is now | ||
| 3198 | * fixed to send back 24 correctly, but, for backwards | ||
| 3199 | * compatibility, we now have reserved 15 for the | ||
| 3200 | * bad EtherLite response to 24 as well. | ||
| 3201 | */ | ||
| 3202 | |||
| 3203 | /* Fallthru! */ | ||
| 3204 | |||
| 3205 | case 24: | ||
| 3206 | |||
| 3207 | /* | ||
| 3208 | * If the product doesn't support VPD, | ||
| 3209 | * it will send back a null IDRESP, | ||
| 3210 | * which is a length of 4 bytes. | ||
| 3211 | */ | ||
| 3212 | if (plen > 4) { | ||
| 3213 | memcpy(nd->nd_vpd, b + 4, min(plen - 4, (long) VPDSIZE)); | ||
| 3214 | nd->nd_vpd_len = min(plen - 4, (long) VPDSIZE); | ||
| 3215 | } | ||
| 3216 | |||
| 3217 | nd->nd_expect &= ~NR_VPD; | ||
| 3218 | break; | ||
| 3219 | |||
| 3220 | default: | ||
| 3221 | goto decode_error; | ||
| 3222 | } | ||
| 3223 | |||
| 3224 | if (nd->nd_expect == 0 && | ||
| 3225 | nd->nd_state == NS_WAIT_QUERY) { | ||
| 3226 | nd->nd_state = NS_READY; | ||
| 3227 | } | ||
| 3228 | break; | ||
| 3229 | |||
| 3230 | /* | ||
| 3231 | * Debug packet. | ||
| 3232 | */ | ||
| 3233 | |||
| 3234 | case 14: | ||
| 3235 | if (remain < 4) | ||
| 3236 | goto done; | ||
| 3237 | |||
| 3238 | plen = get_unaligned_be16(b + 2) + 4; | ||
| 3239 | |||
| 3240 | if (plen > 1000) { | ||
| 3241 | error = "Debug Packet too large"; | ||
| 3242 | goto prot_error; | ||
| 3243 | } | ||
| 3244 | |||
| 3245 | if (remain < plen) | ||
| 3246 | goto done; | ||
| 3247 | break; | ||
| 3248 | |||
| 3249 | /* | ||
| 3250 | * Handle reset packet. | ||
| 3251 | */ | ||
| 3252 | |||
| 3253 | case 15: | ||
| 3254 | if (remain < 2) | ||
| 3255 | goto done; | ||
| 3256 | |||
| 3257 | plen = 2 + b[1]; | ||
| 3258 | |||
| 3259 | if (remain < plen) | ||
| 3260 | goto done; | ||
| 3261 | |||
| 3262 | nd->nd_tx_work = 1; | ||
| 3263 | |||
| 3264 | n = b[plen]; | ||
| 3265 | b[plen] = 0; | ||
| 3266 | |||
| 3267 | b[plen] = n; | ||
| 3268 | |||
| 3269 | error = "Client Reset Acknowledge"; | ||
| 3270 | goto prot_error; | ||
| 3271 | |||
| 3272 | default: | ||
| 3273 | goto decode_error; | ||
| 3274 | } | ||
| 3275 | break; | ||
| 3276 | |||
| 3277 | default: | ||
| 3278 | goto decode_error; | ||
| 3279 | } | ||
| 3280 | |||
| 3281 | b += plen; | ||
| 3282 | remain -= plen; | ||
| 3283 | } | ||
| 3284 | |||
| 3285 | /* | ||
| 3286 | * When the buffer is exhausted, copy any data left at the | ||
| 3287 | * top of the buffer back down to the bottom for the next | ||
| 3288 | * read request. | ||
| 3289 | */ | ||
| 3290 | |||
| 3291 | done: | ||
| 3292 | if (remain > 0 && b != buf) | ||
| 3293 | memcpy(buf, b, remain); | ||
| 3294 | |||
| 3295 | nd->nd_remain = remain; | ||
| 3296 | return; | ||
| 3297 | |||
| 3298 | /* | ||
| 3299 | * Handle a decode error. | ||
| 3300 | */ | ||
| 3301 | |||
| 3302 | decode_error: | ||
| 3303 | error = "Protocol decode error"; | ||
| 3304 | |||
| 3305 | /* | ||
| 3306 | * Handle a general protocol error. | ||
| 3307 | */ | ||
| 3308 | |||
| 3309 | prot_error: | ||
| 3310 | nd->nd_remain = 0; | ||
| 3311 | nd->nd_state = NS_SEND_ERROR; | ||
| 3312 | nd->nd_error = error; | ||
| 3313 | } | ||
| 3314 | |||
| 3315 | /* | ||
| 3316 | * dgrp_net_write() -- write data to the network device. | ||
| 3317 | * | ||
| 3318 | * A zero byte write indicates that the connection to the RealPort | ||
| 3319 | * device has been broken. | ||
| 3320 | * | ||
| 3321 | * A non-zero write indicates data from the RealPort device. | ||
| 3322 | */ | ||
| 3323 | static ssize_t dgrp_net_write(struct file *file, const char __user *buf, | ||
| 3324 | size_t count, loff_t *ppos) | ||
| 3325 | { | ||
| 3326 | struct nd_struct *nd; | ||
| 3327 | ssize_t rtn = 0; | ||
| 3328 | long n; | ||
| 3329 | long total = 0; | ||
| 3330 | |||
| 3331 | /* | ||
| 3332 | * Get the node pointer, and quit if it doesn't exist. | ||
| 3333 | */ | ||
| 3334 | nd = (struct nd_struct *)(file->private_data); | ||
| 3335 | if (!nd) | ||
| 3336 | return -ENXIO; | ||
| 3337 | |||
| 3338 | /* | ||
| 3339 | * Grab the NET lock. | ||
| 3340 | */ | ||
| 3341 | down(&nd->nd_net_semaphore); | ||
| 3342 | |||
| 3343 | nd->nd_write_count++; | ||
| 3344 | |||
| 3345 | /* | ||
| 3346 | * Handle disconnect. | ||
| 3347 | */ | ||
| 3348 | |||
| 3349 | if (count == 0) { | ||
| 3350 | dgrp_net_idle(nd); | ||
| 3351 | /* | ||
| 3352 | * Set the active port count to zero. | ||
| 3353 | */ | ||
| 3354 | dgrp_chan_count(nd, 0); | ||
| 3355 | goto unlock; | ||
| 3356 | } | ||
| 3357 | |||
| 3358 | /* | ||
| 3359 | * Loop to process entire receive packet. | ||
| 3360 | */ | ||
| 3361 | |||
| 3362 | while (count > 0) { | ||
| 3363 | n = UIO_MAX - nd->nd_remain; | ||
| 3364 | |||
| 3365 | if (n > count) | ||
| 3366 | n = count; | ||
| 3367 | |||
| 3368 | nd->nd_rx_byte += n + nd->nd_link.lk_header_size; | ||
| 3369 | |||
| 3370 | rtn = copy_from_user(nd->nd_iobuf + nd->nd_remain, | ||
| 3371 | (void __user *) buf + total, n); | ||
| 3372 | if (rtn) { | ||
| 3373 | rtn = -EFAULT; | ||
| 3374 | goto unlock; | ||
| 3375 | } | ||
| 3376 | |||
| 3377 | *ppos += n; | ||
| 3378 | |||
| 3379 | total += n; | ||
| 3380 | |||
| 3381 | count -= n; | ||
| 3382 | |||
| 3383 | if (nd->nd_mon_buf) | ||
| 3384 | dgrp_monitor_data(nd, RPDUMP_SERVER, | ||
| 3385 | nd->nd_iobuf + nd->nd_remain, n); | ||
| 3386 | |||
| 3387 | nd->nd_remain += n; | ||
| 3388 | |||
| 3389 | dgrp_receive(nd); | ||
| 3390 | } | ||
| 3391 | |||
| 3392 | rtn = total; | ||
| 3393 | |||
| 3394 | unlock: | ||
| 3395 | /* | ||
| 3396 | * Release the NET lock. | ||
| 3397 | */ | ||
| 3398 | up(&nd->nd_net_semaphore); | ||
| 3399 | |||
| 3400 | return rtn; | ||
| 3401 | } | ||
| 3402 | |||
| 3403 | |||
| 3404 | /* | ||
| 3405 | * dgrp_net_select() | ||
| 3406 | * Determine whether a device is ready to be read or written to, and | ||
| 3407 | * sleep if not. | ||
| 3408 | */ | ||
| 3409 | static unsigned int dgrp_net_select(struct file *file, | ||
| 3410 | struct poll_table_struct *table) | ||
| 3411 | { | ||
| 3412 | unsigned int retval = 0; | ||
| 3413 | struct nd_struct *nd = file->private_data; | ||
| 3414 | |||
| 3415 | poll_wait(file, &nd->nd_tx_waitq, table); | ||
| 3416 | |||
| 3417 | if (nd->nd_tx_ready) | ||
| 3418 | retval |= POLLIN | POLLRDNORM; /* Conditionally readable */ | ||
| 3419 | |||
| 3420 | retval |= POLLOUT | POLLWRNORM; /* Always writeable */ | ||
| 3421 | |||
| 3422 | return retval; | ||
| 3423 | } | ||
| 3424 | |||
| 3425 | /* | ||
| 3426 | * dgrp_net_ioctl | ||
| 3427 | * | ||
| 3428 | * Implement those functions which allow the network daemon to control | ||
| 3429 | * the network parameters in the driver. The ioctls include ones to | ||
| 3430 | * get and set the link speed parameters for the PortServer. | ||
| 3431 | */ | ||
| 3432 | static long dgrp_net_ioctl(struct file *file, unsigned int cmd, | ||
| 3433 | unsigned long arg) | ||
| 3434 | { | ||
| 3435 | struct nd_struct *nd; | ||
| 3436 | int rtn = 0; | ||
| 3437 | long size = _IOC_SIZE(cmd); | ||
| 3438 | struct link_struct link; | ||
| 3439 | |||
| 3440 | nd = file->private_data; | ||
| 3441 | |||
| 3442 | if (_IOC_DIR(cmd) & _IOC_READ) | ||
| 3443 | rtn = access_ok(VERIFY_WRITE, (void __user *) arg, size); | ||
| 3444 | else if (_IOC_DIR(cmd) & _IOC_WRITE) | ||
| 3445 | rtn = access_ok(VERIFY_READ, (void __user *) arg, size); | ||
| 3446 | |||
| 3447 | if (!rtn) | ||
| 3448 | return rtn; | ||
| 3449 | |||
| 3450 | switch (cmd) { | ||
| 3451 | case DIGI_SETLINK: | ||
| 3452 | if (size != sizeof(struct link_struct)) | ||
| 3453 | return -EINVAL; | ||
| 3454 | |||
| 3455 | if (copy_from_user((void *)(&link), (void __user *) arg, size)) | ||
| 3456 | return -EFAULT; | ||
| 3457 | |||
| 3458 | if (link.lk_fast_rate < 9600) | ||
| 3459 | link.lk_fast_rate = 9600; | ||
| 3460 | |||
| 3461 | if (link.lk_slow_rate < 2400) | ||
| 3462 | link.lk_slow_rate = 2400; | ||
| 3463 | |||
| 3464 | if (link.lk_fast_rate > 10000000) | ||
| 3465 | link.lk_fast_rate = 10000000; | ||
| 3466 | |||
| 3467 | if (link.lk_slow_rate > link.lk_fast_rate) | ||
| 3468 | link.lk_slow_rate = link.lk_fast_rate; | ||
| 3469 | |||
| 3470 | if (link.lk_fast_delay > 2000) | ||
| 3471 | link.lk_fast_delay = 2000; | ||
| 3472 | |||
| 3473 | if (link.lk_slow_delay > 10000) | ||
| 3474 | link.lk_slow_delay = 10000; | ||
| 3475 | |||
| 3476 | if (link.lk_fast_delay < 60) | ||
| 3477 | link.lk_fast_delay = 60; | ||
| 3478 | |||
| 3479 | if (link.lk_slow_delay < link.lk_fast_delay) | ||
| 3480 | link.lk_slow_delay = link.lk_fast_delay; | ||
| 3481 | |||
| 3482 | if (link.lk_header_size < 2) | ||
| 3483 | link.lk_header_size = 2; | ||
| 3484 | |||
| 3485 | if (link.lk_header_size > 128) | ||
| 3486 | link.lk_header_size = 128; | ||
| 3487 | |||
| 3488 | link.lk_fast_rate /= 8 * 1000 / dgrp_poll_tick; | ||
| 3489 | link.lk_slow_rate /= 8 * 1000 / dgrp_poll_tick; | ||
| 3490 | |||
| 3491 | link.lk_fast_delay /= dgrp_poll_tick; | ||
| 3492 | link.lk_slow_delay /= dgrp_poll_tick; | ||
| 3493 | |||
| 3494 | nd->nd_link = link; | ||
| 3495 | |||
| 3496 | break; | ||
| 3497 | |||
| 3498 | case DIGI_GETLINK: | ||
| 3499 | if (size != sizeof(struct link_struct)) | ||
| 3500 | return -EINVAL; | ||
| 3501 | |||
| 3502 | if (copy_to_user((void __user *)arg, (void *)(&nd->nd_link), | ||
| 3503 | size)) | ||
| 3504 | return -EFAULT; | ||
| 3505 | |||
| 3506 | break; | ||
| 3507 | |||
| 3508 | default: | ||
| 3509 | return -EINVAL; | ||
| 3510 | |||
| 3511 | } | ||
| 3512 | |||
| 3513 | return 0; | ||
| 3514 | } | ||
| 3515 | |||
| 3516 | /** | ||
| 3517 | * dgrp_poll_handler() -- handler for poll timer | ||
| 3518 | * | ||
| 3519 | * As each timer expires, it determines (a) whether the "transmit" | ||
| 3520 | * waiter needs to be woken up, and (b) whether the poller needs to | ||
| 3521 | * be rescheduled. | ||
| 3522 | */ | ||
| 3523 | void dgrp_poll_handler(unsigned long arg) | ||
| 3524 | { | ||
| 3525 | struct dgrp_poll_data *poll_data; | ||
| 3526 | struct nd_struct *nd; | ||
| 3527 | struct link_struct *lk; | ||
| 3528 | ulong time; | ||
| 3529 | ulong poll_time; | ||
| 3530 | ulong freq; | ||
| 3531 | ulong lock_flags; | ||
| 3532 | |||
| 3533 | poll_data = (struct dgrp_poll_data *) arg; | ||
| 3534 | freq = 1000 / poll_data->poll_tick; | ||
| 3535 | poll_data->poll_round += 17; | ||
| 3536 | |||
| 3537 | if (poll_data->poll_round >= freq) | ||
| 3538 | poll_data->poll_round -= freq; | ||
| 3539 | |||
| 3540 | /* | ||
| 3541 | * Loop to process all open nodes. | ||
| 3542 | * | ||
| 3543 | * For each node, determine the rate at which it should | ||
| 3544 | * be transmitting data. Then if the node should wake up | ||
| 3545 | * and transmit data now, enable the net receive select | ||
| 3546 | * to get the transmit going. | ||
| 3547 | */ | ||
| 3548 | |||
| 3549 | list_for_each_entry(nd, &nd_struct_list, list) { | ||
| 3550 | |||
| 3551 | lk = &nd->nd_link; | ||
| 3552 | |||
| 3553 | /* | ||
| 3554 | * Decrement statistics. These are only for use with | ||
| 3555 | * KME, so don't worry that the operations are done | ||
| 3556 | * unlocked, and so the results are occassionally wrong. | ||
| 3557 | */ | ||
| 3558 | |||
| 3559 | nd->nd_read_count -= (nd->nd_read_count + | ||
| 3560 | poll_data->poll_round) / freq; | ||
| 3561 | nd->nd_write_count -= (nd->nd_write_count + | ||
| 3562 | poll_data->poll_round) / freq; | ||
| 3563 | nd->nd_send_count -= (nd->nd_send_count + | ||
| 3564 | poll_data->poll_round) / freq; | ||
| 3565 | nd->nd_tx_byte -= (nd->nd_tx_byte + | ||
| 3566 | poll_data->poll_round) / freq; | ||
| 3567 | nd->nd_rx_byte -= (nd->nd_rx_byte + | ||
| 3568 | poll_data->poll_round) / freq; | ||
| 3569 | |||
| 3570 | /* | ||
| 3571 | * Wake the daemon to transmit data only when there is | ||
| 3572 | * enough byte credit to send data. | ||
| 3573 | * | ||
| 3574 | * The results are approximate because the operations | ||
| 3575 | * are performed unlocked, and we are inspecting | ||
| 3576 | * data asynchronously updated elsewhere. The whole | ||
| 3577 | * thing is just approximation anyway, so that should | ||
| 3578 | * be okay. | ||
| 3579 | */ | ||
| 3580 | |||
| 3581 | if (lk->lk_slow_rate >= UIO_MAX) { | ||
| 3582 | |||
| 3583 | nd->nd_delay = 0; | ||
| 3584 | nd->nd_rate = UIO_MAX; | ||
| 3585 | |||
| 3586 | nd->nd_tx_deposit = nd->nd_tx_charge + 3 * UIO_MAX; | ||
| 3587 | nd->nd_tx_credit = 3 * UIO_MAX; | ||
| 3588 | |||
| 3589 | } else { | ||
| 3590 | |||
| 3591 | long rate; | ||
| 3592 | long delay; | ||
| 3593 | long deposit; | ||
| 3594 | long charge; | ||
| 3595 | long size; | ||
| 3596 | long excess; | ||
| 3597 | |||
| 3598 | long seq_in = nd->nd_seq_in; | ||
| 3599 | long seq_out = nd->nd_seq_out; | ||
| 3600 | |||
| 3601 | /* | ||
| 3602 | * If there are no outstanding packets, run at the | ||
| 3603 | * fastest rate. | ||
| 3604 | */ | ||
| 3605 | |||
| 3606 | if (seq_in == seq_out) { | ||
| 3607 | delay = 0; | ||
| 3608 | rate = lk->lk_fast_rate; | ||
| 3609 | } | ||
| 3610 | |||
| 3611 | /* | ||
| 3612 | * Otherwise compute the transmit rate based on the | ||
| 3613 | * delay since the oldest packet. | ||
| 3614 | */ | ||
| 3615 | |||
| 3616 | else { | ||
| 3617 | /* | ||
| 3618 | * The actual delay is computed as the | ||
| 3619 | * time since the oldest unacknowledged | ||
| 3620 | * packet was sent, minus the time it | ||
| 3621 | * took to send that packet to the server. | ||
| 3622 | */ | ||
| 3623 | |||
| 3624 | delay = ((jiffies - nd->nd_seq_time[seq_out]) | ||
| 3625 | - (nd->nd_seq_size[seq_out] / | ||
| 3626 | lk->lk_fast_rate)); | ||
| 3627 | |||
| 3628 | /* | ||
| 3629 | * If the delay is less than the "fast" | ||
| 3630 | * delay, transmit full speed. If greater | ||
| 3631 | * than the "slow" delay, transmit at the | ||
| 3632 | * "slow" speed. In between, interpolate | ||
| 3633 | * between the fast and slow speeds. | ||
| 3634 | */ | ||
| 3635 | |||
| 3636 | rate = | ||
| 3637 | (delay <= lk->lk_fast_delay ? | ||
| 3638 | lk->lk_fast_rate : | ||
| 3639 | delay >= lk->lk_slow_delay ? | ||
| 3640 | lk->lk_slow_rate : | ||
| 3641 | (lk->lk_slow_rate + | ||
| 3642 | (lk->lk_slow_delay - delay) * | ||
| 3643 | (lk->lk_fast_rate - lk->lk_slow_rate) / | ||
| 3644 | (lk->lk_slow_delay - lk->lk_fast_delay) | ||
| 3645 | ) | ||
| 3646 | ); | ||
| 3647 | } | ||
| 3648 | |||
| 3649 | nd->nd_delay = delay; | ||
| 3650 | nd->nd_rate = rate; | ||
| 3651 | |||
| 3652 | /* | ||
| 3653 | * Increase the transmit credit by depositing the | ||
| 3654 | * current transmit rate. | ||
| 3655 | */ | ||
| 3656 | |||
| 3657 | deposit = nd->nd_tx_deposit; | ||
| 3658 | charge = nd->nd_tx_charge; | ||
| 3659 | |||
| 3660 | deposit += rate; | ||
| 3661 | |||
| 3662 | /* | ||
| 3663 | * If the available transmit credit becomes too large, | ||
| 3664 | * reduce the deposit to correct the value. | ||
| 3665 | * | ||
| 3666 | * Too large is the max of: | ||
| 3667 | * 6 times the header size | ||
| 3668 | * 3 times the current transmit rate. | ||
| 3669 | */ | ||
| 3670 | |||
| 3671 | size = 2 * nd->nd_link.lk_header_size; | ||
| 3672 | |||
| 3673 | if (size < rate) | ||
| 3674 | size = rate; | ||
| 3675 | |||
| 3676 | size *= 3; | ||
| 3677 | |||
| 3678 | excess = deposit - charge - size; | ||
| 3679 | |||
| 3680 | if (excess > 0) | ||
| 3681 | deposit -= excess; | ||
| 3682 | |||
| 3683 | nd->nd_tx_deposit = deposit; | ||
| 3684 | nd->nd_tx_credit = deposit - charge; | ||
| 3685 | |||
| 3686 | /* | ||
| 3687 | * Wake the transmit task only if the transmit credit | ||
| 3688 | * is at least 3 times the transmit header size. | ||
| 3689 | */ | ||
| 3690 | |||
| 3691 | size = 3 * lk->lk_header_size; | ||
| 3692 | |||
| 3693 | if (nd->nd_tx_credit < size) | ||
| 3694 | continue; | ||
| 3695 | } | ||
| 3696 | |||
| 3697 | |||
| 3698 | /* | ||
| 3699 | * Enable the READ select to wake the daemon if there | ||
| 3700 | * is useful work for the drp_read routine to perform. | ||
| 3701 | */ | ||
| 3702 | |||
| 3703 | if (waitqueue_active(&nd->nd_tx_waitq) && | ||
| 3704 | (nd->nd_tx_work != 0 || | ||
| 3705 | (ulong)(jiffies - nd->nd_tx_time) >= IDLE_MAX)) { | ||
| 3706 | nd->nd_tx_ready = 1; | ||
| 3707 | |||
| 3708 | wake_up_interruptible(&nd->nd_tx_waitq); | ||
| 3709 | |||
| 3710 | /* not needed */ | ||
| 3711 | /* nd->nd_flag &= ~ND_SELECT; */ | ||
| 3712 | } | ||
| 3713 | } | ||
| 3714 | |||
| 3715 | |||
| 3716 | /* | ||
| 3717 | * Schedule ourself back at the nominal wakeup interval. | ||
| 3718 | */ | ||
| 3719 | spin_lock_irqsave(&poll_data->poll_lock, lock_flags); | ||
| 3720 | |||
| 3721 | poll_data->node_active_count--; | ||
| 3722 | if (poll_data->node_active_count > 0) { | ||
| 3723 | poll_data->node_active_count++; | ||
| 3724 | poll_time = poll_data->timer.expires + | ||
| 3725 | poll_data->poll_tick * HZ / 1000; | ||
| 3726 | |||
| 3727 | time = poll_time - jiffies; | ||
| 3728 | |||
| 3729 | if (time >= 2 * poll_data->poll_tick) | ||
| 3730 | poll_time = jiffies + dgrp_poll_tick * HZ / 1000; | ||
| 3731 | |||
| 3732 | poll_data->timer.expires = poll_time; | ||
| 3733 | add_timer(&poll_data->timer); | ||
| 3734 | } | ||
| 3735 | |||
| 3736 | spin_unlock_irqrestore(&poll_data->poll_lock, lock_flags); | ||
| 3737 | } | ||
diff --git a/drivers/staging/dgrp/dgrp_ports_ops.c b/drivers/staging/dgrp/dgrp_ports_ops.c new file mode 100644 index 000000000000..cd1fc2088624 --- /dev/null +++ b/drivers/staging/dgrp/dgrp_ports_ops.c | |||
| @@ -0,0 +1,170 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright 1999-2000 Digi International (www.digi.com) | ||
| 4 | * James Puzzo <jamesp at digi dot com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 9 | * any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the | ||
| 13 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | ||
| 14 | * PURPOSE. See the GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | |||
| 22 | /* | ||
| 23 | * | ||
| 24 | * Filename: | ||
| 25 | * | ||
| 26 | * dgrp_ports_ops.c | ||
| 27 | * | ||
| 28 | * Description: | ||
| 29 | * | ||
| 30 | * Handle the file operations required for the /proc/dgrp/ports/... | ||
| 31 | * devices. Basically gathers tty status for the node and returns it. | ||
| 32 | * | ||
| 33 | * Author: | ||
| 34 | * | ||
| 35 | * James A. Puzzo | ||
| 36 | * | ||
| 37 | */ | ||
| 38 | |||
| 39 | #include <linux/module.h> | ||
| 40 | #include <linux/proc_fs.h> | ||
| 41 | #include <linux/tty.h> | ||
| 42 | #include <linux/sched.h> | ||
| 43 | #include <linux/seq_file.h> | ||
| 44 | |||
| 45 | #include "dgrp_common.h" | ||
| 46 | |||
| 47 | /* File operation declarations */ | ||
| 48 | static int dgrp_ports_open(struct inode *, struct file *); | ||
| 49 | |||
| 50 | static const struct file_operations ports_ops = { | ||
| 51 | .owner = THIS_MODULE, | ||
| 52 | .open = dgrp_ports_open, | ||
| 53 | .read = seq_read, | ||
| 54 | .llseek = seq_lseek, | ||
| 55 | .release = seq_release | ||
| 56 | }; | ||
| 57 | |||
| 58 | static struct inode_operations ports_inode_ops = { | ||
| 59 | .permission = dgrp_inode_permission | ||
| 60 | }; | ||
| 61 | |||
| 62 | |||
| 63 | void dgrp_register_ports_hook(struct proc_dir_entry *de) | ||
| 64 | { | ||
| 65 | struct nd_struct *node = de->data; | ||
| 66 | |||
| 67 | de->proc_iops = &ports_inode_ops; | ||
| 68 | de->proc_fops = &ports_ops; | ||
| 69 | node->nd_ports_de = de; | ||
| 70 | } | ||
| 71 | |||
| 72 | static void *dgrp_ports_seq_start(struct seq_file *seq, loff_t *pos) | ||
| 73 | { | ||
| 74 | if (*pos == 0) | ||
| 75 | seq_puts(seq, "#num tty_open pr_open tot_wait MSTAT IFLAG OFLAG CFLAG BPS DIGIFLAGS\n"); | ||
| 76 | |||
| 77 | return pos; | ||
| 78 | } | ||
| 79 | |||
| 80 | static void *dgrp_ports_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
| 81 | { | ||
| 82 | struct nd_struct *nd = seq->private; | ||
| 83 | |||
| 84 | if (*pos >= nd->nd_chan_count) | ||
| 85 | return NULL; | ||
| 86 | |||
| 87 | *pos += 1; | ||
| 88 | |||
| 89 | return pos; | ||
| 90 | } | ||
| 91 | |||
| 92 | static void dgrp_ports_seq_stop(struct seq_file *seq, void *v) | ||
| 93 | { | ||
| 94 | } | ||
| 95 | |||
| 96 | static int dgrp_ports_seq_show(struct seq_file *seq, void *v) | ||
| 97 | { | ||
| 98 | loff_t *pos = v; | ||
| 99 | struct nd_struct *nd; | ||
| 100 | struct ch_struct *ch; | ||
| 101 | struct un_struct *tun, *pun; | ||
| 102 | unsigned int totcnt; | ||
| 103 | |||
| 104 | nd = seq->private; | ||
| 105 | if (!nd) | ||
| 106 | return 0; | ||
| 107 | |||
| 108 | if (*pos >= nd->nd_chan_count) | ||
| 109 | return 0; | ||
| 110 | |||
| 111 | ch = &nd->nd_chan[*pos]; | ||
| 112 | tun = &ch->ch_tun; | ||
| 113 | pun = &ch->ch_pun; | ||
| 114 | |||
| 115 | /* | ||
| 116 | * If port is not open and no one is waiting to | ||
| 117 | * open it, the modem signal values can't be | ||
| 118 | * trusted, and will be zeroed. | ||
| 119 | */ | ||
| 120 | totcnt = tun->un_open_count + | ||
| 121 | pun->un_open_count + | ||
| 122 | ch->ch_wait_count[0] + | ||
| 123 | ch->ch_wait_count[1] + | ||
| 124 | ch->ch_wait_count[2]; | ||
| 125 | |||
| 126 | seq_printf(seq, "%02d %02d %02d %02d 0x%04X 0x%04X 0x%04X 0x%04X %-6d 0x%04X\n", | ||
| 127 | (int) *pos, | ||
| 128 | tun->un_open_count, | ||
| 129 | pun->un_open_count, | ||
| 130 | ch->ch_wait_count[0] + | ||
| 131 | ch->ch_wait_count[1] + | ||
| 132 | ch->ch_wait_count[2], | ||
| 133 | (totcnt ? ch->ch_s_mlast : 0), | ||
| 134 | ch->ch_s_iflag, | ||
| 135 | ch->ch_s_oflag, | ||
| 136 | ch->ch_s_cflag, | ||
| 137 | (ch->ch_s_brate ? (1843200 / ch->ch_s_brate) : 0), | ||
| 138 | ch->ch_digi.digi_flags); | ||
| 139 | |||
| 140 | return 0; | ||
| 141 | } | ||
| 142 | |||
| 143 | static const struct seq_operations ports_seq_ops = { | ||
| 144 | .start = dgrp_ports_seq_start, | ||
| 145 | .next = dgrp_ports_seq_next, | ||
| 146 | .stop = dgrp_ports_seq_stop, | ||
| 147 | .show = dgrp_ports_seq_show, | ||
| 148 | }; | ||
| 149 | |||
| 150 | /** | ||
| 151 | * dgrp_ports_open -- open the /proc/dgrp/ports/... device | ||
| 152 | * @inode: struct inode * | ||
| 153 | * @file: struct file * | ||
| 154 | * | ||
| 155 | * Open function to open the /proc/dgrp/ports device for a PortServer. | ||
| 156 | * This is the open function for struct file_operations | ||
| 157 | */ | ||
| 158 | static int dgrp_ports_open(struct inode *inode, struct file *file) | ||
| 159 | { | ||
| 160 | struct seq_file *seq; | ||
| 161 | int rtn; | ||
| 162 | |||
| 163 | rtn = seq_open(file, &ports_seq_ops); | ||
| 164 | if (!rtn) { | ||
| 165 | seq = file->private_data; | ||
| 166 | seq->private = PDE(inode)->data; | ||
| 167 | } | ||
| 168 | |||
| 169 | return rtn; | ||
| 170 | } | ||
diff --git a/drivers/staging/dgrp/dgrp_specproc.c b/drivers/staging/dgrp/dgrp_specproc.c new file mode 100644 index 000000000000..28f5c9ab6b43 --- /dev/null +++ b/drivers/staging/dgrp/dgrp_specproc.c | |||
| @@ -0,0 +1,822 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright 1999 Digi International (www.digi.com) | ||
| 4 | * James Puzzo <jamesp at digi dot com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 9 | * any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the | ||
| 13 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | ||
| 14 | * PURPOSE. See the GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* | ||
| 19 | * | ||
| 20 | * Filename: | ||
| 21 | * | ||
| 22 | * dgrp_specproc.c | ||
| 23 | * | ||
| 24 | * Description: | ||
| 25 | * | ||
| 26 | * Handle the "config" proc entry for the linux realport device driver | ||
| 27 | * and provide slots for the "net" and "mon" devices | ||
| 28 | * | ||
| 29 | * Author: | ||
| 30 | * | ||
| 31 | * James A. Puzzo | ||
| 32 | * | ||
| 33 | */ | ||
| 34 | |||
| 35 | #include <linux/module.h> | ||
| 36 | #include <linux/tty.h> | ||
| 37 | #include <linux/sched.h> | ||
| 38 | #include <linux/cred.h> | ||
| 39 | #include <linux/proc_fs.h> | ||
| 40 | #include <linux/ctype.h> | ||
| 41 | #include <linux/seq_file.h> | ||
| 42 | #include <linux/vmalloc.h> | ||
| 43 | |||
| 44 | #include "dgrp_common.h" | ||
| 45 | |||
| 46 | static struct dgrp_proc_entry dgrp_table[]; | ||
| 47 | static struct proc_dir_entry *dgrp_proc_dir_entry; | ||
| 48 | |||
| 49 | static int dgrp_add_id(long id); | ||
| 50 | static int dgrp_remove_nd(struct nd_struct *nd); | ||
| 51 | static void unregister_dgrp_device(struct proc_dir_entry *de); | ||
| 52 | static void register_dgrp_device(struct nd_struct *node, | ||
| 53 | struct proc_dir_entry *root, | ||
| 54 | void (*register_hook)(struct proc_dir_entry *de)); | ||
| 55 | |||
| 56 | /* File operation declarations */ | ||
| 57 | static int dgrp_gen_proc_open(struct inode *, struct file *); | ||
| 58 | static int dgrp_gen_proc_close(struct inode *, struct file *); | ||
| 59 | static int parse_write_config(char *); | ||
| 60 | |||
| 61 | |||
| 62 | static const struct file_operations dgrp_proc_file_ops = { | ||
| 63 | .owner = THIS_MODULE, | ||
| 64 | .open = dgrp_gen_proc_open, | ||
| 65 | .release = dgrp_gen_proc_close, | ||
| 66 | }; | ||
| 67 | |||
| 68 | static struct inode_operations proc_inode_ops = { | ||
| 69 | .permission = dgrp_inode_permission | ||
| 70 | }; | ||
| 71 | |||
| 72 | |||
| 73 | static void register_proc_table(struct dgrp_proc_entry *, | ||
| 74 | struct proc_dir_entry *); | ||
| 75 | static void unregister_proc_table(struct dgrp_proc_entry *, | ||
| 76 | struct proc_dir_entry *); | ||
| 77 | |||
| 78 | static struct dgrp_proc_entry dgrp_net_table[]; | ||
| 79 | static struct dgrp_proc_entry dgrp_mon_table[]; | ||
| 80 | static struct dgrp_proc_entry dgrp_ports_table[]; | ||
| 81 | static struct dgrp_proc_entry dgrp_dpa_table[]; | ||
| 82 | |||
| 83 | static ssize_t config_proc_write(struct file *file, const char __user *buffer, | ||
| 84 | size_t count, loff_t *pos); | ||
| 85 | |||
| 86 | static int nodeinfo_proc_open(struct inode *inode, struct file *file); | ||
| 87 | static int info_proc_open(struct inode *inode, struct file *file); | ||
| 88 | static int config_proc_open(struct inode *inode, struct file *file); | ||
| 89 | |||
| 90 | static struct file_operations config_proc_file_ops = { | ||
| 91 | .owner = THIS_MODULE, | ||
| 92 | .open = config_proc_open, | ||
| 93 | .read = seq_read, | ||
| 94 | .llseek = seq_lseek, | ||
| 95 | .release = seq_release, | ||
| 96 | .write = config_proc_write | ||
| 97 | }; | ||
| 98 | |||
| 99 | static struct file_operations info_proc_file_ops = { | ||
| 100 | .owner = THIS_MODULE, | ||
| 101 | .open = info_proc_open, | ||
| 102 | .read = seq_read, | ||
| 103 | .llseek = seq_lseek, | ||
| 104 | .release = seq_release, | ||
| 105 | }; | ||
| 106 | |||
| 107 | static struct file_operations nodeinfo_proc_file_ops = { | ||
| 108 | .owner = THIS_MODULE, | ||
| 109 | .open = nodeinfo_proc_open, | ||
| 110 | .read = seq_read, | ||
| 111 | .llseek = seq_lseek, | ||
| 112 | .release = seq_release, | ||
| 113 | }; | ||
| 114 | |||
| 115 | static struct dgrp_proc_entry dgrp_table[] = { | ||
| 116 | { | ||
| 117 | .id = DGRP_CONFIG, | ||
| 118 | .name = "config", | ||
| 119 | .mode = 0644, | ||
| 120 | .proc_file_ops = &config_proc_file_ops, | ||
| 121 | }, | ||
| 122 | { | ||
| 123 | .id = DGRP_INFO, | ||
| 124 | .name = "info", | ||
| 125 | .mode = 0644, | ||
| 126 | .proc_file_ops = &info_proc_file_ops, | ||
| 127 | }, | ||
| 128 | { | ||
| 129 | .id = DGRP_NODEINFO, | ||
| 130 | .name = "nodeinfo", | ||
| 131 | .mode = 0644, | ||
| 132 | .proc_file_ops = &nodeinfo_proc_file_ops, | ||
| 133 | }, | ||
| 134 | { | ||
| 135 | .id = DGRP_NETDIR, | ||
| 136 | .name = "net", | ||
| 137 | .mode = 0500, | ||
| 138 | .child = dgrp_net_table | ||
| 139 | }, | ||
| 140 | { | ||
| 141 | .id = DGRP_MONDIR, | ||
| 142 | .name = "mon", | ||
| 143 | .mode = 0500, | ||
| 144 | .child = dgrp_mon_table | ||
| 145 | }, | ||
| 146 | { | ||
| 147 | .id = DGRP_PORTSDIR, | ||
| 148 | .name = "ports", | ||
| 149 | .mode = 0500, | ||
| 150 | .child = dgrp_ports_table | ||
| 151 | }, | ||
| 152 | { | ||
| 153 | .id = DGRP_DPADIR, | ||
| 154 | .name = "dpa", | ||
| 155 | .mode = 0500, | ||
| 156 | .child = dgrp_dpa_table | ||
| 157 | } | ||
| 158 | }; | ||
| 159 | |||
| 160 | static struct proc_dir_entry *net_entry_pointer; | ||
| 161 | static struct proc_dir_entry *mon_entry_pointer; | ||
| 162 | static struct proc_dir_entry *dpa_entry_pointer; | ||
| 163 | static struct proc_dir_entry *ports_entry_pointer; | ||
| 164 | |||
| 165 | static struct dgrp_proc_entry dgrp_net_table[] = { | ||
| 166 | {0} | ||
| 167 | }; | ||
| 168 | |||
| 169 | static struct dgrp_proc_entry dgrp_mon_table[] = { | ||
| 170 | {0} | ||
| 171 | }; | ||
| 172 | |||
| 173 | static struct dgrp_proc_entry dgrp_ports_table[] = { | ||
| 174 | {0} | ||
| 175 | }; | ||
| 176 | |||
| 177 | static struct dgrp_proc_entry dgrp_dpa_table[] = { | ||
| 178 | {0} | ||
| 179 | }; | ||
| 180 | |||
| 181 | void dgrp_unregister_proc(void) | ||
| 182 | { | ||
| 183 | unregister_proc_table(dgrp_table, dgrp_proc_dir_entry); | ||
| 184 | net_entry_pointer = NULL; | ||
| 185 | mon_entry_pointer = NULL; | ||
| 186 | dpa_entry_pointer = NULL; | ||
| 187 | ports_entry_pointer = NULL; | ||
| 188 | |||
| 189 | if (dgrp_proc_dir_entry) { | ||
| 190 | remove_proc_entry(dgrp_proc_dir_entry->name, | ||
| 191 | dgrp_proc_dir_entry->parent); | ||
| 192 | dgrp_proc_dir_entry = NULL; | ||
| 193 | } | ||
| 194 | |||
| 195 | } | ||
| 196 | |||
| 197 | void dgrp_register_proc(void) | ||
| 198 | { | ||
| 199 | /* | ||
| 200 | * Register /proc/dgrp | ||
| 201 | */ | ||
| 202 | dgrp_proc_dir_entry = proc_create("dgrp", S_IFDIR, NULL, | ||
| 203 | &dgrp_proc_file_ops); | ||
| 204 | register_proc_table(dgrp_table, dgrp_proc_dir_entry); | ||
| 205 | } | ||
| 206 | |||
| 207 | /* | ||
| 208 | * /proc/sys support | ||
| 209 | */ | ||
| 210 | static int dgrp_proc_match(int len, const char *name, struct proc_dir_entry *de) | ||
| 211 | { | ||
| 212 | if (!de || !de->low_ino) | ||
| 213 | return 0; | ||
| 214 | if (de->namelen != len) | ||
| 215 | return 0; | ||
| 216 | return !memcmp(name, de->name, len); | ||
| 217 | } | ||
| 218 | |||
| 219 | |||
| 220 | /* | ||
| 221 | * Scan the entries in table and add them all to /proc at the position | ||
| 222 | * referred to by "root" | ||
| 223 | */ | ||
| 224 | static void register_proc_table(struct dgrp_proc_entry *table, | ||
| 225 | struct proc_dir_entry *root) | ||
| 226 | { | ||
| 227 | struct proc_dir_entry *de; | ||
| 228 | int len; | ||
| 229 | mode_t mode; | ||
| 230 | |||
| 231 | for (; table->id; table++) { | ||
| 232 | /* Can't do anything without a proc name. */ | ||
| 233 | if (!table->name) | ||
| 234 | continue; | ||
| 235 | |||
| 236 | /* Maybe we can't do anything with it... */ | ||
| 237 | if (!table->proc_file_ops && | ||
| 238 | !table->child) { | ||
| 239 | pr_warn("dgrp: Can't register %s\n", | ||
| 240 | table->name); | ||
| 241 | continue; | ||
| 242 | } | ||
| 243 | |||
| 244 | len = strlen(table->name); | ||
| 245 | mode = table->mode; | ||
| 246 | |||
| 247 | de = NULL; | ||
| 248 | if (!table->child) | ||
| 249 | mode |= S_IFREG; | ||
| 250 | else { | ||
| 251 | mode |= S_IFDIR; | ||
| 252 | for (de = root->subdir; de; de = de->next) { | ||
| 253 | if (dgrp_proc_match(len, table->name, de)) | ||
| 254 | break; | ||
| 255 | } | ||
| 256 | /* If the subdir exists already, de is non-NULL */ | ||
| 257 | } | ||
| 258 | |||
| 259 | if (!de) { | ||
| 260 | de = create_proc_entry(table->name, mode, root); | ||
| 261 | if (!de) | ||
| 262 | continue; | ||
| 263 | de->data = (void *) table; | ||
| 264 | if (!table->child) { | ||
| 265 | de->proc_iops = &proc_inode_ops; | ||
| 266 | if (table->proc_file_ops) | ||
| 267 | de->proc_fops = table->proc_file_ops; | ||
| 268 | else | ||
| 269 | de->proc_fops = &dgrp_proc_file_ops; | ||
| 270 | } | ||
| 271 | } | ||
| 272 | table->de = de; | ||
| 273 | if (de->mode & S_IFDIR) | ||
| 274 | register_proc_table(table->child, de); | ||
| 275 | |||
| 276 | if (table->id == DGRP_NETDIR) | ||
| 277 | net_entry_pointer = de; | ||
| 278 | |||
| 279 | if (table->id == DGRP_MONDIR) | ||
| 280 | mon_entry_pointer = de; | ||
| 281 | |||
| 282 | if (table->id == DGRP_DPADIR) | ||
| 283 | dpa_entry_pointer = de; | ||
| 284 | |||
| 285 | if (table->id == DGRP_PORTSDIR) | ||
| 286 | ports_entry_pointer = de; | ||
| 287 | } | ||
| 288 | } | ||
| 289 | |||
| 290 | /* | ||
| 291 | * Unregister a /proc sysctl table and any subdirectories. | ||
| 292 | */ | ||
| 293 | static void unregister_proc_table(struct dgrp_proc_entry *table, | ||
| 294 | struct proc_dir_entry *root) | ||
| 295 | { | ||
| 296 | struct proc_dir_entry *de; | ||
| 297 | struct nd_struct *tmp; | ||
| 298 | |||
| 299 | list_for_each_entry(tmp, &nd_struct_list, list) { | ||
| 300 | if ((table == dgrp_net_table) && (tmp->nd_net_de)) { | ||
| 301 | unregister_dgrp_device(tmp->nd_net_de); | ||
| 302 | dgrp_remove_node_class_sysfs_files(tmp); | ||
| 303 | } | ||
| 304 | |||
| 305 | if ((table == dgrp_mon_table) && (tmp->nd_mon_de)) | ||
| 306 | unregister_dgrp_device(tmp->nd_mon_de); | ||
| 307 | |||
| 308 | if ((table == dgrp_dpa_table) && (tmp->nd_dpa_de)) | ||
| 309 | unregister_dgrp_device(tmp->nd_dpa_de); | ||
| 310 | |||
| 311 | if ((table == dgrp_ports_table) && (tmp->nd_ports_de)) | ||
| 312 | unregister_dgrp_device(tmp->nd_ports_de); | ||
| 313 | } | ||
| 314 | |||
| 315 | for (; table->id; table++) { | ||
| 316 | de = table->de; | ||
| 317 | |||
| 318 | if (!de) | ||
| 319 | continue; | ||
| 320 | if (de->mode & S_IFDIR) { | ||
| 321 | if (!table->child) { | ||
| 322 | pr_alert("dgrp: malformed sysctl tree on free\n"); | ||
| 323 | continue; | ||
| 324 | } | ||
| 325 | unregister_proc_table(table->child, de); | ||
| 326 | |||
| 327 | /* Don't unregister directories which still have entries */ | ||
| 328 | if (de->subdir) | ||
| 329 | continue; | ||
| 330 | } | ||
| 331 | |||
| 332 | /* Don't unregister proc entries that are still being used.. */ | ||
| 333 | if ((atomic_read(&de->count)) != 1) { | ||
| 334 | pr_alert("proc entry %s in use, not removing\n", | ||
| 335 | de->name); | ||
| 336 | continue; | ||
| 337 | } | ||
| 338 | |||
| 339 | remove_proc_entry(de->name, de->parent); | ||
| 340 | table->de = NULL; | ||
| 341 | } | ||
| 342 | } | ||
| 343 | |||
| 344 | static int dgrp_gen_proc_open(struct inode *inode, struct file *file) | ||
| 345 | { | ||
| 346 | struct proc_dir_entry *de; | ||
| 347 | struct dgrp_proc_entry *entry; | ||
| 348 | int ret = 0; | ||
| 349 | |||
| 350 | de = (struct proc_dir_entry *) PDE(file->f_dentry->d_inode); | ||
| 351 | if (!de || !de->data) { | ||
| 352 | ret = -ENXIO; | ||
| 353 | goto done; | ||
| 354 | } | ||
| 355 | |||
| 356 | entry = (struct dgrp_proc_entry *) de->data; | ||
| 357 | if (!entry) { | ||
| 358 | ret = -ENXIO; | ||
| 359 | goto done; | ||
| 360 | } | ||
| 361 | |||
| 362 | down(&entry->excl_sem); | ||
| 363 | |||
| 364 | if (entry->excl_cnt) | ||
| 365 | ret = -EBUSY; | ||
| 366 | else | ||
| 367 | entry->excl_cnt++; | ||
| 368 | |||
| 369 | up(&entry->excl_sem); | ||
| 370 | |||
| 371 | done: | ||
| 372 | return ret; | ||
| 373 | } | ||
| 374 | |||
| 375 | static int dgrp_gen_proc_close(struct inode *inode, struct file *file) | ||
| 376 | { | ||
| 377 | struct proc_dir_entry *de; | ||
| 378 | struct dgrp_proc_entry *entry; | ||
| 379 | |||
| 380 | de = (struct proc_dir_entry *) PDE(file->f_dentry->d_inode); | ||
| 381 | if (!de || !de->data) | ||
| 382 | goto done; | ||
| 383 | |||
| 384 | entry = (struct dgrp_proc_entry *) de->data; | ||
| 385 | if (!entry) | ||
| 386 | goto done; | ||
| 387 | |||
| 388 | down(&entry->excl_sem); | ||
| 389 | |||
| 390 | if (entry->excl_cnt) | ||
| 391 | entry->excl_cnt = 0; | ||
| 392 | |||
| 393 | up(&entry->excl_sem); | ||
| 394 | |||
| 395 | done: | ||
| 396 | return 0; | ||
| 397 | } | ||
| 398 | |||
| 399 | static void *config_proc_start(struct seq_file *m, loff_t *pos) | ||
| 400 | { | ||
| 401 | return seq_list_start_head(&nd_struct_list, *pos); | ||
| 402 | } | ||
| 403 | |||
| 404 | static void *config_proc_next(struct seq_file *p, void *v, loff_t *pos) | ||
| 405 | { | ||
| 406 | return seq_list_next(v, &nd_struct_list, pos); | ||
| 407 | } | ||
| 408 | |||
| 409 | static void config_proc_stop(struct seq_file *m, void *v) | ||
| 410 | { | ||
| 411 | } | ||
| 412 | |||
| 413 | static int config_proc_show(struct seq_file *m, void *v) | ||
| 414 | { | ||
| 415 | struct nd_struct *nd; | ||
| 416 | char tmp_id[4]; | ||
| 417 | |||
| 418 | if (v == &nd_struct_list) { | ||
| 419 | seq_puts(m, "#-----------------------------------------------------------------------------\n"); | ||
| 420 | seq_puts(m, "# Avail\n"); | ||
| 421 | seq_puts(m, "# ID Major State Ports\n"); | ||
| 422 | return 0; | ||
| 423 | } | ||
| 424 | |||
| 425 | nd = list_entry(v, struct nd_struct, list); | ||
| 426 | |||
| 427 | ID_TO_CHAR(nd->nd_ID, tmp_id); | ||
| 428 | |||
| 429 | seq_printf(m, " %-2.2s %-5ld %-10.10s %-5d\n", | ||
| 430 | tmp_id, | ||
| 431 | nd->nd_major, | ||
| 432 | ND_STATE_STR(nd->nd_state), | ||
| 433 | nd->nd_chan_count); | ||
| 434 | |||
| 435 | return 0; | ||
| 436 | } | ||
| 437 | |||
| 438 | static const struct seq_operations proc_config_ops = { | ||
| 439 | .start = config_proc_start, | ||
| 440 | .next = config_proc_next, | ||
| 441 | .stop = config_proc_stop, | ||
| 442 | .show = config_proc_show | ||
| 443 | }; | ||
| 444 | |||
| 445 | static int config_proc_open(struct inode *inode, struct file *file) | ||
| 446 | { | ||
| 447 | return seq_open(file, &proc_config_ops); | ||
| 448 | } | ||
| 449 | |||
| 450 | |||
| 451 | /* | ||
| 452 | * When writing configuration information, each "record" (i.e. each | ||
| 453 | * write) is treated as an independent request. See the "parse" | ||
| 454 | * description for more details. | ||
| 455 | */ | ||
| 456 | static ssize_t config_proc_write(struct file *file, const char __user *buffer, | ||
| 457 | size_t count, loff_t *pos) | ||
| 458 | { | ||
| 459 | ssize_t retval; | ||
| 460 | char *inbuf, *sp; | ||
| 461 | char *line, *ldelim; | ||
| 462 | |||
| 463 | if (count > 32768) | ||
| 464 | return -EINVAL; | ||
| 465 | |||
| 466 | inbuf = sp = vzalloc(count + 1); | ||
| 467 | if (!inbuf) | ||
| 468 | return -ENOMEM; | ||
| 469 | |||
| 470 | if (copy_from_user(inbuf, buffer, count)) { | ||
| 471 | retval = -EFAULT; | ||
| 472 | goto done; | ||
| 473 | } | ||
| 474 | |||
| 475 | inbuf[count] = 0; | ||
| 476 | |||
| 477 | ldelim = "\n"; | ||
| 478 | |||
| 479 | line = strpbrk(sp, ldelim); | ||
| 480 | while (line) { | ||
| 481 | *line = 0; | ||
| 482 | retval = parse_write_config(sp); | ||
| 483 | if (retval) | ||
| 484 | goto done; | ||
| 485 | |||
| 486 | sp = line + 1; | ||
| 487 | line = strpbrk(sp, ldelim); | ||
| 488 | } | ||
| 489 | |||
| 490 | retval = count; | ||
| 491 | done: | ||
| 492 | vfree(inbuf); | ||
| 493 | return retval; | ||
| 494 | } | ||
| 495 | |||
| 496 | /* | ||
| 497 | * ------------------------------------------------------------------------ | ||
| 498 | * | ||
| 499 | * The following are the functions to parse input | ||
| 500 | * | ||
| 501 | * ------------------------------------------------------------------------ | ||
| 502 | */ | ||
| 503 | static inline char *skip_past_ws(const char *str) | ||
| 504 | { | ||
| 505 | while ((*str) && !isspace(*str)) | ||
| 506 | ++str; | ||
| 507 | |||
| 508 | return skip_spaces(str); | ||
| 509 | } | ||
| 510 | |||
| 511 | static int parse_id(char **c, char *cID) | ||
| 512 | { | ||
| 513 | int tmp = **c; | ||
| 514 | |||
| 515 | if (isalnum(tmp) || (tmp == '_')) | ||
| 516 | cID[0] = tmp; | ||
| 517 | else | ||
| 518 | return -EINVAL; | ||
| 519 | |||
| 520 | (*c)++; tmp = **c; | ||
| 521 | |||
| 522 | if (isalnum(tmp) || (tmp == '_')) { | ||
| 523 | cID[1] = tmp; | ||
| 524 | (*c)++; | ||
| 525 | } else | ||
| 526 | cID[1] = 0; | ||
| 527 | |||
| 528 | return 0; | ||
| 529 | } | ||
| 530 | |||
| 531 | static int parse_add_config(char *buf) | ||
| 532 | { | ||
| 533 | char *c = buf; | ||
| 534 | int retval; | ||
| 535 | char cID[2]; | ||
| 536 | long ID; | ||
| 537 | |||
| 538 | c = skip_past_ws(c); | ||
| 539 | |||
| 540 | retval = parse_id(&c, cID); | ||
| 541 | if (retval < 0) | ||
| 542 | return retval; | ||
| 543 | |||
| 544 | ID = CHAR_TO_ID(cID); | ||
| 545 | |||
| 546 | c = skip_past_ws(c); | ||
| 547 | |||
| 548 | return dgrp_add_id(ID); | ||
| 549 | } | ||
| 550 | |||
| 551 | static int parse_del_config(char *buf) | ||
| 552 | { | ||
| 553 | char *c = buf; | ||
| 554 | int retval; | ||
| 555 | struct nd_struct *nd; | ||
| 556 | char cID[2]; | ||
| 557 | long ID; | ||
| 558 | long major; | ||
| 559 | |||
| 560 | c = skip_past_ws(c); | ||
| 561 | |||
| 562 | retval = parse_id(&c, cID); | ||
| 563 | if (retval < 0) | ||
| 564 | return retval; | ||
| 565 | |||
| 566 | ID = CHAR_TO_ID(cID); | ||
| 567 | |||
| 568 | c = skip_past_ws(c); | ||
| 569 | |||
| 570 | retval = kstrtol(c, 10, &major); | ||
| 571 | if (retval) | ||
| 572 | return retval; | ||
| 573 | |||
| 574 | nd = nd_struct_get(major); | ||
| 575 | if (!nd) | ||
| 576 | return -EINVAL; | ||
| 577 | |||
| 578 | if ((nd->nd_major != major) || (nd->nd_ID != ID)) | ||
| 579 | return -EINVAL; | ||
| 580 | |||
| 581 | return dgrp_remove_nd(nd); | ||
| 582 | } | ||
| 583 | |||
| 584 | static int parse_chg_config(char *buf) | ||
| 585 | { | ||
| 586 | return -EINVAL; | ||
| 587 | } | ||
| 588 | |||
| 589 | /* | ||
| 590 | * The passed character buffer represents a single configuration request. | ||
| 591 | * If the first character is a "+", it is parsed as a request to add a | ||
| 592 | * PortServer | ||
| 593 | * If the first character is a "-", it is parsed as a request to delete a | ||
| 594 | * PortServer | ||
| 595 | * If the first character is a "*", it is parsed as a request to change a | ||
| 596 | * PortServer | ||
| 597 | * Any other character (including whitespace) causes the record to be | ||
| 598 | * ignored. | ||
| 599 | */ | ||
| 600 | static int parse_write_config(char *buf) | ||
| 601 | { | ||
| 602 | int retval; | ||
| 603 | |||
| 604 | switch (buf[0]) { | ||
| 605 | case '+': | ||
| 606 | retval = parse_add_config(buf); | ||
| 607 | break; | ||
| 608 | case '-': | ||
| 609 | retval = parse_del_config(buf); | ||
| 610 | break; | ||
| 611 | case '*': | ||
| 612 | retval = parse_chg_config(buf); | ||
| 613 | break; | ||
| 614 | default: | ||
| 615 | retval = -EINVAL; | ||
| 616 | } | ||
| 617 | |||
| 618 | return retval; | ||
| 619 | } | ||
| 620 | |||
| 621 | static int info_proc_show(struct seq_file *m, void *v) | ||
| 622 | { | ||
| 623 | seq_printf(m, "version: %s\n", DIGI_VERSION); | ||
| 624 | seq_puts(m, "register_with_sysfs: 1\n"); | ||
| 625 | seq_printf(m, "rawreadok: 0x%08x\t(%d)\n", | ||
| 626 | dgrp_rawreadok, dgrp_rawreadok); | ||
| 627 | seq_printf(m, "pollrate: 0x%08x\t(%d)\n", | ||
| 628 | dgrp_poll_tick, dgrp_poll_tick); | ||
| 629 | |||
| 630 | return 0; | ||
| 631 | } | ||
| 632 | |||
| 633 | static int info_proc_open(struct inode *inode, struct file *file) | ||
| 634 | { | ||
| 635 | return single_open(file, info_proc_show, NULL); | ||
| 636 | } | ||
| 637 | |||
| 638 | |||
| 639 | static void *nodeinfo_start(struct seq_file *m, loff_t *pos) | ||
| 640 | { | ||
| 641 | return seq_list_start_head(&nd_struct_list, *pos); | ||
| 642 | } | ||
| 643 | |||
| 644 | static void *nodeinfo_next(struct seq_file *p, void *v, loff_t *pos) | ||
| 645 | { | ||
| 646 | return seq_list_next(v, &nd_struct_list, pos); | ||
| 647 | } | ||
| 648 | |||
| 649 | static void nodeinfo_stop(struct seq_file *m, void *v) | ||
| 650 | { | ||
| 651 | } | ||
| 652 | |||
| 653 | static int nodeinfo_show(struct seq_file *m, void *v) | ||
| 654 | { | ||
| 655 | struct nd_struct *nd; | ||
| 656 | char hwver[8]; | ||
| 657 | char swver[8]; | ||
| 658 | char tmp_id[4]; | ||
| 659 | |||
| 660 | if (v == &nd_struct_list) { | ||
| 661 | seq_puts(m, "#-----------------------------------------------------------------------------\n"); | ||
| 662 | seq_puts(m, "# HW HW SW\n"); | ||
| 663 | seq_puts(m, "# ID State Version ID Version Description\n"); | ||
| 664 | return 0; | ||
| 665 | } | ||
| 666 | |||
| 667 | nd = list_entry(v, struct nd_struct, list); | ||
| 668 | |||
| 669 | ID_TO_CHAR(nd->nd_ID, tmp_id); | ||
| 670 | |||
| 671 | if (nd->nd_state == NS_READY) { | ||
| 672 | sprintf(hwver, "%d.%d", (nd->nd_hw_ver >> 8) & 0xff, | ||
| 673 | nd->nd_hw_ver & 0xff); | ||
| 674 | sprintf(swver, "%d.%d", (nd->nd_sw_ver >> 8) & 0xff, | ||
| 675 | nd->nd_sw_ver & 0xff); | ||
| 676 | seq_printf(m, " %-2.2s %-10.10s %-7.7s %-3d %-7.7s %-35.35s\n", | ||
| 677 | tmp_id, | ||
| 678 | ND_STATE_STR(nd->nd_state), | ||
| 679 | hwver, | ||
| 680 | nd->nd_hw_id, | ||
| 681 | swver, | ||
| 682 | nd->nd_ps_desc); | ||
| 683 | |||
| 684 | } else { | ||
| 685 | seq_printf(m, " %-2.2s %-10.10s\n", | ||
| 686 | tmp_id, | ||
| 687 | ND_STATE_STR(nd->nd_state)); | ||
| 688 | } | ||
| 689 | |||
| 690 | return 0; | ||
| 691 | } | ||
| 692 | |||
| 693 | |||
| 694 | static const struct seq_operations nodeinfo_ops = { | ||
| 695 | .start = nodeinfo_start, | ||
| 696 | .next = nodeinfo_next, | ||
| 697 | .stop = nodeinfo_stop, | ||
| 698 | .show = nodeinfo_show | ||
| 699 | }; | ||
| 700 | |||
| 701 | static int nodeinfo_proc_open(struct inode *inode, struct file *file) | ||
| 702 | { | ||
| 703 | return seq_open(file, &nodeinfo_ops); | ||
| 704 | } | ||
| 705 | |||
| 706 | /** | ||
| 707 | * dgrp_add_id() -- creates new nd struct and adds it to list | ||
| 708 | * @id: id of device to add | ||
| 709 | */ | ||
| 710 | static int dgrp_add_id(long id) | ||
| 711 | { | ||
| 712 | struct nd_struct *nd; | ||
| 713 | int ret; | ||
| 714 | int i; | ||
| 715 | |||
| 716 | nd = kzalloc(sizeof(struct nd_struct), GFP_KERNEL); | ||
| 717 | if (!nd) | ||
| 718 | return -ENOMEM; | ||
| 719 | |||
| 720 | nd->nd_major = 0; | ||
| 721 | nd->nd_ID = id; | ||
| 722 | |||
| 723 | spin_lock_init(&nd->nd_lock); | ||
| 724 | |||
| 725 | init_waitqueue_head(&nd->nd_tx_waitq); | ||
| 726 | init_waitqueue_head(&nd->nd_mon_wqueue); | ||
| 727 | init_waitqueue_head(&nd->nd_dpa_wqueue); | ||
| 728 | for (i = 0; i < SEQ_MAX; i++) | ||
| 729 | init_waitqueue_head(&nd->nd_seq_wque[i]); | ||
| 730 | |||
| 731 | /* setup the structures to get the major number */ | ||
| 732 | ret = dgrp_tty_init(nd); | ||
| 733 | if (ret) | ||
| 734 | goto error_out; | ||
| 735 | |||
| 736 | nd->nd_major = nd->nd_serial_ttdriver->major; | ||
| 737 | |||
| 738 | ret = nd_struct_add(nd); | ||
| 739 | if (ret) | ||
| 740 | goto error_out; | ||
| 741 | |||
| 742 | register_dgrp_device(nd, net_entry_pointer, dgrp_register_net_hook); | ||
| 743 | register_dgrp_device(nd, mon_entry_pointer, dgrp_register_mon_hook); | ||
| 744 | register_dgrp_device(nd, dpa_entry_pointer, dgrp_register_dpa_hook); | ||
| 745 | register_dgrp_device(nd, ports_entry_pointer, | ||
| 746 | dgrp_register_ports_hook); | ||
| 747 | |||
| 748 | return 0; | ||
| 749 | |||
| 750 | error_out: | ||
| 751 | kfree(nd); | ||
| 752 | return ret; | ||
| 753 | |||
| 754 | } | ||
| 755 | |||
| 756 | static int dgrp_remove_nd(struct nd_struct *nd) | ||
| 757 | { | ||
| 758 | int ret; | ||
| 759 | |||
| 760 | /* Check to see if the selected structure is in use */ | ||
| 761 | if (nd->nd_tty_ref_cnt) | ||
| 762 | return -EBUSY; | ||
| 763 | |||
| 764 | if (nd->nd_net_de) { | ||
| 765 | unregister_dgrp_device(nd->nd_net_de); | ||
| 766 | dgrp_remove_node_class_sysfs_files(nd); | ||
| 767 | } | ||
| 768 | |||
| 769 | if (nd->nd_mon_de) | ||
| 770 | unregister_dgrp_device(nd->nd_mon_de); | ||
| 771 | |||
| 772 | if (nd->nd_ports_de) | ||
| 773 | unregister_dgrp_device(nd->nd_ports_de); | ||
| 774 | |||
| 775 | if (nd->nd_dpa_de) | ||
| 776 | unregister_dgrp_device(nd->nd_dpa_de); | ||
| 777 | |||
| 778 | dgrp_tty_uninit(nd); | ||
| 779 | |||
| 780 | ret = nd_struct_del(nd); | ||
| 781 | if (ret) | ||
| 782 | return ret; | ||
| 783 | |||
| 784 | kfree(nd); | ||
| 785 | return 0; | ||
| 786 | } | ||
| 787 | |||
| 788 | static void register_dgrp_device(struct nd_struct *node, | ||
| 789 | struct proc_dir_entry *root, | ||
| 790 | void (*register_hook)(struct proc_dir_entry *de)) | ||
| 791 | { | ||
| 792 | char buf[3]; | ||
| 793 | struct proc_dir_entry *de; | ||
| 794 | |||
| 795 | ID_TO_CHAR(node->nd_ID, buf); | ||
| 796 | |||
| 797 | de = create_proc_entry(buf, 0600 | S_IFREG, root); | ||
| 798 | if (!de) | ||
| 799 | return; | ||
| 800 | |||
| 801 | de->data = (void *) node; | ||
| 802 | |||
| 803 | if (register_hook) | ||
| 804 | register_hook(de); | ||
| 805 | |||
| 806 | } | ||
| 807 | |||
| 808 | static void unregister_dgrp_device(struct proc_dir_entry *de) | ||
| 809 | { | ||
| 810 | if (!de) | ||
| 811 | return; | ||
| 812 | |||
| 813 | /* Don't unregister proc entries that are still being used.. */ | ||
| 814 | if ((atomic_read(&de->count)) != 1) { | ||
| 815 | pr_alert("%s - proc entry %s in use. Not removing.\n", | ||
| 816 | __func__, de->name); | ||
| 817 | return; | ||
| 818 | } | ||
| 819 | |||
| 820 | remove_proc_entry(de->name, de->parent); | ||
| 821 | de = NULL; | ||
| 822 | } | ||
diff --git a/drivers/staging/dgrp/dgrp_sysfs.c b/drivers/staging/dgrp/dgrp_sysfs.c new file mode 100644 index 000000000000..e5a3c88d016e --- /dev/null +++ b/drivers/staging/dgrp/dgrp_sysfs.c | |||
| @@ -0,0 +1,555 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2004 Digi International (www.digi.com) | ||
| 3 | * Scott H Kilau <Scott_Kilau at digi dot com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 8 | * any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the | ||
| 12 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | ||
| 13 | * PURPOSE. See the GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "dgrp_common.h" | ||
| 18 | |||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/version.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/ctype.h> | ||
| 23 | #include <linux/string.h> | ||
| 24 | #include <linux/serial_reg.h> | ||
| 25 | #include <linux/pci.h> | ||
| 26 | #include <linux/kdev_t.h> | ||
| 27 | |||
| 28 | |||
| 29 | #define PORTSERVER_DIVIDEND 1843200 | ||
| 30 | #define SERIAL_TYPE_NORMAL 1 | ||
| 31 | #define SERIAL_TYPE_CALLOUT 2 | ||
| 32 | #define SERIAL_TYPE_XPRINT 3 | ||
| 33 | |||
| 34 | |||
| 35 | static struct class *dgrp_class; | ||
| 36 | static struct device *dgrp_class_nodes_dev; | ||
| 37 | static struct device *dgrp_class_global_settings_dev; | ||
| 38 | |||
| 39 | |||
| 40 | static ssize_t dgrp_class_version_show(struct class *class, | ||
| 41 | struct class_attribute *attr, char *buf) | ||
| 42 | { | ||
| 43 | return snprintf(buf, PAGE_SIZE, "%s\n", DIGI_VERSION); | ||
| 44 | } | ||
| 45 | static CLASS_ATTR(driver_version, 0400, dgrp_class_version_show, NULL); | ||
| 46 | |||
| 47 | |||
| 48 | static ssize_t dgrp_class_register_with_sysfs_show(struct device *c, | ||
| 49 | struct device_attribute *attr, | ||
| 50 | char *buf) | ||
| 51 | { | ||
| 52 | return snprintf(buf, PAGE_SIZE, "1\n"); | ||
| 53 | } | ||
| 54 | static DEVICE_ATTR(register_with_sysfs, 0400, | ||
| 55 | dgrp_class_register_with_sysfs_show, NULL); | ||
| 56 | |||
| 57 | |||
| 58 | static ssize_t dgrp_class_rawreadok_show(struct device *c, | ||
| 59 | struct device_attribute *attr, | ||
| 60 | char *buf) | ||
| 61 | { | ||
| 62 | return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_rawreadok); | ||
| 63 | } | ||
| 64 | static ssize_t dgrp_class_rawreadok_store(struct device *c, | ||
| 65 | struct device_attribute *attr, | ||
| 66 | const char *buf, size_t count) | ||
| 67 | { | ||
| 68 | sscanf(buf, "0x%x\n", &dgrp_rawreadok); | ||
| 69 | return count; | ||
| 70 | } | ||
| 71 | static DEVICE_ATTR(rawreadok, 0600, dgrp_class_rawreadok_show, | ||
| 72 | dgrp_class_rawreadok_store); | ||
| 73 | |||
| 74 | |||
| 75 | static ssize_t dgrp_class_pollrate_show(struct device *c, | ||
| 76 | struct device_attribute *attr, | ||
| 77 | char *buf) | ||
| 78 | { | ||
| 79 | return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_poll_tick); | ||
| 80 | } | ||
| 81 | |||
| 82 | static ssize_t dgrp_class_pollrate_store(struct device *c, | ||
| 83 | struct device_attribute *attr, | ||
| 84 | const char *buf, size_t count) | ||
| 85 | { | ||
| 86 | sscanf(buf, "0x%x\n", &dgrp_poll_tick); | ||
| 87 | return count; | ||
| 88 | } | ||
| 89 | static DEVICE_ATTR(pollrate, 0600, dgrp_class_pollrate_show, | ||
| 90 | dgrp_class_pollrate_store); | ||
| 91 | |||
| 92 | static struct attribute *dgrp_sysfs_global_settings_entries[] = { | ||
| 93 | &dev_attr_pollrate.attr, | ||
| 94 | &dev_attr_rawreadok.attr, | ||
| 95 | &dev_attr_register_with_sysfs.attr, | ||
| 96 | NULL | ||
| 97 | }; | ||
| 98 | |||
| 99 | |||
| 100 | static struct attribute_group dgrp_global_settings_attribute_group = { | ||
| 101 | .name = NULL, | ||
| 102 | .attrs = dgrp_sysfs_global_settings_entries, | ||
| 103 | }; | ||
| 104 | |||
| 105 | |||
| 106 | |||
| 107 | void dgrp_create_class_sysfs_files(void) | ||
| 108 | { | ||
| 109 | int ret = 0; | ||
| 110 | int max_majors = 1U << (32 - MINORBITS); | ||
| 111 | |||
| 112 | dgrp_class = class_create(THIS_MODULE, "digi_realport"); | ||
| 113 | ret = class_create_file(dgrp_class, &class_attr_driver_version); | ||
| 114 | |||
| 115 | dgrp_class_global_settings_dev = device_create(dgrp_class, NULL, | ||
| 116 | MKDEV(0, max_majors + 1), NULL, "driver_settings"); | ||
| 117 | |||
| 118 | ret = sysfs_create_group(&dgrp_class_global_settings_dev->kobj, | ||
| 119 | &dgrp_global_settings_attribute_group); | ||
| 120 | if (ret) { | ||
| 121 | pr_alert("%s: failed to create sysfs global settings device attributes.\n", | ||
| 122 | __func__); | ||
| 123 | sysfs_remove_group(&dgrp_class_global_settings_dev->kobj, | ||
| 124 | &dgrp_global_settings_attribute_group); | ||
| 125 | return; | ||
| 126 | } | ||
| 127 | |||
| 128 | dgrp_class_nodes_dev = device_create(dgrp_class, NULL, | ||
| 129 | MKDEV(0, max_majors + 2), NULL, "nodes"); | ||
| 130 | |||
| 131 | } | ||
| 132 | |||
| 133 | |||
| 134 | void dgrp_remove_class_sysfs_files(void) | ||
| 135 | { | ||
| 136 | struct nd_struct *nd; | ||
| 137 | int max_majors = 1U << (32 - MINORBITS); | ||
| 138 | |||
| 139 | list_for_each_entry(nd, &nd_struct_list, list) | ||
| 140 | dgrp_remove_node_class_sysfs_files(nd); | ||
| 141 | |||
| 142 | sysfs_remove_group(&dgrp_class_global_settings_dev->kobj, | ||
| 143 | &dgrp_global_settings_attribute_group); | ||
| 144 | |||
| 145 | class_remove_file(dgrp_class, &class_attr_driver_version); | ||
| 146 | |||
| 147 | device_destroy(dgrp_class, MKDEV(0, max_majors + 1)); | ||
| 148 | device_destroy(dgrp_class, MKDEV(0, max_majors + 2)); | ||
| 149 | class_destroy(dgrp_class); | ||
| 150 | } | ||
| 151 | |||
| 152 | static ssize_t dgrp_node_state_show(struct device *c, | ||
| 153 | struct device_attribute *attr, char *buf) | ||
| 154 | { | ||
| 155 | struct nd_struct *nd; | ||
| 156 | |||
| 157 | if (!c) | ||
| 158 | return 0; | ||
| 159 | nd = (struct nd_struct *) dev_get_drvdata(c); | ||
| 160 | if (!nd) | ||
| 161 | return 0; | ||
| 162 | |||
| 163 | return snprintf(buf, PAGE_SIZE, "%s\n", ND_STATE_STR(nd->nd_state)); | ||
| 164 | } | ||
| 165 | |||
| 166 | static DEVICE_ATTR(state, 0600, dgrp_node_state_show, NULL); | ||
| 167 | |||
| 168 | static ssize_t dgrp_node_description_show(struct device *c, | ||
| 169 | struct device_attribute *attr, | ||
| 170 | char *buf) | ||
| 171 | { | ||
| 172 | struct nd_struct *nd; | ||
| 173 | |||
| 174 | if (!c) | ||
| 175 | return 0; | ||
| 176 | nd = (struct nd_struct *) dev_get_drvdata(c); | ||
| 177 | if (!nd) | ||
| 178 | return 0; | ||
| 179 | |||
| 180 | if (nd->nd_state == NS_READY && nd->nd_ps_desc) | ||
| 181 | return snprintf(buf, PAGE_SIZE, "%s\n", nd->nd_ps_desc); | ||
| 182 | return 0; | ||
| 183 | } | ||
| 184 | static DEVICE_ATTR(description_info, 0600, dgrp_node_description_show, NULL); | ||
| 185 | |||
| 186 | static ssize_t dgrp_node_hw_version_show(struct device *c, | ||
| 187 | struct device_attribute *attr, | ||
| 188 | char *buf) | ||
| 189 | { | ||
| 190 | struct nd_struct *nd; | ||
| 191 | |||
| 192 | if (!c) | ||
| 193 | return 0; | ||
| 194 | nd = (struct nd_struct *) dev_get_drvdata(c); | ||
| 195 | if (!nd) | ||
| 196 | return 0; | ||
| 197 | |||
| 198 | if (nd->nd_state == NS_READY) | ||
| 199 | return snprintf(buf, PAGE_SIZE, "%d.%d\n", | ||
| 200 | (nd->nd_hw_ver >> 8) & 0xff, | ||
| 201 | nd->nd_hw_ver & 0xff); | ||
| 202 | |||
| 203 | return 0; | ||
| 204 | } | ||
| 205 | static DEVICE_ATTR(hw_version_info, 0600, dgrp_node_hw_version_show, NULL); | ||
| 206 | |||
| 207 | static ssize_t dgrp_node_hw_id_show(struct device *c, | ||
| 208 | struct device_attribute *attr, char *buf) | ||
| 209 | { | ||
| 210 | struct nd_struct *nd; | ||
| 211 | |||
| 212 | if (!c) | ||
| 213 | return 0; | ||
| 214 | nd = (struct nd_struct *) dev_get_drvdata(c); | ||
| 215 | if (!nd) | ||
| 216 | return 0; | ||
| 217 | |||
| 218 | |||
| 219 | if (nd->nd_state == NS_READY) | ||
| 220 | return snprintf(buf, PAGE_SIZE, "%d\n", nd->nd_hw_id); | ||
| 221 | return 0; | ||
| 222 | } | ||
| 223 | static DEVICE_ATTR(hw_id_info, 0600, dgrp_node_hw_id_show, NULL); | ||
| 224 | |||
| 225 | static ssize_t dgrp_node_sw_version_show(struct device *c, | ||
| 226 | struct device_attribute *attr, | ||
| 227 | char *buf) | ||
| 228 | { | ||
| 229 | struct nd_struct *nd; | ||
| 230 | |||
| 231 | if (!c) | ||
| 232 | return 0; | ||
| 233 | |||
| 234 | nd = (struct nd_struct *) dev_get_drvdata(c); | ||
| 235 | if (!nd) | ||
| 236 | return 0; | ||
| 237 | |||
| 238 | if (nd->nd_state == NS_READY) | ||
| 239 | return snprintf(buf, PAGE_SIZE, "%d.%d\n", | ||
| 240 | (nd->nd_sw_ver >> 8) & 0xff, | ||
| 241 | nd->nd_sw_ver & 0xff); | ||
| 242 | |||
| 243 | return 0; | ||
| 244 | } | ||
| 245 | static DEVICE_ATTR(sw_version_info, 0600, dgrp_node_sw_version_show, NULL); | ||
| 246 | |||
| 247 | |||
| 248 | static struct attribute *dgrp_sysfs_node_entries[] = { | ||
| 249 | &dev_attr_state.attr, | ||
| 250 | &dev_attr_description_info.attr, | ||
| 251 | &dev_attr_hw_version_info.attr, | ||
| 252 | &dev_attr_hw_id_info.attr, | ||
| 253 | &dev_attr_sw_version_info.attr, | ||
| 254 | NULL | ||
| 255 | }; | ||
| 256 | |||
| 257 | |||
| 258 | static struct attribute_group dgrp_node_attribute_group = { | ||
| 259 | .name = NULL, | ||
| 260 | .attrs = dgrp_sysfs_node_entries, | ||
| 261 | }; | ||
| 262 | |||
| 263 | |||
| 264 | void dgrp_create_node_class_sysfs_files(struct nd_struct *nd) | ||
| 265 | { | ||
| 266 | int ret; | ||
| 267 | char name[10]; | ||
| 268 | |||
| 269 | if (nd->nd_ID) | ||
| 270 | ID_TO_CHAR(nd->nd_ID, name); | ||
| 271 | else | ||
| 272 | sprintf(name, "node%ld", nd->nd_major); | ||
| 273 | |||
| 274 | nd->nd_class_dev = device_create(dgrp_class, dgrp_class_nodes_dev, | ||
| 275 | MKDEV(0, nd->nd_major), NULL, name); | ||
| 276 | |||
| 277 | ret = sysfs_create_group(&nd->nd_class_dev->kobj, | ||
| 278 | &dgrp_node_attribute_group); | ||
| 279 | |||
| 280 | if (ret) { | ||
| 281 | pr_alert("%s: failed to create sysfs node device attributes.\n", | ||
| 282 | __func__); | ||
| 283 | sysfs_remove_group(&nd->nd_class_dev->kobj, | ||
| 284 | &dgrp_node_attribute_group); | ||
| 285 | return; | ||
| 286 | } | ||
| 287 | |||
| 288 | dev_set_drvdata(nd->nd_class_dev, nd); | ||
| 289 | |||
| 290 | } | ||
| 291 | |||
| 292 | |||
| 293 | void dgrp_remove_node_class_sysfs_files(struct nd_struct *nd) | ||
| 294 | { | ||
| 295 | if (nd->nd_class_dev) { | ||
| 296 | sysfs_remove_group(&nd->nd_class_dev->kobj, | ||
| 297 | &dgrp_node_attribute_group); | ||
| 298 | |||
| 299 | device_destroy(dgrp_class, MKDEV(0, nd->nd_major)); | ||
| 300 | nd->nd_class_dev = NULL; | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | |||
| 305 | |||
| 306 | static ssize_t dgrp_tty_state_show(struct device *d, | ||
| 307 | struct device_attribute *attr, char *buf) | ||
| 308 | { | ||
| 309 | struct un_struct *un; | ||
| 310 | |||
| 311 | if (!d) | ||
| 312 | return 0; | ||
| 313 | un = (struct un_struct *) dev_get_drvdata(d); | ||
| 314 | if (!un) | ||
| 315 | return 0; | ||
| 316 | |||
| 317 | return snprintf(buf, PAGE_SIZE, "%s\n", | ||
| 318 | un->un_open_count ? "Open" : "Closed"); | ||
| 319 | } | ||
| 320 | static DEVICE_ATTR(state_info, 0600, dgrp_tty_state_show, NULL); | ||
| 321 | |||
| 322 | static ssize_t dgrp_tty_baud_show(struct device *d, | ||
| 323 | struct device_attribute *attr, char *buf) | ||
| 324 | { | ||
| 325 | struct ch_struct *ch; | ||
| 326 | struct un_struct *un; | ||
| 327 | |||
| 328 | if (!d) | ||
| 329 | return 0; | ||
| 330 | un = (struct un_struct *) dev_get_drvdata(d); | ||
| 331 | if (!un) | ||
| 332 | return 0; | ||
| 333 | ch = un->un_ch; | ||
| 334 | if (!ch) | ||
| 335 | return 0; | ||
| 336 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
| 337 | un->un_open_count ? (PORTSERVER_DIVIDEND / ch->ch_s_brate) : 0); | ||
| 338 | } | ||
| 339 | static DEVICE_ATTR(baud_info, 0400, dgrp_tty_baud_show, NULL); | ||
| 340 | |||
| 341 | |||
| 342 | static ssize_t dgrp_tty_msignals_show(struct device *d, | ||
| 343 | struct device_attribute *attr, char *buf) | ||
| 344 | { | ||
| 345 | struct ch_struct *ch; | ||
| 346 | struct un_struct *un; | ||
| 347 | |||
| 348 | if (!d) | ||
| 349 | return 0; | ||
| 350 | un = (struct un_struct *) dev_get_drvdata(d); | ||
| 351 | if (!un) | ||
| 352 | return 0; | ||
| 353 | ch = un->un_ch; | ||
| 354 | if (!ch) | ||
| 355 | return 0; | ||
| 356 | |||
| 357 | if (ch->ch_open_count) { | ||
| 358 | return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n", | ||
| 359 | (ch->ch_s_mlast & DM_RTS) ? "RTS" : "", | ||
| 360 | (ch->ch_s_mlast & DM_CTS) ? "CTS" : "", | ||
| 361 | (ch->ch_s_mlast & DM_DTR) ? "DTR" : "", | ||
| 362 | (ch->ch_s_mlast & DM_DSR) ? "DSR" : "", | ||
| 363 | (ch->ch_s_mlast & DM_CD) ? "DCD" : "", | ||
| 364 | (ch->ch_s_mlast & DM_RI) ? "RI" : ""); | ||
| 365 | } | ||
| 366 | return 0; | ||
| 367 | } | ||
| 368 | static DEVICE_ATTR(msignals_info, 0400, dgrp_tty_msignals_show, NULL); | ||
| 369 | |||
| 370 | |||
| 371 | static ssize_t dgrp_tty_iflag_show(struct device *d, | ||
| 372 | struct device_attribute *attr, char *buf) | ||
| 373 | { | ||
| 374 | struct ch_struct *ch; | ||
| 375 | struct un_struct *un; | ||
| 376 | |||
| 377 | if (!d) | ||
| 378 | return 0; | ||
| 379 | un = (struct un_struct *) dev_get_drvdata(d); | ||
| 380 | if (!un) | ||
| 381 | return 0; | ||
| 382 | ch = un->un_ch; | ||
| 383 | if (!ch) | ||
| 384 | return 0; | ||
| 385 | return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_iflag); | ||
| 386 | } | ||
| 387 | static DEVICE_ATTR(iflag_info, 0600, dgrp_tty_iflag_show, NULL); | ||
| 388 | |||
| 389 | |||
| 390 | static ssize_t dgrp_tty_cflag_show(struct device *d, | ||
| 391 | struct device_attribute *attr, char *buf) | ||
| 392 | { | ||
| 393 | struct ch_struct *ch; | ||
| 394 | struct un_struct *un; | ||
| 395 | |||
| 396 | if (!d) | ||
| 397 | return 0; | ||
| 398 | un = (struct un_struct *) dev_get_drvdata(d); | ||
| 399 | if (!un) | ||
| 400 | return 0; | ||
| 401 | ch = un->un_ch; | ||
| 402 | if (!ch) | ||
| 403 | return 0; | ||
| 404 | return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_cflag); | ||
| 405 | } | ||
| 406 | static DEVICE_ATTR(cflag_info, 0600, dgrp_tty_cflag_show, NULL); | ||
| 407 | |||
| 408 | |||
| 409 | static ssize_t dgrp_tty_oflag_show(struct device *d, | ||
| 410 | struct device_attribute *attr, char *buf) | ||
| 411 | { | ||
| 412 | struct ch_struct *ch; | ||
| 413 | struct un_struct *un; | ||
| 414 | |||
| 415 | if (!d) | ||
| 416 | return 0; | ||
| 417 | un = (struct un_struct *) dev_get_drvdata(d); | ||
| 418 | if (!un) | ||
| 419 | return 0; | ||
| 420 | ch = un->un_ch; | ||
| 421 | if (!ch) | ||
| 422 | return 0; | ||
| 423 | return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_oflag); | ||
| 424 | } | ||
| 425 | static DEVICE_ATTR(oflag_info, 0600, dgrp_tty_oflag_show, NULL); | ||
| 426 | |||
| 427 | |||
| 428 | static ssize_t dgrp_tty_digi_flag_show(struct device *d, | ||
| 429 | struct device_attribute *attr, char *buf) | ||
| 430 | { | ||
| 431 | struct ch_struct *ch; | ||
| 432 | struct un_struct *un; | ||
| 433 | |||
| 434 | if (!d) | ||
| 435 | return 0; | ||
| 436 | un = (struct un_struct *) dev_get_drvdata(d); | ||
| 437 | if (!un) | ||
| 438 | return 0; | ||
| 439 | ch = un->un_ch; | ||
| 440 | if (!ch) | ||
| 441 | return 0; | ||
| 442 | return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags); | ||
| 443 | } | ||
| 444 | static DEVICE_ATTR(digi_flag_info, 0600, dgrp_tty_digi_flag_show, NULL); | ||
| 445 | |||
| 446 | |||
| 447 | static ssize_t dgrp_tty_rxcount_show(struct device *d, | ||
| 448 | struct device_attribute *attr, char *buf) | ||
| 449 | { | ||
| 450 | struct ch_struct *ch; | ||
| 451 | struct un_struct *un; | ||
| 452 | |||
| 453 | if (!d) | ||
| 454 | return 0; | ||
| 455 | un = (struct un_struct *) dev_get_drvdata(d); | ||
| 456 | if (!un) | ||
| 457 | return 0; | ||
| 458 | ch = un->un_ch; | ||
| 459 | if (!ch) | ||
| 460 | return 0; | ||
| 461 | return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_rxcount); | ||
| 462 | } | ||
| 463 | static DEVICE_ATTR(rxcount_info, 0600, dgrp_tty_rxcount_show, NULL); | ||
| 464 | |||
| 465 | |||
| 466 | static ssize_t dgrp_tty_txcount_show(struct device *d, | ||
| 467 | struct device_attribute *attr, char *buf) | ||
| 468 | { | ||
| 469 | struct ch_struct *ch; | ||
| 470 | struct un_struct *un; | ||
| 471 | |||
| 472 | if (!d) | ||
| 473 | return 0; | ||
| 474 | un = (struct un_struct *) dev_get_drvdata(d); | ||
| 475 | if (!un) | ||
| 476 | return 0; | ||
| 477 | ch = un->un_ch; | ||
| 478 | if (!ch) | ||
| 479 | return 0; | ||
| 480 | return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_txcount); | ||
| 481 | } | ||
| 482 | static DEVICE_ATTR(txcount_info, 0600, dgrp_tty_txcount_show, NULL); | ||
| 483 | |||
| 484 | |||
| 485 | static ssize_t dgrp_tty_name_show(struct device *d, | ||
| 486 | struct device_attribute *attr, char *buf) | ||
| 487 | { | ||
| 488 | struct nd_struct *nd; | ||
| 489 | struct ch_struct *ch; | ||
| 490 | struct un_struct *un; | ||
| 491 | char name[10]; | ||
| 492 | |||
| 493 | if (!d) | ||
| 494 | return 0; | ||
| 495 | un = (struct un_struct *) dev_get_drvdata(d); | ||
| 496 | if (!un) | ||
| 497 | return 0; | ||
| 498 | ch = un->un_ch; | ||
| 499 | if (!ch) | ||
| 500 | return 0; | ||
| 501 | nd = ch->ch_nd; | ||
| 502 | if (!nd) | ||
| 503 | return 0; | ||
| 504 | |||
| 505 | ID_TO_CHAR(nd->nd_ID, name); | ||
| 506 | |||
| 507 | return snprintf(buf, PAGE_SIZE, "%s%s%02d\n", | ||
| 508 | un->un_type == SERIAL_TYPE_XPRINT ? "pr" : "tty", | ||
| 509 | name, ch->ch_portnum); | ||
| 510 | } | ||
| 511 | static DEVICE_ATTR(custom_name, 0600, dgrp_tty_name_show, NULL); | ||
| 512 | |||
| 513 | |||
| 514 | static struct attribute *dgrp_sysfs_tty_entries[] = { | ||
| 515 | &dev_attr_state_info.attr, | ||
| 516 | &dev_attr_baud_info.attr, | ||
| 517 | &dev_attr_msignals_info.attr, | ||
| 518 | &dev_attr_iflag_info.attr, | ||
| 519 | &dev_attr_cflag_info.attr, | ||
| 520 | &dev_attr_oflag_info.attr, | ||
| 521 | &dev_attr_digi_flag_info.attr, | ||
| 522 | &dev_attr_rxcount_info.attr, | ||
| 523 | &dev_attr_txcount_info.attr, | ||
| 524 | &dev_attr_custom_name.attr, | ||
| 525 | NULL | ||
| 526 | }; | ||
| 527 | |||
| 528 | |||
| 529 | static struct attribute_group dgrp_tty_attribute_group = { | ||
| 530 | .name = NULL, | ||
| 531 | .attrs = dgrp_sysfs_tty_entries, | ||
| 532 | }; | ||
| 533 | |||
| 534 | |||
| 535 | void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c) | ||
| 536 | { | ||
| 537 | int ret; | ||
| 538 | |||
| 539 | ret = sysfs_create_group(&c->kobj, &dgrp_tty_attribute_group); | ||
| 540 | if (ret) { | ||
| 541 | pr_alert("%s: failed to create sysfs tty device attributes.\n", | ||
| 542 | __func__); | ||
| 543 | sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group); | ||
| 544 | return; | ||
| 545 | } | ||
| 546 | |||
| 547 | dev_set_drvdata(c, un); | ||
| 548 | |||
| 549 | } | ||
| 550 | |||
| 551 | |||
| 552 | void dgrp_remove_tty_sysfs(struct device *c) | ||
| 553 | { | ||
| 554 | sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group); | ||
| 555 | } | ||
diff --git a/drivers/staging/dgrp/dgrp_tty.c b/drivers/staging/dgrp/dgrp_tty.c new file mode 100644 index 000000000000..7d7de873870c --- /dev/null +++ b/drivers/staging/dgrp/dgrp_tty.c | |||
| @@ -0,0 +1,3331 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright 1999 Digi International (www.digi.com) | ||
| 4 | * Gene Olson <Gene_Olson at digi dot com> | ||
| 5 | * James Puzzo <jamesp at digi dot com> | ||
| 6 | * Jeff Randall | ||
| 7 | * Scott Kilau <scottk at digi dot com> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 12 | * any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the | ||
| 16 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | ||
| 17 | * PURPOSE. See the GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * | ||
| 23 | * Filename: | ||
| 24 | * | ||
| 25 | * dgrp_tty.c | ||
| 26 | * | ||
| 27 | * Description: | ||
| 28 | * | ||
| 29 | * This file implements the tty driver functionality for the | ||
| 30 | * RealPort driver software. | ||
| 31 | * | ||
| 32 | * Author: | ||
| 33 | * | ||
| 34 | * James A. Puzzo | ||
| 35 | * Ann-Marie Westgate | ||
| 36 | * | ||
| 37 | */ | ||
| 38 | |||
| 39 | #include <linux/slab.h> | ||
| 40 | #include <linux/tty.h> | ||
| 41 | #include <linux/tty_flip.h> | ||
| 42 | #include <linux/sched.h> | ||
| 43 | |||
| 44 | #include "dgrp_common.h" | ||
| 45 | |||
| 46 | #ifndef _POSIX_VDISABLE | ||
| 47 | #define _POSIX_VDISABLE ('\0') | ||
| 48 | #endif | ||
| 49 | |||
| 50 | /* | ||
| 51 | * forward declarations | ||
| 52 | */ | ||
| 53 | |||
| 54 | static void drp_param(struct ch_struct *); | ||
| 55 | static void dgrp_tty_close(struct tty_struct *, struct file *); | ||
| 56 | |||
| 57 | /* ioctl helper functions */ | ||
| 58 | static int set_modem_info(struct ch_struct *, unsigned int, unsigned int *); | ||
| 59 | static int get_modem_info(struct ch_struct *, unsigned int *); | ||
| 60 | static void dgrp_set_custom_speed(struct ch_struct *, int); | ||
| 61 | static int dgrp_tty_digigetedelay(struct tty_struct *, int *); | ||
| 62 | static int dgrp_tty_digisetedelay(struct tty_struct *, int *); | ||
| 63 | static int dgrp_send_break(struct ch_struct *, int); | ||
| 64 | |||
| 65 | static ushort tty_to_ch_flags(struct tty_struct *, char); | ||
| 66 | static tcflag_t ch_to_tty_flags(unsigned short, char); | ||
| 67 | |||
| 68 | static void dgrp_tty_input_start(struct tty_struct *); | ||
| 69 | static void dgrp_tty_input_stop(struct tty_struct *); | ||
| 70 | |||
| 71 | static void drp_wmove(struct ch_struct *, int, void*, int); | ||
| 72 | |||
| 73 | static int dgrp_tty_open(struct tty_struct *, struct file *); | ||
| 74 | static void dgrp_tty_close(struct tty_struct *, struct file *); | ||
| 75 | static int dgrp_tty_write(struct tty_struct *, const unsigned char *, int); | ||
| 76 | static int dgrp_tty_write_room(struct tty_struct *); | ||
| 77 | static void dgrp_tty_flush_buffer(struct tty_struct *); | ||
| 78 | static int dgrp_tty_chars_in_buffer(struct tty_struct *); | ||
| 79 | static int dgrp_tty_ioctl(struct tty_struct *, unsigned int, unsigned long); | ||
| 80 | static void dgrp_tty_set_termios(struct tty_struct *, struct ktermios *); | ||
| 81 | static void dgrp_tty_stop(struct tty_struct *); | ||
| 82 | static void dgrp_tty_start(struct tty_struct *); | ||
| 83 | static void dgrp_tty_throttle(struct tty_struct *); | ||
| 84 | static void dgrp_tty_unthrottle(struct tty_struct *); | ||
| 85 | static void dgrp_tty_hangup(struct tty_struct *); | ||
| 86 | static int dgrp_tty_put_char(struct tty_struct *, unsigned char); | ||
| 87 | static int dgrp_tty_tiocmget(struct tty_struct *); | ||
| 88 | static int dgrp_tty_tiocmset(struct tty_struct *, unsigned int, unsigned int); | ||
| 89 | static int dgrp_tty_send_break(struct tty_struct *, int); | ||
| 90 | static void dgrp_tty_send_xchar(struct tty_struct *, char); | ||
| 91 | |||
| 92 | /* | ||
| 93 | * tty defines | ||
| 94 | */ | ||
| 95 | #define SERIAL_TYPE_NORMAL 1 | ||
| 96 | #define SERIAL_TYPE_CALLOUT 2 | ||
| 97 | #define SERIAL_TYPE_XPRINT 3 | ||
| 98 | |||
| 99 | |||
| 100 | /* | ||
| 101 | * tty globals/statics | ||
| 102 | */ | ||
| 103 | |||
| 104 | |||
| 105 | #define PORTSERVER_DIVIDEND 1843200 | ||
| 106 | |||
| 107 | /* | ||
| 108 | * Default transparent print information. | ||
| 109 | */ | ||
| 110 | static struct digi_struct digi_init = { | ||
| 111 | .digi_flags = DIGI_COOK, /* Flags */ | ||
| 112 | .digi_maxcps = 100, /* Max CPS */ | ||
| 113 | .digi_maxchar = 50, /* Max chars in print queue */ | ||
| 114 | .digi_bufsize = 100, /* Printer buffer size */ | ||
| 115 | .digi_onlen = 4, /* size of printer on string */ | ||
| 116 | .digi_offlen = 4, /* size of printer off string */ | ||
| 117 | .digi_onstr = "\033[5i", /* ANSI printer on string */ | ||
| 118 | .digi_offstr = "\033[4i", /* ANSI printer off string */ | ||
| 119 | .digi_term = "ansi" /* default terminal type */ | ||
| 120 | }; | ||
| 121 | |||
| 122 | /* | ||
| 123 | * Define a local default termios struct. All ports will be created | ||
| 124 | * with this termios initially. | ||
| 125 | * | ||
| 126 | * This defines a raw port at 9600 baud, 8 data bits, no parity, | ||
| 127 | * 1 stop bit. | ||
| 128 | */ | ||
| 129 | static struct ktermios DefaultTermios = { | ||
| 130 | .c_iflag = (ICRNL | IXON), | ||
| 131 | .c_oflag = (OPOST | ONLCR), | ||
| 132 | .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL), | ||
| 133 | .c_lflag = (ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ||
| 134 | | ECHOKE | IEXTEN), | ||
| 135 | .c_cc = INIT_C_CC, | ||
| 136 | .c_line = 0, | ||
| 137 | }; | ||
| 138 | |||
| 139 | /* Define our tty operations struct */ | ||
| 140 | static const struct tty_operations dgrp_tty_ops = { | ||
| 141 | .open = dgrp_tty_open, | ||
| 142 | .close = dgrp_tty_close, | ||
| 143 | .write = dgrp_tty_write, | ||
| 144 | .write_room = dgrp_tty_write_room, | ||
| 145 | .flush_buffer = dgrp_tty_flush_buffer, | ||
| 146 | .chars_in_buffer = dgrp_tty_chars_in_buffer, | ||
| 147 | .flush_chars = NULL, | ||
| 148 | .ioctl = dgrp_tty_ioctl, | ||
| 149 | .set_termios = dgrp_tty_set_termios, | ||
| 150 | .stop = dgrp_tty_stop, | ||
| 151 | .start = dgrp_tty_start, | ||
| 152 | .throttle = dgrp_tty_throttle, | ||
| 153 | .unthrottle = dgrp_tty_unthrottle, | ||
| 154 | .hangup = dgrp_tty_hangup, | ||
| 155 | .put_char = dgrp_tty_put_char, | ||
| 156 | .tiocmget = dgrp_tty_tiocmget, | ||
| 157 | .tiocmset = dgrp_tty_tiocmset, | ||
| 158 | .break_ctl = dgrp_tty_send_break, | ||
| 159 | .send_xchar = dgrp_tty_send_xchar | ||
| 160 | }; | ||
| 161 | |||
| 162 | |||
| 163 | static int calc_baud_rate(struct un_struct *un) | ||
| 164 | { | ||
| 165 | int i; | ||
| 166 | int brate; | ||
| 167 | |||
| 168 | struct baud_rates { | ||
| 169 | unsigned int rate; | ||
| 170 | unsigned int cflag; | ||
| 171 | }; | ||
| 172 | |||
| 173 | static struct baud_rates baud_rates[] = { | ||
| 174 | { 921600, B921600 }, | ||
| 175 | { 460800, B460800 }, | ||
| 176 | { 230400, B230400 }, | ||
| 177 | { 115200, B115200 }, | ||
| 178 | { 57600, B57600 }, | ||
| 179 | { 38400, B38400 }, | ||
| 180 | { 19200, B19200 }, | ||
| 181 | { 9600, B9600 }, | ||
| 182 | { 4800, B4800 }, | ||
| 183 | { 2400, B2400 }, | ||
| 184 | { 1200, B1200 }, | ||
| 185 | { 600, B600 }, | ||
| 186 | { 300, B300 }, | ||
| 187 | { 200, B200 }, | ||
| 188 | { 150, B150 }, | ||
| 189 | { 134, B134 }, | ||
| 190 | { 110, B110 }, | ||
| 191 | { 75, B75 }, | ||
| 192 | { 50, B50 }, | ||
| 193 | { 0, B9600 } | ||
| 194 | }; | ||
| 195 | |||
| 196 | brate = C_BAUD(un->un_tty); | ||
| 197 | |||
| 198 | for (i = 0; baud_rates[i].rate; i++) { | ||
| 199 | if (baud_rates[i].cflag == brate) | ||
| 200 | break; | ||
| 201 | } | ||
| 202 | |||
| 203 | return baud_rates[i].rate; | ||
| 204 | } | ||
| 205 | |||
| 206 | static int calc_fastbaud_rate(struct un_struct *un, struct ktermios *uts) | ||
| 207 | { | ||
| 208 | int i; | ||
| 209 | int brate; | ||
| 210 | |||
| 211 | ulong bauds[2][16] = { | ||
| 212 | { /* fastbaud*/ | ||
| 213 | 0, 57600, 76800, 115200, | ||
| 214 | 131657, 153600, 230400, 460800, | ||
| 215 | 921600, 1200, 1800, 2400, | ||
| 216 | 4800, 9600, 19200, 38400 }, | ||
| 217 | { /* fastbaud & CBAUDEX */ | ||
| 218 | 0, 57600, 115200, 230400, | ||
| 219 | 460800, 150, 200, 921600, | ||
| 220 | 600, 1200, 1800, 2400, | ||
| 221 | 4800, 9600, 19200, 38400 } | ||
| 222 | }; | ||
| 223 | |||
| 224 | brate = C_BAUD(un->un_tty) & 0xff; | ||
| 225 | |||
| 226 | i = (uts->c_cflag & CBAUDEX) ? 1 : 0; | ||
| 227 | |||
| 228 | |||
| 229 | if ((i >= 0) && (i < 2) && (brate >= 0) && (brate < 16)) | ||
| 230 | brate = bauds[i][brate]; | ||
| 231 | else | ||
| 232 | brate = 0; | ||
| 233 | |||
| 234 | return brate; | ||
| 235 | } | ||
| 236 | |||
| 237 | /** | ||
| 238 | * drp_param() -- send parameter values to be sent to the node | ||
| 239 | * @ch: channel structure of port to modify | ||
| 240 | * | ||
| 241 | * Interprets the tty and modem changes made by an application | ||
| 242 | * program (by examining the termios structures) and sets up | ||
| 243 | * parameter values to be sent to the node. | ||
| 244 | */ | ||
| 245 | static void drp_param(struct ch_struct *ch) | ||
| 246 | { | ||
| 247 | struct nd_struct *nd; | ||
| 248 | struct un_struct *un; | ||
| 249 | int brate; | ||
| 250 | int mflow; | ||
| 251 | int xflag; | ||
| 252 | int iflag; | ||
| 253 | struct ktermios *tts, *pts, *uts; | ||
| 254 | |||
| 255 | nd = ch->ch_nd; | ||
| 256 | |||
| 257 | /* | ||
| 258 | * If the terminal device is open, use it to set up all tty | ||
| 259 | * modes and functions. Otherwise use the printer device. | ||
| 260 | */ | ||
| 261 | |||
| 262 | if (ch->ch_tun.un_open_count) { | ||
| 263 | |||
| 264 | un = &ch->ch_tun; | ||
| 265 | tts = &ch->ch_tun.un_tty->termios; | ||
| 266 | |||
| 267 | /* | ||
| 268 | * If both devices are open, copy critical line | ||
| 269 | * parameters from the tty device to the printer, | ||
| 270 | * so that if the tty is closed, the printer will | ||
| 271 | * continue without disruption. | ||
| 272 | */ | ||
| 273 | |||
| 274 | if (ch->ch_pun.un_open_count) { | ||
| 275 | |||
| 276 | pts = &ch->ch_pun.un_tty->termios; | ||
| 277 | |||
| 278 | pts->c_cflag ^= | ||
| 279 | (pts->c_cflag ^ tts->c_cflag) & | ||
| 280 | (CBAUD | CSIZE | CSTOPB | CREAD | PARENB | | ||
| 281 | PARODD | HUPCL | CLOCAL); | ||
| 282 | |||
| 283 | pts->c_iflag ^= | ||
| 284 | (pts->c_iflag ^ tts->c_iflag) & | ||
| 285 | (IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | | ||
| 286 | ISTRIP | IXON | IXANY | IXOFF); | ||
| 287 | |||
| 288 | pts->c_cc[VSTART] = tts->c_cc[VSTART]; | ||
| 289 | pts->c_cc[VSTOP] = tts->c_cc[VSTOP]; | ||
| 290 | } | ||
| 291 | } else if (ch->ch_pun.un_open_count == 0) { | ||
| 292 | pr_warn("%s - ch_pun.un_open_count shouldn't be 0\n", | ||
| 293 | __func__); | ||
| 294 | return; | ||
| 295 | } else { | ||
| 296 | un = &ch->ch_pun; | ||
| 297 | } | ||
| 298 | |||
| 299 | uts = &un->un_tty->termios; | ||
| 300 | |||
| 301 | /* | ||
| 302 | * Determine if FAST writes can be performed. | ||
| 303 | */ | ||
| 304 | |||
| 305 | if ((ch->ch_digi.digi_flags & DIGI_COOK) != 0 && | ||
| 306 | (ch->ch_tun.un_open_count != 0) && | ||
| 307 | !((un->un_tty)->ldisc->ops->flags & LDISC_FLAG_DEFINED) && | ||
| 308 | !(L_XCASE(un->un_tty))) { | ||
| 309 | ch->ch_flag |= CH_FAST_WRITE; | ||
| 310 | } else { | ||
| 311 | ch->ch_flag &= ~CH_FAST_WRITE; | ||
| 312 | } | ||
| 313 | |||
| 314 | /* | ||
| 315 | * If FAST writes can be performed, and OPOST is on in the | ||
| 316 | * terminal device, do OPOST handling in the server. | ||
| 317 | */ | ||
| 318 | |||
| 319 | if ((ch->ch_flag & CH_FAST_WRITE) && | ||
| 320 | O_OPOST(un->un_tty) != 0) { | ||
| 321 | int oflag = tty_to_ch_flags(un->un_tty, 'o'); | ||
| 322 | |||
| 323 | /* add to ch_ocook any processing flags set in the termio */ | ||
| 324 | ch->ch_ocook |= oflag & (OF_OLCUC | | ||
| 325 | OF_ONLCR | | ||
| 326 | OF_OCRNL | | ||
| 327 | OF_ONLRET | | ||
| 328 | OF_TABDLY); | ||
| 329 | |||
| 330 | /* | ||
| 331 | * the hpux driver clears any flags set in ch_ocook | ||
| 332 | * from the termios oflag. It is STILL reported though | ||
| 333 | * by a TCGETA | ||
| 334 | */ | ||
| 335 | |||
| 336 | oflag = ch_to_tty_flags(ch->ch_ocook, 'o'); | ||
| 337 | uts->c_oflag &= ~oflag; | ||
| 338 | |||
| 339 | } else { | ||
| 340 | /* clear the ch->ch_ocook flag */ | ||
| 341 | int oflag = ch_to_tty_flags(ch->ch_ocook, 'o'); | ||
| 342 | uts->c_oflag |= oflag; | ||
| 343 | ch->ch_ocook = 0; | ||
| 344 | } | ||
| 345 | |||
| 346 | ch->ch_oflag = ch->ch_ocook; | ||
| 347 | |||
| 348 | |||
| 349 | ch->ch_flag &= ~CH_FAST_READ; | ||
| 350 | |||
| 351 | /* | ||
| 352 | * Generate channel flags | ||
| 353 | */ | ||
| 354 | |||
| 355 | if (C_BAUD(un->un_tty) == B0) { | ||
| 356 | if (!(ch->ch_flag & CH_BAUD0)) { | ||
| 357 | /* TODO : the HPUX driver flushes line */ | ||
| 358 | /* TODO : discipline, I assume I don't have to */ | ||
| 359 | |||
| 360 | ch->ch_tout = ch->ch_tin; | ||
| 361 | ch->ch_rout = ch->ch_rin; | ||
| 362 | |||
| 363 | ch->ch_break_time = 0; | ||
| 364 | |||
| 365 | ch->ch_send |= RR_TX_FLUSH | RR_RX_FLUSH; | ||
| 366 | |||
| 367 | ch->ch_mout &= ~(DM_DTR | DM_RTS); | ||
| 368 | |||
| 369 | ch->ch_flag |= CH_BAUD0; | ||
| 370 | } | ||
| 371 | } else if (ch->ch_custom_speed) { | ||
| 372 | ch->ch_brate = PORTSERVER_DIVIDEND / ch->ch_custom_speed ; | ||
| 373 | |||
| 374 | if (ch->ch_flag & CH_BAUD0) { | ||
| 375 | ch->ch_mout |= DM_DTR | DM_RTS; | ||
| 376 | |||
| 377 | ch->ch_flag &= ~CH_BAUD0; | ||
| 378 | } | ||
| 379 | } else { | ||
| 380 | /* | ||
| 381 | * Baud rate mapping. | ||
| 382 | * | ||
| 383 | * If FASTBAUD isn't on, we can scan the new baud rate list | ||
| 384 | * as required. | ||
| 385 | * | ||
| 386 | * However, if FASTBAUD is on, we must go to the old | ||
| 387 | * baud rate mapping that existed many many moons ago, | ||
| 388 | * for compatibility reasons. | ||
| 389 | */ | ||
| 390 | |||
| 391 | if (!(ch->ch_digi.digi_flags & DIGI_FAST)) | ||
| 392 | brate = calc_baud_rate(un); | ||
| 393 | else | ||
| 394 | brate = calc_fastbaud_rate(un, uts); | ||
| 395 | |||
| 396 | if (brate == 0) | ||
| 397 | brate = 9600; | ||
| 398 | |||
| 399 | ch->ch_brate = PORTSERVER_DIVIDEND / brate; | ||
| 400 | |||
| 401 | if (ch->ch_flag & CH_BAUD0) { | ||
| 402 | ch->ch_mout |= DM_DTR | DM_RTS; | ||
| 403 | |||
| 404 | ch->ch_flag &= ~CH_BAUD0; | ||
| 405 | } | ||
| 406 | } | ||
| 407 | |||
| 408 | /* | ||
| 409 | * Generate channel cflags from the termio. | ||
| 410 | */ | ||
| 411 | |||
| 412 | ch->ch_cflag = tty_to_ch_flags(un->un_tty, 'c'); | ||
| 413 | |||
| 414 | /* | ||
| 415 | * Generate channel iflags from the termio. | ||
| 416 | */ | ||
| 417 | |||
| 418 | iflag = (int) tty_to_ch_flags(un->un_tty, 'i'); | ||
| 419 | |||
| 420 | if (START_CHAR(un->un_tty) == _POSIX_VDISABLE || | ||
| 421 | STOP_CHAR(un->un_tty) == _POSIX_VDISABLE) { | ||
| 422 | iflag &= ~(IF_IXON | IF_IXANY | IF_IXOFF); | ||
| 423 | } | ||
| 424 | |||
| 425 | ch->ch_iflag = iflag; | ||
| 426 | |||
| 427 | /* | ||
| 428 | * Generate flow control characters | ||
| 429 | */ | ||
| 430 | |||
| 431 | /* | ||
| 432 | * From the POSIX.1 spec (7.1.2.6): "If {_POSIX_VDISABLE} | ||
| 433 | * is defined for the terminal device file, and the value | ||
| 434 | * of one of the changable special control characters (see | ||
| 435 | * 7.1.1.9) is {_POSIX_VDISABLE}, that function shall be | ||
| 436 | * disabled, that is, no input data shall be recognized as | ||
| 437 | * the disabled special character." | ||
| 438 | * | ||
| 439 | * OK, so we don't ever assign S/DXB XON or XOFF to _POSIX_VDISABLE. | ||
| 440 | */ | ||
| 441 | |||
| 442 | if (uts->c_cc[VSTART] != _POSIX_VDISABLE) | ||
| 443 | ch->ch_xon = uts->c_cc[VSTART]; | ||
| 444 | if (uts->c_cc[VSTOP] != _POSIX_VDISABLE) | ||
| 445 | ch->ch_xoff = uts->c_cc[VSTOP]; | ||
| 446 | |||
| 447 | ch->ch_lnext = (uts->c_cc[VLNEXT] == _POSIX_VDISABLE ? 0 : | ||
| 448 | uts->c_cc[VLNEXT]); | ||
| 449 | |||
| 450 | /* | ||
| 451 | * Also, if either c_cc[START] or c_cc[STOP] is set to | ||
| 452 | * _POSIX_VDISABLE, we can't really do software flow | ||
| 453 | * control--in either direction--so we turn it off as | ||
| 454 | * far as S/DXB is concerned. In essence, if you disable | ||
| 455 | * one, you disable the other too. | ||
| 456 | */ | ||
| 457 | if ((uts->c_cc[VSTART] == _POSIX_VDISABLE) || | ||
| 458 | (uts->c_cc[VSTOP] == _POSIX_VDISABLE)) | ||
| 459 | ch->ch_iflag &= ~(IF_IXOFF | IF_IXON); | ||
| 460 | |||
| 461 | /* | ||
| 462 | * Update xflags. | ||
| 463 | */ | ||
| 464 | |||
| 465 | xflag = 0; | ||
| 466 | |||
| 467 | if (ch->ch_digi.digi_flags & DIGI_AIXON) | ||
| 468 | xflag = XF_XIXON; | ||
| 469 | |||
| 470 | if ((ch->ch_xxon == _POSIX_VDISABLE) || | ||
| 471 | (ch->ch_xxoff == _POSIX_VDISABLE)) | ||
| 472 | xflag &= ~XF_XIXON; | ||
| 473 | |||
| 474 | ch->ch_xflag = xflag; | ||
| 475 | |||
| 476 | |||
| 477 | /* | ||
| 478 | * Figure effective DCD value. | ||
| 479 | */ | ||
| 480 | |||
| 481 | if (C_CLOCAL(un->un_tty)) | ||
| 482 | ch->ch_flag |= CH_CLOCAL; | ||
| 483 | else | ||
| 484 | ch->ch_flag &= ~CH_CLOCAL; | ||
| 485 | |||
| 486 | /* | ||
| 487 | * Check modem signals | ||
| 488 | */ | ||
| 489 | |||
| 490 | dgrp_carrier(ch); | ||
| 491 | |||
| 492 | /* | ||
| 493 | * Get hardware handshake value. | ||
| 494 | */ | ||
| 495 | |||
| 496 | mflow = 0; | ||
| 497 | |||
| 498 | if (C_CRTSCTS(un->un_tty)) | ||
| 499 | mflow |= (DM_RTS | DM_CTS); | ||
| 500 | |||
| 501 | if (ch->ch_digi.digi_flags & RTSPACE) | ||
| 502 | mflow |= DM_RTS; | ||
| 503 | |||
| 504 | if (ch->ch_digi.digi_flags & DTRPACE) | ||
| 505 | mflow |= DM_DTR; | ||
| 506 | |||
| 507 | if (ch->ch_digi.digi_flags & CTSPACE) | ||
| 508 | mflow |= DM_CTS; | ||
| 509 | |||
| 510 | if (ch->ch_digi.digi_flags & DSRPACE) | ||
| 511 | mflow |= DM_DSR; | ||
| 512 | |||
| 513 | if (ch->ch_digi.digi_flags & DCDPACE) | ||
| 514 | mflow |= DM_CD; | ||
| 515 | |||
| 516 | if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) | ||
| 517 | mflow |= DM_RTS_TOGGLE; | ||
| 518 | |||
| 519 | ch->ch_mflow = mflow; | ||
| 520 | |||
| 521 | /* | ||
| 522 | * Send the changes to the server. | ||
| 523 | */ | ||
| 524 | |||
| 525 | ch->ch_flag |= CH_PARAM; | ||
| 526 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 527 | |||
| 528 | if (waitqueue_active(&ch->ch_flag_wait)) | ||
| 529 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 530 | } | ||
| 531 | |||
| 532 | /* | ||
| 533 | * This function is just used as a callback for timeouts | ||
| 534 | * waiting on the ch_sleep flag. | ||
| 535 | */ | ||
| 536 | static void wake_up_drp_sleep_timer(unsigned long ptr) | ||
| 537 | { | ||
| 538 | struct ch_struct *ch = (struct ch_struct *) ptr; | ||
| 539 | if (ch) | ||
| 540 | wake_up(&ch->ch_sleep); | ||
| 541 | } | ||
| 542 | |||
| 543 | |||
| 544 | /* | ||
| 545 | * Set up our own sleep that can't be cancelled | ||
| 546 | * until our timeout occurs. | ||
| 547 | */ | ||
| 548 | static void drp_my_sleep(struct ch_struct *ch) | ||
| 549 | { | ||
| 550 | struct timer_list drp_wakeup_timer; | ||
| 551 | DECLARE_WAITQUEUE(wait, current); | ||
| 552 | |||
| 553 | /* | ||
| 554 | * First make sure we're ready to receive the wakeup. | ||
| 555 | */ | ||
| 556 | |||
| 557 | add_wait_queue(&ch->ch_sleep, &wait); | ||
| 558 | current->state = TASK_UNINTERRUPTIBLE; | ||
| 559 | |||
| 560 | /* | ||
| 561 | * Since we are uninterruptible, set a timer to | ||
| 562 | * unset the uninterruptable state in 1 second. | ||
| 563 | */ | ||
| 564 | |||
| 565 | init_timer(&drp_wakeup_timer); | ||
| 566 | drp_wakeup_timer.function = wake_up_drp_sleep_timer; | ||
| 567 | drp_wakeup_timer.data = (unsigned long) ch; | ||
| 568 | drp_wakeup_timer.expires = jiffies + (1 * HZ); | ||
| 569 | add_timer(&drp_wakeup_timer); | ||
| 570 | |||
| 571 | schedule(); | ||
| 572 | |||
| 573 | del_timer(&drp_wakeup_timer); | ||
| 574 | |||
| 575 | remove_wait_queue(&ch->ch_sleep, &wait); | ||
| 576 | } | ||
| 577 | |||
| 578 | /* | ||
| 579 | * dgrp_tty_open() | ||
| 580 | * | ||
| 581 | * returns: | ||
| 582 | * -EBUSY - this is a callout device and the normal device is active | ||
| 583 | * - there is an error in opening the tty | ||
| 584 | * -ENODEV - the channel does not exist | ||
| 585 | * -EAGAIN - we are in the middle of hanging up or closing | ||
| 586 | * - IMMEDIATE_OPEN fails | ||
| 587 | * -ENXIO or -EAGAIN | ||
| 588 | * - if the port is outside physical range | ||
| 589 | * -EINTR - the open is interrupted | ||
| 590 | * | ||
| 591 | */ | ||
| 592 | static int dgrp_tty_open(struct tty_struct *tty, struct file *file) | ||
| 593 | { | ||
| 594 | int retval = 0; | ||
| 595 | struct nd_struct *nd; | ||
| 596 | struct ch_struct *ch; | ||
| 597 | struct un_struct *un; | ||
| 598 | int port; | ||
| 599 | int delay_error; | ||
| 600 | int otype; | ||
| 601 | int unf; | ||
| 602 | int wait_carrier; | ||
| 603 | int category; | ||
| 604 | int counts_were_incremented = 0; | ||
| 605 | ulong lock_flags; | ||
| 606 | DECLARE_WAITQUEUE(wait, current); | ||
| 607 | |||
| 608 | /* | ||
| 609 | * Do some initial checks to see if the node and port exist | ||
| 610 | */ | ||
| 611 | |||
| 612 | nd = nd_struct_get(MAJOR(tty_devnum(tty))); | ||
| 613 | port = PORT_NUM(MINOR(tty_devnum(tty))); | ||
| 614 | category = OPEN_CATEGORY(MINOR(tty_devnum(tty))); | ||
| 615 | |||
| 616 | if (!nd) | ||
| 617 | return -ENODEV; | ||
| 618 | |||
| 619 | if (port >= CHAN_MAX) | ||
| 620 | return -ENODEV; | ||
| 621 | |||
| 622 | /* | ||
| 623 | * The channel exists. | ||
| 624 | */ | ||
| 625 | |||
| 626 | ch = nd->nd_chan + port; | ||
| 627 | |||
| 628 | un = IS_PRINT(MINOR(tty_devnum(tty))) ? &ch->ch_pun : &ch->ch_tun; | ||
| 629 | un->un_tty = tty; | ||
| 630 | tty->driver_data = un; | ||
| 631 | |||
| 632 | /* | ||
| 633 | * If we are in the middle of hanging up, | ||
| 634 | * then return an error | ||
| 635 | */ | ||
| 636 | if (tty_hung_up_p(file)) { | ||
| 637 | retval = ((un->un_flag & UN_HUP_NOTIFY) ? | ||
| 638 | -EAGAIN : -ERESTARTSYS); | ||
| 639 | goto done; | ||
| 640 | } | ||
| 641 | |||
| 642 | /* | ||
| 643 | * If the port is in the middle of closing, then block | ||
| 644 | * until it is done, then try again. | ||
| 645 | */ | ||
| 646 | retval = wait_event_interruptible(un->un_close_wait, | ||
| 647 | ((un->un_flag & UN_CLOSING) == 0)); | ||
| 648 | |||
| 649 | if (retval) | ||
| 650 | goto done; | ||
| 651 | |||
| 652 | /* | ||
| 653 | * If the port is in the middle of a reopen after a network disconnect, | ||
| 654 | * wait until it is done, then try again. | ||
| 655 | */ | ||
| 656 | retval = wait_event_interruptible(ch->ch_flag_wait, | ||
| 657 | ((ch->ch_flag & CH_PORT_GONE) == 0)); | ||
| 658 | |||
| 659 | if (retval) | ||
| 660 | goto done; | ||
| 661 | |||
| 662 | /* | ||
| 663 | * If this is a callout device, then just make sure the normal | ||
| 664 | * device isn't being used. | ||
| 665 | */ | ||
| 666 | |||
| 667 | if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) { | ||
| 668 | if (un->un_flag & UN_NORMAL_ACTIVE) { | ||
| 669 | retval = -EBUSY; | ||
| 670 | goto done; | ||
| 671 | } else { | ||
| 672 | un->un_flag |= UN_CALLOUT_ACTIVE; | ||
| 673 | } | ||
| 674 | } | ||
| 675 | |||
| 676 | /* | ||
| 677 | * Loop waiting until the open can be successfully completed. | ||
| 678 | */ | ||
| 679 | |||
| 680 | spin_lock_irqsave(&nd->nd_lock, lock_flags); | ||
| 681 | |||
| 682 | nd->nd_tx_work = 1; | ||
| 683 | |||
| 684 | for (;;) { | ||
| 685 | wait_carrier = 0; | ||
| 686 | |||
| 687 | /* | ||
| 688 | * Determine the open type from the flags provided. | ||
| 689 | */ | ||
| 690 | |||
| 691 | /* | ||
| 692 | * If the port is not enabled, then exit | ||
| 693 | */ | ||
| 694 | if (test_bit(TTY_IO_ERROR, &tty->flags)) { | ||
| 695 | /* there was an error in opening the tty */ | ||
| 696 | if (un->un_flag & UN_CALLOUT_ACTIVE) | ||
| 697 | retval = -EBUSY; | ||
| 698 | else | ||
| 699 | un->un_flag |= UN_NORMAL_ACTIVE; | ||
| 700 | goto unlock; | ||
| 701 | } | ||
| 702 | |||
| 703 | if (file->f_flags & O_NONBLOCK) { | ||
| 704 | |||
| 705 | /* | ||
| 706 | * if the O_NONBLOCK is set, errors on read and write | ||
| 707 | * must return -EAGAIN immediately and NOT sleep | ||
| 708 | * on the waitqs. | ||
| 709 | */ | ||
| 710 | otype = OTYPE_IMMEDIATE; | ||
| 711 | delay_error = -EAGAIN; | ||
| 712 | |||
| 713 | } else if (!OPEN_WAIT_AVAIL(category) || | ||
| 714 | (file->f_flags & O_NDELAY) != 0) { | ||
| 715 | otype = OTYPE_IMMEDIATE; | ||
| 716 | delay_error = -EBUSY; | ||
| 717 | |||
| 718 | } else if (!OPEN_WAIT_CARRIER(category) || | ||
| 719 | ((ch->ch_digi.digi_flags & DIGI_FORCEDCD) != 0) || | ||
| 720 | C_CLOCAL(tty)) { | ||
| 721 | otype = OTYPE_PERSISTENT; | ||
| 722 | delay_error = 0; | ||
| 723 | |||
| 724 | } else { | ||
| 725 | otype = OTYPE_INCOMING; | ||
| 726 | delay_error = 0; | ||
| 727 | } | ||
| 728 | |||
| 729 | /* | ||
| 730 | * Handle port currently outside physical port range. | ||
| 731 | */ | ||
| 732 | |||
| 733 | if (port >= nd->nd_chan_count) { | ||
| 734 | if (otype == OTYPE_IMMEDIATE) { | ||
| 735 | retval = (nd->nd_state == NS_READY) ? | ||
| 736 | -ENXIO : -EAGAIN; | ||
| 737 | goto unlock; | ||
| 738 | } | ||
| 739 | } | ||
| 740 | |||
| 741 | /* | ||
| 742 | * Handle port not currently open. | ||
| 743 | */ | ||
| 744 | |||
| 745 | else if (ch->ch_open_count == 0) { | ||
| 746 | /* | ||
| 747 | * Return an error when an Incoming Open | ||
| 748 | * response indicates the port is busy. | ||
| 749 | */ | ||
| 750 | |||
| 751 | if (ch->ch_open_error != 0 && otype == ch->ch_otype) { | ||
| 752 | retval = (ch->ch_open_error <= 2) ? | ||
| 753 | delay_error : -ENXIO ; | ||
| 754 | goto unlock; | ||
| 755 | } | ||
| 756 | |||
| 757 | /* | ||
| 758 | * Fail any new Immediate open if we do not have | ||
| 759 | * a normal connection to the server. | ||
| 760 | */ | ||
| 761 | |||
| 762 | if (nd->nd_state != NS_READY && | ||
| 763 | otype == OTYPE_IMMEDIATE) { | ||
| 764 | retval = -EAGAIN; | ||
| 765 | goto unlock; | ||
| 766 | } | ||
| 767 | |||
| 768 | /* | ||
| 769 | * If a Realport open of the correct type has | ||
| 770 | * succeeded, complete the open. | ||
| 771 | */ | ||
| 772 | |||
| 773 | if (ch->ch_state == CS_READY && ch->ch_otype == otype) | ||
| 774 | break; | ||
| 775 | } | ||
| 776 | |||
| 777 | /* | ||
| 778 | * Handle port already open and active as a device | ||
| 779 | * of same category. | ||
| 780 | */ | ||
| 781 | |||
| 782 | else if ((ch->ch_category == category) || | ||
| 783 | IS_PRINT(MINOR(tty_devnum(tty)))) { | ||
| 784 | /* | ||
| 785 | * Fail if opening the device now would | ||
| 786 | * violate exclusive use. | ||
| 787 | */ | ||
| 788 | unf = ch->ch_tun.un_flag | ch->ch_pun.un_flag; | ||
| 789 | |||
| 790 | if ((file->f_flags & O_EXCL) || (unf & UN_EXCL)) { | ||
| 791 | retval = -EBUSY; | ||
| 792 | goto unlock; | ||
| 793 | } | ||
| 794 | |||
| 795 | /* | ||
| 796 | * If the open device is in the hangup state, all | ||
| 797 | * system calls fail except close(). | ||
| 798 | */ | ||
| 799 | |||
| 800 | /* TODO : check on hangup_p calls */ | ||
| 801 | |||
| 802 | if (ch->ch_flag & CH_HANGUP) { | ||
| 803 | retval = -ENXIO; | ||
| 804 | goto unlock; | ||
| 805 | } | ||
| 806 | |||
| 807 | /* | ||
| 808 | * If the port is ready, and carrier is ignored | ||
| 809 | * or present, then complete the open. | ||
| 810 | */ | ||
| 811 | |||
| 812 | if (ch->ch_state == CS_READY && | ||
| 813 | (otype != OTYPE_INCOMING || | ||
| 814 | ch->ch_flag & CH_VIRT_CD)) | ||
| 815 | break; | ||
| 816 | |||
| 817 | wait_carrier = 1; | ||
| 818 | } | ||
| 819 | |||
| 820 | /* | ||
| 821 | * Handle port active with a different category device. | ||
| 822 | */ | ||
| 823 | |||
| 824 | else { | ||
| 825 | if (otype == OTYPE_IMMEDIATE) { | ||
| 826 | retval = delay_error; | ||
| 827 | goto unlock; | ||
| 828 | } | ||
| 829 | } | ||
| 830 | |||
| 831 | /* | ||
| 832 | * Wait until conditions change, then take another | ||
| 833 | * try at the open. | ||
| 834 | */ | ||
| 835 | |||
| 836 | ch->ch_wait_count[otype]++; | ||
| 837 | |||
| 838 | if (wait_carrier) | ||
| 839 | ch->ch_wait_carrier++; | ||
| 840 | |||
| 841 | /* | ||
| 842 | * Prepare the task to accept the wakeup, then | ||
| 843 | * release our locks and release control. | ||
| 844 | */ | ||
| 845 | |||
| 846 | add_wait_queue(&ch->ch_flag_wait, &wait); | ||
| 847 | current->state = TASK_INTERRUPTIBLE; | ||
| 848 | |||
| 849 | spin_unlock_irqrestore(&nd->nd_lock, lock_flags); | ||
| 850 | |||
| 851 | /* | ||
| 852 | * Give up control, we'll come back if we're | ||
| 853 | * interrupted or are woken up. | ||
| 854 | */ | ||
| 855 | schedule(); | ||
| 856 | remove_wait_queue(&ch->ch_flag_wait, &wait); | ||
| 857 | |||
| 858 | spin_lock_irqsave(&nd->nd_lock, lock_flags); | ||
| 859 | |||
| 860 | current->state = TASK_RUNNING; | ||
| 861 | |||
| 862 | ch->ch_wait_count[otype]--; | ||
| 863 | |||
| 864 | if (wait_carrier) | ||
| 865 | ch->ch_wait_carrier--; | ||
| 866 | |||
| 867 | nd->nd_tx_work = 1; | ||
| 868 | |||
| 869 | if (signal_pending(current)) { | ||
| 870 | retval = -EINTR; | ||
| 871 | goto unlock; | ||
| 872 | } | ||
| 873 | } /* end for(;;) */ | ||
| 874 | |||
| 875 | /* | ||
| 876 | * The open has succeeded. No turning back. | ||
| 877 | */ | ||
| 878 | counts_were_incremented = 1; | ||
| 879 | un->un_open_count++; | ||
| 880 | ch->ch_open_count++; | ||
| 881 | |||
| 882 | /* | ||
| 883 | * Initialize the channel, if it's not already open. | ||
| 884 | */ | ||
| 885 | |||
| 886 | if (ch->ch_open_count == 1) { | ||
| 887 | ch->ch_flag = 0; | ||
| 888 | ch->ch_inwait = 0; | ||
| 889 | ch->ch_category = category; | ||
| 890 | ch->ch_pscan_state = 0; | ||
| 891 | |||
| 892 | /* TODO : find out what PS-1 bug Gene was referring to */ | ||
| 893 | /* TODO : in the following comment. */ | ||
| 894 | |||
| 895 | ch->ch_send = RR_TX_START | RR_RX_START; /* PS-1 bug */ | ||
| 896 | |||
| 897 | if (C_CLOCAL(tty) || | ||
| 898 | ch->ch_s_mlast & DM_CD || | ||
| 899 | ch->ch_digi.digi_flags & DIGI_FORCEDCD) | ||
| 900 | ch->ch_flag |= CH_VIRT_CD; | ||
| 901 | else if (OPEN_FORCES_CARRIER(category)) | ||
| 902 | ch->ch_flag |= CH_VIRT_CD; | ||
| 903 | |||
| 904 | } | ||
| 905 | |||
| 906 | /* | ||
| 907 | * Initialize the unit, if it is not already open. | ||
| 908 | */ | ||
| 909 | |||
| 910 | if (un->un_open_count == 1) { | ||
| 911 | /* | ||
| 912 | * Since all terminal options are always sticky in Linux, | ||
| 913 | * we don't need the UN_STICKY flag to be handled specially. | ||
| 914 | */ | ||
| 915 | /* clears all the digi flags, leaves serial flags */ | ||
| 916 | un->un_flag &= ~UN_DIGI_MASK; | ||
| 917 | |||
| 918 | if (file->f_flags & O_EXCL) | ||
| 919 | un->un_flag |= UN_EXCL; | ||
| 920 | |||
| 921 | /* TODO : include "session" and "pgrp" */ | ||
| 922 | |||
| 923 | /* | ||
| 924 | * In Linux, all terminal parameters are intended to be sticky. | ||
| 925 | * as a result, we "remove" the code which once reset the ports | ||
| 926 | * to sane values. | ||
| 927 | */ | ||
| 928 | |||
| 929 | drp_param(ch); | ||
| 930 | |||
| 931 | } | ||
| 932 | |||
| 933 | un->un_flag |= UN_INITIALIZED; | ||
| 934 | |||
| 935 | retval = 0; | ||
| 936 | |||
| 937 | unlock: | ||
| 938 | |||
| 939 | spin_unlock_irqrestore(&nd->nd_lock, lock_flags); | ||
| 940 | |||
| 941 | done: | ||
| 942 | /* | ||
| 943 | * Linux does a close for every open, even failed ones! | ||
| 944 | */ | ||
| 945 | if (!counts_were_incremented) { | ||
| 946 | un->un_open_count++; | ||
| 947 | ch->ch_open_count++; | ||
| 948 | } | ||
| 949 | |||
| 950 | if (retval) | ||
| 951 | dev_err(tty->dev, "tty open bad return (%i)\n", retval); | ||
| 952 | |||
| 953 | return retval; | ||
| 954 | } | ||
| 955 | |||
| 956 | |||
| 957 | |||
| 958 | |||
| 959 | /* | ||
| 960 | * dgrp_tty_close() -- close function for tty_operations | ||
| 961 | */ | ||
| 962 | static void dgrp_tty_close(struct tty_struct *tty, struct file *file) | ||
| 963 | { | ||
| 964 | struct ch_struct *ch; | ||
| 965 | struct un_struct *un; | ||
| 966 | struct nd_struct *nd; | ||
| 967 | int tpos; | ||
| 968 | int port; | ||
| 969 | int err = 0; | ||
| 970 | int s = 0; | ||
| 971 | ulong waketime; | ||
| 972 | ulong lock_flags; | ||
| 973 | int sent_printer_offstr = 0; | ||
| 974 | |||
| 975 | port = PORT_NUM(MINOR(tty_devnum(tty))); | ||
| 976 | |||
| 977 | un = tty->driver_data; | ||
| 978 | |||
| 979 | if (!un) | ||
| 980 | return; | ||
| 981 | |||
| 982 | ch = un->un_ch; | ||
| 983 | |||
| 984 | if (!ch) | ||
| 985 | return; | ||
| 986 | |||
| 987 | nd = ch->ch_nd; | ||
| 988 | |||
| 989 | if (!nd) | ||
| 990 | return; | ||
| 991 | |||
| 992 | spin_lock_irqsave(&nd->nd_lock, lock_flags); | ||
| 993 | |||
| 994 | |||
| 995 | /* Used to be on channel basis, now we check on a unit basis. */ | ||
| 996 | if (un->un_open_count != 1) | ||
| 997 | goto unlock; | ||
| 998 | |||
| 999 | /* | ||
| 1000 | * OK, its the last close on the unit | ||
| 1001 | */ | ||
| 1002 | un->un_flag |= UN_CLOSING; | ||
| 1003 | |||
| 1004 | /* | ||
| 1005 | * Notify the discipline to only process XON/XOFF characters. | ||
| 1006 | */ | ||
| 1007 | tty->closing = 1; | ||
| 1008 | |||
| 1009 | /* | ||
| 1010 | * Wait for output to drain only if this is | ||
| 1011 | * the last close against the channel | ||
| 1012 | */ | ||
| 1013 | |||
| 1014 | if (ch->ch_open_count == 1) { | ||
| 1015 | /* | ||
| 1016 | * If its the print device, we need to ensure at all costs that | ||
| 1017 | * the offstr will fit. If it won't, flush our tbuf. | ||
| 1018 | */ | ||
| 1019 | if (IS_PRINT(MINOR(tty_devnum(tty))) && | ||
| 1020 | (((ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK) < | ||
| 1021 | ch->ch_digi.digi_offlen)) | ||
| 1022 | ch->ch_tin = ch->ch_tout; | ||
| 1023 | |||
| 1024 | /* | ||
| 1025 | * Turn off the printer. Don't bother checking to see if its | ||
| 1026 | * IS_PRINT... Since this is the last close the flag is going | ||
| 1027 | * to be cleared, so we MUST make sure the offstr gets inserted | ||
| 1028 | * into tbuf. | ||
| 1029 | */ | ||
| 1030 | |||
| 1031 | if ((ch->ch_flag & CH_PRON) != 0) { | ||
| 1032 | drp_wmove(ch, 0, ch->ch_digi.digi_offstr, | ||
| 1033 | ch->ch_digi.digi_offlen); | ||
| 1034 | ch->ch_flag &= ~CH_PRON; | ||
| 1035 | sent_printer_offstr = 1; | ||
| 1036 | } | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | /* | ||
| 1040 | * Wait until either the output queue has drained, or we see | ||
| 1041 | * absolutely no progress for 15 seconds. | ||
| 1042 | */ | ||
| 1043 | |||
| 1044 | tpos = ch->ch_s_tpos; | ||
| 1045 | |||
| 1046 | waketime = jiffies + 15 * HZ; | ||
| 1047 | |||
| 1048 | for (;;) { | ||
| 1049 | |||
| 1050 | /* | ||
| 1051 | * Make sure the port still exists. | ||
| 1052 | */ | ||
| 1053 | |||
| 1054 | if (port >= nd->nd_chan_count) { | ||
| 1055 | err = 1; | ||
| 1056 | break; | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | if (signal_pending(current)) { | ||
| 1060 | err = 1; | ||
| 1061 | break; | ||
| 1062 | } | ||
| 1063 | |||
| 1064 | /* | ||
| 1065 | * If the port is idle (not opened on the server), we have | ||
| 1066 | * no way of draining/flushing/closing the port on that server. | ||
| 1067 | * So break out of loop. | ||
| 1068 | */ | ||
| 1069 | if (ch->ch_state == CS_IDLE) | ||
| 1070 | break; | ||
| 1071 | |||
| 1072 | nd->nd_tx_work = 1; | ||
| 1073 | |||
| 1074 | /* | ||
| 1075 | * Exit if the queues for this unit are empty, | ||
| 1076 | * and either the other unit is still open or all | ||
| 1077 | * data has drained. | ||
| 1078 | */ | ||
| 1079 | |||
| 1080 | if ((un->un_tty)->ops->chars_in_buffer ? | ||
| 1081 | ((un->un_tty)->ops->chars_in_buffer)(un->un_tty) == 0 : 1) { | ||
| 1082 | |||
| 1083 | /* | ||
| 1084 | * We don't need to wait for a buffer to drain | ||
| 1085 | * if the other unit is open. | ||
| 1086 | */ | ||
| 1087 | |||
| 1088 | if (ch->ch_open_count != un->un_open_count) | ||
| 1089 | break; | ||
| 1090 | |||
| 1091 | /* | ||
| 1092 | * The wait is complete when all queues are | ||
| 1093 | * drained, and any break in progress is complete. | ||
| 1094 | */ | ||
| 1095 | |||
| 1096 | if (ch->ch_tin == ch->ch_tout && | ||
| 1097 | ch->ch_s_tin == ch->ch_s_tpos && | ||
| 1098 | (ch->ch_send & RR_TX_BREAK) == 0) { | ||
| 1099 | break; | ||
| 1100 | } | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | /* | ||
| 1104 | * Flush TX data and exit the wait if NDELAY is set, | ||
| 1105 | * or this is not a DIGI printer, and the close timeout | ||
| 1106 | * expires. | ||
| 1107 | */ | ||
| 1108 | |||
| 1109 | if ((file->f_flags & (O_NDELAY | O_NONBLOCK)) || | ||
| 1110 | ((long)(jiffies - waketime) >= 0 && | ||
| 1111 | (ch->ch_digi.digi_flags & DIGI_PRINTER) == 0)) { | ||
| 1112 | |||
| 1113 | /* | ||
| 1114 | * If we sent the printer off string, we cannot | ||
| 1115 | * flush our internal buffers, or we might lose | ||
| 1116 | * the offstr. | ||
| 1117 | */ | ||
| 1118 | if (!sent_printer_offstr) | ||
| 1119 | dgrp_tty_flush_buffer(tty); | ||
| 1120 | |||
| 1121 | tty_ldisc_flush(tty); | ||
| 1122 | break; | ||
| 1123 | } | ||
| 1124 | |||
| 1125 | /* | ||
| 1126 | * Otherwise take a short nap. | ||
| 1127 | */ | ||
| 1128 | |||
| 1129 | ch->ch_flag |= CH_DRAIN; | ||
| 1130 | |||
| 1131 | spin_unlock_irqrestore(&nd->nd_lock, lock_flags); | ||
| 1132 | |||
| 1133 | schedule_timeout_interruptible(1); | ||
| 1134 | s = signal_pending(current); | ||
| 1135 | |||
| 1136 | spin_lock_irqsave(&nd->nd_lock, lock_flags); | ||
| 1137 | |||
| 1138 | if (s) { | ||
| 1139 | /* | ||
| 1140 | * If we had sent the printer off string, we now have | ||
| 1141 | * some problems. | ||
| 1142 | * | ||
| 1143 | * The system won't let us sleep since we got an error | ||
| 1144 | * back from sleep, presumably because the user did | ||
| 1145 | * a ctrl-c... | ||
| 1146 | * But we need to ensure that the offstr gets sent! | ||
| 1147 | * Thus, we have to do something else besides sleeping. | ||
| 1148 | * The plan: | ||
| 1149 | * 1) Make this task uninterruptable. | ||
| 1150 | * 2) Set up a timer to go off in 1 sec. | ||
| 1151 | * 3) Act as tho we just got out of the sleep above. | ||
| 1152 | * | ||
| 1153 | * Thankfully, in the real world, this just | ||
| 1154 | * never happens. | ||
| 1155 | */ | ||
| 1156 | |||
| 1157 | if (sent_printer_offstr) { | ||
| 1158 | spin_unlock_irqrestore(&nd->nd_lock, | ||
| 1159 | lock_flags); | ||
| 1160 | drp_my_sleep(ch); | ||
| 1161 | spin_lock_irqsave(&nd->nd_lock, lock_flags); | ||
| 1162 | } else { | ||
| 1163 | err = 1; | ||
| 1164 | break; | ||
| 1165 | } | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | /* | ||
| 1169 | * Restart the wait if any progress is seen. | ||
| 1170 | */ | ||
| 1171 | |||
| 1172 | if (ch->ch_s_tpos != tpos) { | ||
| 1173 | tpos = ch->ch_s_tpos; | ||
| 1174 | |||
| 1175 | /* TODO: this gives us timeout problems with nist ?? */ | ||
| 1176 | waketime = jiffies + 15 * HZ; | ||
| 1177 | } | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | /* | ||
| 1181 | * Close the line discipline | ||
| 1182 | */ | ||
| 1183 | |||
| 1184 | /* this is done in tty_io.c */ | ||
| 1185 | /* if ((un->un_tty)->ldisc.close) | ||
| 1186 | * ((un->un_tty)->ldisc.close)(un->un_tty); | ||
| 1187 | */ | ||
| 1188 | |||
| 1189 | /* don't do this here */ | ||
| 1190 | /* un->un_flag = 0; */ | ||
| 1191 | |||
| 1192 | /* | ||
| 1193 | * Flush the receive buffer on terminal unit close only. | ||
| 1194 | */ | ||
| 1195 | |||
| 1196 | if (!IS_PRINT(MINOR(tty_devnum(tty)))) | ||
| 1197 | ch->ch_rout = ch->ch_rin; | ||
| 1198 | |||
| 1199 | |||
| 1200 | /* | ||
| 1201 | * Don't permit the close to happen until we get any pending | ||
| 1202 | * sync request responses. | ||
| 1203 | * There could be other ports depending upon the response as well. | ||
| 1204 | * | ||
| 1205 | * Also, don't permit the close to happen until any parameter | ||
| 1206 | * changes have been sent out from the state machine as well. | ||
| 1207 | * This is required because of a ditty -a race with -HUPCL | ||
| 1208 | * We MUST make sure all channel parameters have been sent to the | ||
| 1209 | * Portserver before sending a close. | ||
| 1210 | */ | ||
| 1211 | |||
| 1212 | if ((err != 1) && (ch->ch_state != CS_IDLE)) { | ||
| 1213 | spin_unlock_irqrestore(&nd->nd_lock, lock_flags); | ||
| 1214 | s = wait_event_interruptible(ch->ch_flag_wait, | ||
| 1215 | ((ch->ch_flag & (CH_WAITING_SYNC | CH_PARAM)) == 0)); | ||
| 1216 | spin_lock_irqsave(&nd->nd_lock, lock_flags); | ||
| 1217 | } | ||
| 1218 | |||
| 1219 | /* | ||
| 1220 | * Cleanup the channel if last unit open. | ||
| 1221 | */ | ||
| 1222 | |||
| 1223 | if (ch->ch_open_count == 1) { | ||
| 1224 | ch->ch_flag = 0; | ||
| 1225 | ch->ch_category = 0; | ||
| 1226 | ch->ch_send = 0; | ||
| 1227 | ch->ch_expect = 0; | ||
| 1228 | ch->ch_tout = ch->ch_tin; | ||
| 1229 | /* (un->un_tty)->device = 0; */ | ||
| 1230 | |||
| 1231 | if (ch->ch_state == CS_READY) | ||
| 1232 | ch->ch_state = CS_SEND_CLOSE; | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | /* | ||
| 1236 | * Send the changes to the server | ||
| 1237 | */ | ||
| 1238 | if (ch->ch_state != CS_IDLE) { | ||
| 1239 | ch->ch_flag |= CH_PARAM; | ||
| 1240 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 1241 | } | ||
| 1242 | |||
| 1243 | nd->nd_tx_work = 1; | ||
| 1244 | nd->nd_tx_ready = 1; | ||
| 1245 | |||
| 1246 | unlock: | ||
| 1247 | tty->closing = 0; | ||
| 1248 | |||
| 1249 | if (ch->ch_open_count <= 0) | ||
| 1250 | dev_info(tty->dev, | ||
| 1251 | "%s - unexpected value for ch->ch_open_count: %i\n", | ||
| 1252 | __func__, ch->ch_open_count); | ||
| 1253 | else | ||
| 1254 | ch->ch_open_count--; | ||
| 1255 | |||
| 1256 | if (un->un_open_count <= 0) | ||
| 1257 | dev_info(tty->dev, | ||
| 1258 | "%s - unexpected value for un->un_open_count: %i\n", | ||
| 1259 | __func__, un->un_open_count); | ||
| 1260 | else | ||
| 1261 | un->un_open_count--; | ||
| 1262 | |||
| 1263 | un->un_flag &= ~(UN_NORMAL_ACTIVE | UN_CALLOUT_ACTIVE | UN_CLOSING); | ||
| 1264 | if (waitqueue_active(&un->un_close_wait)) | ||
| 1265 | wake_up_interruptible(&un->un_close_wait); | ||
| 1266 | |||
| 1267 | spin_unlock_irqrestore(&nd->nd_lock, lock_flags); | ||
| 1268 | |||
| 1269 | return; | ||
| 1270 | |||
| 1271 | } | ||
| 1272 | |||
| 1273 | static void drp_wmove(struct ch_struct *ch, int from_user, void *buf, int count) | ||
| 1274 | { | ||
| 1275 | int n; | ||
| 1276 | int ret = 0; | ||
| 1277 | |||
| 1278 | ch->ch_nd->nd_tx_work = 1; | ||
| 1279 | |||
| 1280 | n = TBUF_MAX - ch->ch_tin; | ||
| 1281 | |||
| 1282 | if (count >= n) { | ||
| 1283 | if (from_user) | ||
| 1284 | ret = copy_from_user(ch->ch_tbuf + ch->ch_tin, | ||
| 1285 | (void __user *) buf, n); | ||
| 1286 | else | ||
| 1287 | memcpy(ch->ch_tbuf + ch->ch_tin, buf, n); | ||
| 1288 | |||
| 1289 | buf = (char *) buf + n; | ||
| 1290 | count -= n; | ||
| 1291 | ch->ch_tin = 0; | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | if (from_user) | ||
| 1295 | ret = copy_from_user(ch->ch_tbuf + ch->ch_tin, | ||
| 1296 | (void __user *) buf, count); | ||
| 1297 | else | ||
| 1298 | memcpy(ch->ch_tbuf + ch->ch_tin, buf, count); | ||
| 1299 | |||
| 1300 | ch->ch_tin += count; | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | |||
| 1304 | static int dgrp_calculate_txprint_bounds(struct ch_struct *ch, int space, | ||
| 1305 | int *un_flag) | ||
| 1306 | { | ||
| 1307 | clock_t tt; | ||
| 1308 | clock_t mt; | ||
| 1309 | unsigned short tmax = 0; | ||
| 1310 | |||
| 1311 | /* | ||
| 1312 | * If the terminal device is busy, reschedule when | ||
| 1313 | * the terminal device becomes idle. | ||
| 1314 | */ | ||
| 1315 | |||
| 1316 | if (ch->ch_tun.un_open_count != 0 && | ||
| 1317 | ch->ch_tun.un_tty->ops->chars_in_buffer && | ||
| 1318 | ((ch->ch_tun.un_tty->ops->chars_in_buffer)(ch->ch_tun.un_tty) != 0)) { | ||
| 1319 | *un_flag = UN_PWAIT; | ||
| 1320 | return 0; | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | /* | ||
| 1324 | * Assure that whenever there is printer data in the output | ||
| 1325 | * buffer, there always remains enough space after it to | ||
| 1326 | * turn the printer off. | ||
| 1327 | */ | ||
| 1328 | space -= ch->ch_digi.digi_offlen; | ||
| 1329 | |||
| 1330 | if (space <= 0) { | ||
| 1331 | *un_flag = UN_EMPTY; | ||
| 1332 | return 0; | ||
| 1333 | } | ||
| 1334 | |||
| 1335 | /* | ||
| 1336 | * We measure printer CPS speed by incrementing | ||
| 1337 | * ch_cpstime by (HZ / digi_maxcps) for every | ||
| 1338 | * character we output, restricting output so | ||
| 1339 | * that ch_cpstime never exceeds lbolt. | ||
| 1340 | * | ||
| 1341 | * However if output has not been done for some | ||
| 1342 | * time, lbolt will grow to very much larger than | ||
| 1343 | * ch_cpstime, which would allow essentially | ||
| 1344 | * unlimited amounts of output until ch_cpstime | ||
| 1345 | * finally caught up. To avoid this, we adjust | ||
| 1346 | * cps_time when necessary so the difference | ||
| 1347 | * between lbolt and ch_cpstime never results | ||
| 1348 | * in sending more than digi_bufsize characters. | ||
| 1349 | * | ||
| 1350 | * This nicely models a printer with an internal | ||
| 1351 | * buffer of digi_bufsize characters. | ||
| 1352 | * | ||
| 1353 | * Get the time between lbolt and ch->ch_cpstime; | ||
| 1354 | */ | ||
| 1355 | |||
| 1356 | tt = jiffies - ch->ch_cpstime; | ||
| 1357 | |||
| 1358 | /* | ||
| 1359 | * Compute the time required to send digi_bufsize | ||
| 1360 | * characters. | ||
| 1361 | */ | ||
| 1362 | |||
| 1363 | mt = HZ * ch->ch_digi.digi_bufsize / ch->ch_digi.digi_maxcps; | ||
| 1364 | |||
| 1365 | /* | ||
| 1366 | * Compute the number of characters that can be sent | ||
| 1367 | * without violating the time constraint. If the | ||
| 1368 | * direct calculation of this number is bigger than | ||
| 1369 | * digi_bufsize, limit the number to digi_bufsize, | ||
| 1370 | * and adjust cpstime to match. | ||
| 1371 | */ | ||
| 1372 | |||
| 1373 | if ((clock_t)(tt + HZ) > (clock_t)(mt + HZ)) { | ||
| 1374 | tmax = ch->ch_digi.digi_bufsize; | ||
| 1375 | ch->ch_cpstime = jiffies - mt; | ||
| 1376 | } else { | ||
| 1377 | tmax = ch->ch_digi.digi_maxcps * tt / HZ; | ||
| 1378 | } | ||
| 1379 | |||
| 1380 | /* | ||
| 1381 | * If the time constraint now binds, limit the transmit | ||
| 1382 | * count accordingly, and tentatively arrange to be | ||
| 1383 | * rescheduled based on time. | ||
| 1384 | */ | ||
| 1385 | |||
| 1386 | if (tmax < space) { | ||
| 1387 | *un_flag = UN_TIME; | ||
| 1388 | space = tmax; | ||
| 1389 | } | ||
| 1390 | |||
| 1391 | /* | ||
| 1392 | * Compute the total number of characters we can | ||
| 1393 | * output before the total number of characters known | ||
| 1394 | * to be in the output queue exceeds digi_maxchar. | ||
| 1395 | */ | ||
| 1396 | |||
| 1397 | tmax = (ch->ch_digi.digi_maxchar - | ||
| 1398 | ((ch->ch_tin - ch->ch_tout) & TBUF_MASK) - | ||
| 1399 | ((ch->ch_s_tin - ch->ch_s_tpos) & 0xffff)); | ||
| 1400 | |||
| 1401 | |||
| 1402 | /* | ||
| 1403 | * If the digi_maxchar constraint now holds, limit | ||
| 1404 | * the transmit count accordingly, and arrange to | ||
| 1405 | * be rescheduled when the queue becomes empty. | ||
| 1406 | */ | ||
| 1407 | |||
| 1408 | if (space > tmax) { | ||
| 1409 | *un_flag = UN_EMPTY; | ||
| 1410 | space = tmax; | ||
| 1411 | } | ||
| 1412 | |||
| 1413 | if (space <= 0) | ||
| 1414 | *un_flag |= UN_EMPTY; | ||
| 1415 | |||
| 1416 | return space; | ||
| 1417 | } | ||
| 1418 | |||
| 1419 | |||
| 1420 | static int dgrp_tty_write(struct tty_struct *tty, | ||
| 1421 | const unsigned char *buf, | ||
| 1422 | int count) | ||
| 1423 | { | ||
| 1424 | struct nd_struct *nd; | ||
| 1425 | struct un_struct *un; | ||
| 1426 | struct ch_struct *ch; | ||
| 1427 | int space; | ||
| 1428 | int n; | ||
| 1429 | int t; | ||
| 1430 | int sendcount; | ||
| 1431 | int un_flag; | ||
| 1432 | ulong lock_flags; | ||
| 1433 | |||
| 1434 | if (tty == NULL) | ||
| 1435 | return 0; | ||
| 1436 | |||
| 1437 | un = tty->driver_data; | ||
| 1438 | if (!un) | ||
| 1439 | return 0; | ||
| 1440 | |||
| 1441 | ch = un->un_ch; | ||
| 1442 | if (!ch) | ||
| 1443 | return 0; | ||
| 1444 | |||
| 1445 | nd = ch->ch_nd; | ||
| 1446 | if (!nd) | ||
| 1447 | return 0; | ||
| 1448 | |||
| 1449 | /* | ||
| 1450 | * Ignore the request if the channel is not ready. | ||
| 1451 | */ | ||
| 1452 | if (ch->ch_state != CS_READY) | ||
| 1453 | return 0; | ||
| 1454 | |||
| 1455 | spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags); | ||
| 1456 | |||
| 1457 | /* | ||
| 1458 | * Ignore the request if output is blocked. | ||
| 1459 | */ | ||
| 1460 | if ((un->un_flag & (UN_EMPTY | UN_LOW | UN_TIME | UN_PWAIT)) != 0) { | ||
| 1461 | count = 0; | ||
| 1462 | goto out; | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | /* | ||
| 1466 | * Also ignore the request if DPA has this port open, | ||
| 1467 | * and is flow controlled on reading more data. | ||
| 1468 | */ | ||
| 1469 | if (nd->nd_dpa_debug && nd->nd_dpa_flag & DPA_WAIT_SPACE && | ||
| 1470 | nd->nd_dpa_port == MINOR(tty_devnum(ch->ch_tun.un_tty))) { | ||
| 1471 | count = 0; | ||
| 1472 | goto out; | ||
| 1473 | } | ||
| 1474 | |||
| 1475 | /* | ||
| 1476 | * Limit amount we will write to the amount of space | ||
| 1477 | * available in the channel buffer. | ||
| 1478 | */ | ||
| 1479 | sendcount = 0; | ||
| 1480 | |||
| 1481 | space = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK; | ||
| 1482 | |||
| 1483 | /* | ||
| 1484 | * Handle the printer device. | ||
| 1485 | */ | ||
| 1486 | |||
| 1487 | un_flag = UN_LOW; | ||
| 1488 | |||
| 1489 | if (IS_PRINT(MINOR(tty_devnum(tty)))) { | ||
| 1490 | clock_t tt; | ||
| 1491 | clock_t mt; | ||
| 1492 | unsigned short tmax = 0; | ||
| 1493 | |||
| 1494 | /* | ||
| 1495 | * If the terminal device is busy, reschedule when | ||
| 1496 | * the terminal device becomes idle. | ||
| 1497 | */ | ||
| 1498 | |||
| 1499 | if (ch->ch_tun.un_open_count != 0 && | ||
| 1500 | ((ch->ch_tun.un_tty->ops->chars_in_buffer)(ch->ch_tun.un_tty) != 0)) { | ||
| 1501 | un->un_flag |= UN_PWAIT; | ||
| 1502 | count = 0; | ||
| 1503 | goto out; | ||
| 1504 | } | ||
| 1505 | |||
| 1506 | /* | ||
| 1507 | * Assure that whenever there is printer data in the output | ||
| 1508 | * buffer, there always remains enough space after it to | ||
| 1509 | * turn the printer off. | ||
| 1510 | */ | ||
| 1511 | space -= ch->ch_digi.digi_offlen; | ||
| 1512 | |||
| 1513 | /* | ||
| 1514 | * Output the printer on string. | ||
| 1515 | */ | ||
| 1516 | |||
| 1517 | if ((ch->ch_flag & CH_PRON) == 0) { | ||
| 1518 | space -= ch->ch_digi.digi_onlen; | ||
| 1519 | |||
| 1520 | if (space < 0) { | ||
| 1521 | un->un_flag |= UN_EMPTY; | ||
| 1522 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 1523 | count = 0; | ||
| 1524 | goto out; | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | drp_wmove(ch, 0, ch->ch_digi.digi_onstr, | ||
| 1528 | ch->ch_digi.digi_onlen); | ||
| 1529 | |||
| 1530 | ch->ch_flag |= CH_PRON; | ||
| 1531 | } | ||
| 1532 | |||
| 1533 | /* | ||
| 1534 | * We measure printer CPS speed by incrementing | ||
| 1535 | * ch_cpstime by (HZ / digi_maxcps) for every | ||
| 1536 | * character we output, restricting output so | ||
| 1537 | * that ch_cpstime never exceeds lbolt. | ||
| 1538 | * | ||
| 1539 | * However if output has not been done for some | ||
| 1540 | * time, lbolt will grow to very much larger than | ||
| 1541 | * ch_cpstime, which would allow essentially | ||
| 1542 | * unlimited amounts of output until ch_cpstime | ||
| 1543 | * finally caught up. To avoid this, we adjust | ||
| 1544 | * cps_time when necessary so the difference | ||
| 1545 | * between lbolt and ch_cpstime never results | ||
| 1546 | * in sending more than digi_bufsize characters. | ||
| 1547 | * | ||
| 1548 | * This nicely models a printer with an internal | ||
| 1549 | * buffer of digi_bufsize characters. | ||
| 1550 | * | ||
| 1551 | * Get the time between lbolt and ch->ch_cpstime; | ||
| 1552 | */ | ||
| 1553 | |||
| 1554 | tt = jiffies - ch->ch_cpstime; | ||
| 1555 | |||
| 1556 | /* | ||
| 1557 | * Compute the time required to send digi_bufsize | ||
| 1558 | * characters. | ||
| 1559 | */ | ||
| 1560 | |||
| 1561 | mt = HZ * ch->ch_digi.digi_bufsize / ch->ch_digi.digi_maxcps; | ||
| 1562 | |||
| 1563 | /* | ||
| 1564 | * Compute the number of characters that can be sent | ||
| 1565 | * without violating the time constraint. If the | ||
| 1566 | * direct calculation of this number is bigger than | ||
| 1567 | * digi_bufsize, limit the number to digi_bufsize, | ||
| 1568 | * and adjust cpstime to match. | ||
| 1569 | */ | ||
| 1570 | |||
| 1571 | if ((clock_t)(tt + HZ) > (clock_t)(mt + HZ)) { | ||
| 1572 | tmax = ch->ch_digi.digi_bufsize; | ||
| 1573 | ch->ch_cpstime = jiffies - mt; | ||
| 1574 | } else { | ||
| 1575 | tmax = ch->ch_digi.digi_maxcps * tt / HZ; | ||
| 1576 | } | ||
| 1577 | |||
| 1578 | /* | ||
| 1579 | * If the time constraint now binds, limit the transmit | ||
| 1580 | * count accordingly, and tentatively arrange to be | ||
| 1581 | * rescheduled based on time. | ||
| 1582 | */ | ||
| 1583 | |||
| 1584 | if (tmax < space) { | ||
| 1585 | space = tmax; | ||
| 1586 | un_flag = UN_TIME; | ||
| 1587 | } | ||
| 1588 | |||
| 1589 | /* | ||
| 1590 | * Compute the total number of characters we can | ||
| 1591 | * output before the total number of characters known | ||
| 1592 | * to be in the output queue exceeds digi_maxchar. | ||
| 1593 | */ | ||
| 1594 | |||
| 1595 | tmax = (ch->ch_digi.digi_maxchar - | ||
| 1596 | ((ch->ch_tin - ch->ch_tout) & TBUF_MASK) - | ||
| 1597 | ((ch->ch_s_tin - ch->ch_s_tpos) & 0xffff)); | ||
| 1598 | |||
| 1599 | |||
| 1600 | /* | ||
| 1601 | * If the digi_maxchar constraint now holds, limit | ||
| 1602 | * the transmit count accordingly, and arrange to | ||
| 1603 | * be rescheduled when the queue becomes empty. | ||
| 1604 | */ | ||
| 1605 | |||
| 1606 | if (space > tmax) { | ||
| 1607 | space = tmax; | ||
| 1608 | un_flag = UN_EMPTY; | ||
| 1609 | } | ||
| 1610 | |||
| 1611 | } | ||
| 1612 | /* | ||
| 1613 | * Handle the terminal device. | ||
| 1614 | */ | ||
| 1615 | else { | ||
| 1616 | |||
| 1617 | /* | ||
| 1618 | * If the printer device is on, turn it off. | ||
| 1619 | */ | ||
| 1620 | |||
| 1621 | if ((ch->ch_flag & CH_PRON) != 0) { | ||
| 1622 | |||
| 1623 | space -= ch->ch_digi.digi_offlen; | ||
| 1624 | |||
| 1625 | drp_wmove(ch, 0, ch->ch_digi.digi_offstr, | ||
| 1626 | ch->ch_digi.digi_offlen); | ||
| 1627 | |||
| 1628 | ch->ch_flag &= ~CH_PRON; | ||
| 1629 | } | ||
| 1630 | } | ||
| 1631 | |||
| 1632 | /* | ||
| 1633 | * If space is 0 and its because the ch->tbuf | ||
| 1634 | * is full, then Linux will handle a callback when queue | ||
| 1635 | * space becomes available. | ||
| 1636 | * tty_write returns count = 0 | ||
| 1637 | */ | ||
| 1638 | |||
| 1639 | if (space <= 0) { | ||
| 1640 | /* the linux tty_io.c handles this if we return 0 */ | ||
| 1641 | /* if (fp->flags & O_NONBLOCK) return -EAGAIN; */ | ||
| 1642 | |||
| 1643 | un->un_flag |= UN_EMPTY; | ||
| 1644 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 1645 | count = 0; | ||
| 1646 | goto out; | ||
| 1647 | } | ||
| 1648 | |||
| 1649 | count = min(count, space); | ||
| 1650 | |||
| 1651 | if (count > 0) { | ||
| 1652 | |||
| 1653 | un->un_tbusy++; | ||
| 1654 | |||
| 1655 | /* | ||
| 1656 | * Copy the buffer contents to the ch_tbuf | ||
| 1657 | * being careful to wrap around the circular queue | ||
| 1658 | */ | ||
| 1659 | |||
| 1660 | t = TBUF_MAX - ch->ch_tin; | ||
| 1661 | n = count; | ||
| 1662 | |||
| 1663 | if (n >= t) { | ||
| 1664 | memcpy(ch->ch_tbuf + ch->ch_tin, buf, t); | ||
| 1665 | if (nd->nd_dpa_debug && nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(un->un_tty)))) | ||
| 1666 | dgrp_dpa_data(nd, 0, (char *) buf, t); | ||
| 1667 | buf += t; | ||
| 1668 | n -= t; | ||
| 1669 | ch->ch_tin = 0; | ||
| 1670 | sendcount += n; | ||
| 1671 | } | ||
| 1672 | |||
| 1673 | memcpy(ch->ch_tbuf + ch->ch_tin, buf, n); | ||
| 1674 | if (nd->nd_dpa_debug && nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(un->un_tty)))) | ||
| 1675 | dgrp_dpa_data(nd, 0, (char *) buf, n); | ||
| 1676 | buf += n; | ||
| 1677 | ch->ch_tin += n; | ||
| 1678 | sendcount += n; | ||
| 1679 | |||
| 1680 | un->un_tbusy--; | ||
| 1681 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 1682 | if (ch->ch_edelay != DGRP_RTIME) { | ||
| 1683 | (ch->ch_nd)->nd_tx_ready = 1; | ||
| 1684 | wake_up_interruptible(&nd->nd_tx_waitq); | ||
| 1685 | } | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | ch->ch_txcount += count; | ||
| 1689 | |||
| 1690 | if (IS_PRINT(MINOR(tty_devnum(tty)))) { | ||
| 1691 | |||
| 1692 | /* | ||
| 1693 | * Adjust ch_cpstime to account | ||
| 1694 | * for the characters just output. | ||
| 1695 | */ | ||
| 1696 | |||
| 1697 | if (sendcount > 0) { | ||
| 1698 | int cc = HZ * sendcount + ch->ch_cpsrem; | ||
| 1699 | |||
| 1700 | ch->ch_cpstime += cc / ch->ch_digi.digi_maxcps; | ||
| 1701 | ch->ch_cpsrem = cc % ch->ch_digi.digi_maxcps; | ||
| 1702 | } | ||
| 1703 | |||
| 1704 | /* | ||
| 1705 | * If we are now waiting on time, schedule ourself | ||
| 1706 | * back when we'll be able to send a block of | ||
| 1707 | * digi_maxchar characters. | ||
| 1708 | */ | ||
| 1709 | |||
| 1710 | if ((un_flag & UN_TIME) != 0) { | ||
| 1711 | ch->ch_waketime = (ch->ch_cpstime + | ||
| 1712 | (ch->ch_digi.digi_maxchar * HZ / | ||
| 1713 | ch->ch_digi.digi_maxcps)); | ||
| 1714 | } | ||
| 1715 | } | ||
| 1716 | |||
| 1717 | /* | ||
| 1718 | * If the printer unit is waiting for completion | ||
| 1719 | * of terminal output, get him going again. | ||
| 1720 | */ | ||
| 1721 | |||
| 1722 | if ((ch->ch_pun.un_flag & UN_PWAIT) != 0) | ||
| 1723 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 1724 | |||
| 1725 | out: | ||
| 1726 | spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags); | ||
| 1727 | |||
| 1728 | return count; | ||
| 1729 | } | ||
| 1730 | |||
| 1731 | |||
| 1732 | /* | ||
| 1733 | * Put a character into ch->ch_buf | ||
| 1734 | * | ||
| 1735 | * - used by the line discipline for OPOST processing | ||
| 1736 | */ | ||
| 1737 | |||
| 1738 | static int dgrp_tty_put_char(struct tty_struct *tty, unsigned char new_char) | ||
| 1739 | { | ||
| 1740 | struct un_struct *un; | ||
| 1741 | struct ch_struct *ch; | ||
| 1742 | ulong lock_flags; | ||
| 1743 | int space; | ||
| 1744 | int retval = 0; | ||
| 1745 | |||
| 1746 | if (tty == NULL) | ||
| 1747 | return 0; | ||
| 1748 | |||
| 1749 | un = tty->driver_data; | ||
| 1750 | if (!un) | ||
| 1751 | return 0; | ||
| 1752 | |||
| 1753 | ch = un->un_ch; | ||
| 1754 | if (!ch) | ||
| 1755 | return 0; | ||
| 1756 | |||
| 1757 | if (ch->ch_state != CS_READY) | ||
| 1758 | return 0; | ||
| 1759 | |||
| 1760 | spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags); | ||
| 1761 | |||
| 1762 | |||
| 1763 | /* | ||
| 1764 | * If space is 0 and its because the ch->tbuf | ||
| 1765 | * Warn and dump the character, there isn't anything else | ||
| 1766 | * we can do about it. David_Fries@digi.com | ||
| 1767 | */ | ||
| 1768 | |||
| 1769 | space = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK; | ||
| 1770 | |||
| 1771 | un->un_tbusy++; | ||
| 1772 | |||
| 1773 | /* | ||
| 1774 | * Output the printer on string if device is TXPrint. | ||
| 1775 | */ | ||
| 1776 | if (IS_PRINT(MINOR(tty_devnum(tty))) && (ch->ch_flag & CH_PRON) == 0) { | ||
| 1777 | if (space < ch->ch_digi.digi_onlen) { | ||
| 1778 | un->un_tbusy--; | ||
| 1779 | goto out; | ||
| 1780 | } | ||
| 1781 | space -= ch->ch_digi.digi_onlen; | ||
| 1782 | drp_wmove(ch, 0, ch->ch_digi.digi_onstr, | ||
| 1783 | ch->ch_digi.digi_onlen); | ||
| 1784 | ch->ch_flag |= CH_PRON; | ||
| 1785 | } | ||
| 1786 | |||
| 1787 | /* | ||
| 1788 | * Output the printer off string if device is NOT TXPrint. | ||
| 1789 | */ | ||
| 1790 | |||
| 1791 | if (!IS_PRINT(MINOR(tty_devnum(tty))) && | ||
| 1792 | ((ch->ch_flag & CH_PRON) != 0)) { | ||
| 1793 | if (space < ch->ch_digi.digi_offlen) { | ||
| 1794 | un->un_tbusy--; | ||
| 1795 | goto out; | ||
| 1796 | } | ||
| 1797 | |||
| 1798 | space -= ch->ch_digi.digi_offlen; | ||
| 1799 | drp_wmove(ch, 0, ch->ch_digi.digi_offstr, | ||
| 1800 | ch->ch_digi.digi_offlen); | ||
| 1801 | ch->ch_flag &= ~CH_PRON; | ||
| 1802 | } | ||
| 1803 | |||
| 1804 | if (!space) { | ||
| 1805 | un->un_tbusy--; | ||
| 1806 | goto out; | ||
| 1807 | } | ||
| 1808 | |||
| 1809 | /* | ||
| 1810 | * Copy the character to the ch_tbuf being | ||
| 1811 | * careful to wrap around the circular queue | ||
| 1812 | */ | ||
| 1813 | ch->ch_tbuf[ch->ch_tin] = new_char; | ||
| 1814 | ch->ch_tin = (1 + ch->ch_tin) & TBUF_MASK; | ||
| 1815 | |||
| 1816 | if (IS_PRINT(MINOR(tty_devnum(tty)))) { | ||
| 1817 | |||
| 1818 | /* | ||
| 1819 | * Adjust ch_cpstime to account | ||
| 1820 | * for the character just output. | ||
| 1821 | */ | ||
| 1822 | |||
| 1823 | int cc = HZ + ch->ch_cpsrem; | ||
| 1824 | |||
| 1825 | ch->ch_cpstime += cc / ch->ch_digi.digi_maxcps; | ||
| 1826 | ch->ch_cpsrem = cc % ch->ch_digi.digi_maxcps; | ||
| 1827 | |||
| 1828 | /* | ||
| 1829 | * If we are now waiting on time, schedule ourself | ||
| 1830 | * back when we'll be able to send a block of | ||
| 1831 | * digi_maxchar characters. | ||
| 1832 | */ | ||
| 1833 | |||
| 1834 | ch->ch_waketime = (ch->ch_cpstime + | ||
| 1835 | (ch->ch_digi.digi_maxchar * HZ / | ||
| 1836 | ch->ch_digi.digi_maxcps)); | ||
| 1837 | } | ||
| 1838 | |||
| 1839 | |||
| 1840 | un->un_tbusy--; | ||
| 1841 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 1842 | |||
| 1843 | retval = 1; | ||
| 1844 | out: | ||
| 1845 | spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags); | ||
| 1846 | return retval; | ||
| 1847 | } | ||
| 1848 | |||
| 1849 | |||
| 1850 | |||
| 1851 | /* | ||
| 1852 | * Flush TX buffer (make in == out) | ||
| 1853 | * | ||
| 1854 | * check tty_ioctl.c -- this is called after TCOFLUSH | ||
| 1855 | */ | ||
| 1856 | static void dgrp_tty_flush_buffer(struct tty_struct *tty) | ||
| 1857 | { | ||
| 1858 | struct un_struct *un; | ||
| 1859 | struct ch_struct *ch; | ||
| 1860 | |||
| 1861 | if (!tty) | ||
| 1862 | return; | ||
| 1863 | un = tty->driver_data; | ||
| 1864 | if (!un) | ||
| 1865 | return; | ||
| 1866 | |||
| 1867 | ch = un->un_ch; | ||
| 1868 | if (!ch) | ||
| 1869 | return; | ||
| 1870 | |||
| 1871 | ch->ch_tout = ch->ch_tin; | ||
| 1872 | /* do NOT do this here! */ | ||
| 1873 | /* ch->ch_s_tpos = ch->ch_s_tin = 0; */ | ||
| 1874 | |||
| 1875 | /* send the flush output command now */ | ||
| 1876 | ch->ch_send |= RR_TX_FLUSH; | ||
| 1877 | (ch->ch_nd)->nd_tx_ready = 1; | ||
| 1878 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 1879 | wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq); | ||
| 1880 | |||
| 1881 | if (waitqueue_active(&tty->write_wait)) | ||
| 1882 | wake_up_interruptible(&tty->write_wait); | ||
| 1883 | |||
| 1884 | tty_wakeup(tty); | ||
| 1885 | |||
| 1886 | } | ||
| 1887 | |||
| 1888 | /* | ||
| 1889 | * Return space available in Tx buffer | ||
| 1890 | * count = ( ch->ch_tout - ch->ch_tin ) mod (TBUF_MAX - 1) | ||
| 1891 | */ | ||
| 1892 | static int dgrp_tty_write_room(struct tty_struct *tty) | ||
| 1893 | { | ||
| 1894 | struct un_struct *un; | ||
| 1895 | struct ch_struct *ch; | ||
| 1896 | int count; | ||
| 1897 | |||
| 1898 | if (!tty) | ||
| 1899 | return 0; | ||
| 1900 | |||
| 1901 | un = tty->driver_data; | ||
| 1902 | if (!un) | ||
| 1903 | return 0; | ||
| 1904 | |||
| 1905 | ch = un->un_ch; | ||
| 1906 | if (!ch) | ||
| 1907 | return 0; | ||
| 1908 | |||
| 1909 | count = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK; | ||
| 1910 | |||
| 1911 | /* We *MUST* check this, and return 0 if the Printer Unit cannot | ||
| 1912 | * take any more data within its time constraints... If we don't | ||
| 1913 | * return 0 and the printer has hit it time constraint, the ld will | ||
| 1914 | * call us back doing a put_char, which cannot be rejected!!! | ||
| 1915 | */ | ||
| 1916 | if (IS_PRINT(MINOR(tty_devnum(tty)))) { | ||
| 1917 | int un_flag = 0; | ||
| 1918 | count = dgrp_calculate_txprint_bounds(ch, count, &un_flag); | ||
| 1919 | if (count <= 0) | ||
| 1920 | count = 0; | ||
| 1921 | |||
| 1922 | ch->ch_pun.un_flag |= un_flag; | ||
| 1923 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 1924 | } | ||
| 1925 | |||
| 1926 | return count; | ||
| 1927 | } | ||
| 1928 | |||
| 1929 | /* | ||
| 1930 | * Return number of characters that have not been transmitted yet. | ||
| 1931 | * chars_in_buffer = ( ch->ch_tin - ch->ch_tout ) mod (TBUF_MAX - 1) | ||
| 1932 | * + ( ch->ch_s_tin - ch->ch_s_tout ) mod (0xffff) | ||
| 1933 | * = number of characters "in transit" | ||
| 1934 | * | ||
| 1935 | * Remember that sequence number math is always with a sixteen bit | ||
| 1936 | * mask, not the TBUF_MASK. | ||
| 1937 | */ | ||
| 1938 | |||
| 1939 | static int dgrp_tty_chars_in_buffer(struct tty_struct *tty) | ||
| 1940 | { | ||
| 1941 | struct un_struct *un; | ||
| 1942 | struct ch_struct *ch; | ||
| 1943 | int count; | ||
| 1944 | int count1; | ||
| 1945 | |||
| 1946 | if (!tty) | ||
| 1947 | return 0; | ||
| 1948 | |||
| 1949 | un = tty->driver_data; | ||
| 1950 | if (!un) | ||
| 1951 | return 0; | ||
| 1952 | |||
| 1953 | ch = un->un_ch; | ||
| 1954 | if (!ch) | ||
| 1955 | return 0; | ||
| 1956 | |||
| 1957 | count1 = count = (ch->ch_tin - ch->ch_tout) & TBUF_MASK; | ||
| 1958 | count += (ch->ch_s_tin - ch->ch_s_tpos) & 0xffff; | ||
| 1959 | /* one for tbuf, one for the PS */ | ||
| 1960 | |||
| 1961 | /* | ||
| 1962 | * If we are busy transmitting add 1 | ||
| 1963 | */ | ||
| 1964 | count += un->un_tbusy; | ||
| 1965 | |||
| 1966 | return count; | ||
| 1967 | } | ||
| 1968 | |||
| 1969 | |||
| 1970 | /***************************************************************************** | ||
| 1971 | * | ||
| 1972 | * Helper applications for dgrp_tty_ioctl() | ||
| 1973 | * | ||
| 1974 | ***************************************************************************** | ||
| 1975 | */ | ||
| 1976 | |||
| 1977 | |||
| 1978 | /** | ||
| 1979 | * ch_to_tty_flags() -- convert channel flags to termio flags | ||
| 1980 | * @ch_flag: Digi channel flags | ||
| 1981 | * @flagtype: type of ch_flag (iflag, oflag or cflag) | ||
| 1982 | * | ||
| 1983 | * take the channel flags of the specified type and return the | ||
| 1984 | * corresponding termio flag | ||
| 1985 | */ | ||
| 1986 | static tcflag_t ch_to_tty_flags(ushort ch_flag, char flagtype) | ||
| 1987 | { | ||
| 1988 | tcflag_t retval = 0; | ||
| 1989 | |||
| 1990 | switch (flagtype) { | ||
| 1991 | case 'i': | ||
| 1992 | retval = ((ch_flag & IF_IGNBRK) ? IGNBRK : 0) | ||
| 1993 | | ((ch_flag & IF_BRKINT) ? BRKINT : 0) | ||
| 1994 | | ((ch_flag & IF_IGNPAR) ? IGNPAR : 0) | ||
| 1995 | | ((ch_flag & IF_PARMRK) ? PARMRK : 0) | ||
| 1996 | | ((ch_flag & IF_INPCK) ? INPCK : 0) | ||
| 1997 | | ((ch_flag & IF_ISTRIP) ? ISTRIP : 0) | ||
| 1998 | | ((ch_flag & IF_IXON) ? IXON : 0) | ||
| 1999 | | ((ch_flag & IF_IXANY) ? IXANY : 0) | ||
| 2000 | | ((ch_flag & IF_IXOFF) ? IXOFF : 0); | ||
| 2001 | break; | ||
| 2002 | |||
| 2003 | case 'o': | ||
| 2004 | retval = ((ch_flag & OF_OLCUC) ? OLCUC : 0) | ||
| 2005 | | ((ch_flag & OF_ONLCR) ? ONLCR : 0) | ||
| 2006 | | ((ch_flag & OF_OCRNL) ? OCRNL : 0) | ||
| 2007 | | ((ch_flag & OF_ONOCR) ? ONOCR : 0) | ||
| 2008 | | ((ch_flag & OF_ONLRET) ? ONLRET : 0) | ||
| 2009 | /* | ((ch_flag & OF_OTAB3) ? OFILL : 0) */ | ||
| 2010 | | ((ch_flag & OF_TABDLY) ? TABDLY : 0); | ||
| 2011 | break; | ||
| 2012 | |||
| 2013 | case 'c': | ||
| 2014 | retval = ((ch_flag & CF_CSTOPB) ? CSTOPB : 0) | ||
| 2015 | | ((ch_flag & CF_CREAD) ? CREAD : 0) | ||
| 2016 | | ((ch_flag & CF_PARENB) ? PARENB : 0) | ||
| 2017 | | ((ch_flag & CF_PARODD) ? PARODD : 0) | ||
| 2018 | | ((ch_flag & CF_HUPCL) ? HUPCL : 0); | ||
| 2019 | |||
| 2020 | switch (ch_flag & CF_CSIZE) { | ||
| 2021 | case CF_CS5: | ||
| 2022 | retval |= CS5; | ||
| 2023 | break; | ||
| 2024 | case CF_CS6: | ||
| 2025 | retval |= CS6; | ||
| 2026 | break; | ||
| 2027 | case CF_CS7: | ||
| 2028 | retval |= CS7; | ||
| 2029 | break; | ||
| 2030 | case CF_CS8: | ||
| 2031 | retval |= CS8; | ||
| 2032 | break; | ||
| 2033 | default: | ||
| 2034 | retval |= CS8; | ||
| 2035 | break; | ||
| 2036 | } | ||
| 2037 | break; | ||
| 2038 | case 'x': | ||
| 2039 | break; | ||
| 2040 | case 'l': | ||
| 2041 | break; | ||
| 2042 | default: | ||
| 2043 | return 0; | ||
| 2044 | } | ||
| 2045 | |||
| 2046 | return retval; | ||
| 2047 | } | ||
| 2048 | |||
| 2049 | |||
| 2050 | /** | ||
| 2051 | * tty_to_ch_flags() -- convert termio flags to digi channel flags | ||
| 2052 | * @tty: pointer to a TTY structure holding flag to be converted | ||
| 2053 | * @flagtype: identifies which flag (iflags, oflags, or cflags) should | ||
| 2054 | * be converted | ||
| 2055 | * | ||
| 2056 | * take the termio flag of the specified type and return the | ||
| 2057 | * corresponding Digi version of the flags | ||
| 2058 | */ | ||
| 2059 | static ushort tty_to_ch_flags(struct tty_struct *tty, char flagtype) | ||
| 2060 | { | ||
| 2061 | ushort retval = 0; | ||
| 2062 | tcflag_t tflag = 0; | ||
| 2063 | |||
| 2064 | switch (flagtype) { | ||
| 2065 | case 'i': | ||
| 2066 | tflag = tty->termios.c_iflag; | ||
| 2067 | retval = (I_IGNBRK(tty) ? IF_IGNBRK : 0) | ||
| 2068 | | (I_BRKINT(tty) ? IF_BRKINT : 0) | ||
| 2069 | | (I_IGNPAR(tty) ? IF_IGNPAR : 0) | ||
| 2070 | | (I_PARMRK(tty) ? IF_PARMRK : 0) | ||
| 2071 | | (I_INPCK(tty) ? IF_INPCK : 0) | ||
| 2072 | | (I_ISTRIP(tty) ? IF_ISTRIP : 0) | ||
| 2073 | | (I_IXON(tty) ? IF_IXON : 0) | ||
| 2074 | | (I_IXANY(tty) ? IF_IXANY : 0) | ||
| 2075 | | (I_IXOFF(tty) ? IF_IXOFF : 0); | ||
| 2076 | break; | ||
| 2077 | case 'o': | ||
| 2078 | tflag = tty->termios.c_oflag; | ||
| 2079 | /* | ||
| 2080 | * If OPOST is set, then do the post processing in the | ||
| 2081 | * firmware by setting all the processing flags on. | ||
| 2082 | * If ~OPOST, then make sure we are not doing any | ||
| 2083 | * output processing!! | ||
| 2084 | */ | ||
| 2085 | if (!O_OPOST(tty)) | ||
| 2086 | retval = 0; | ||
| 2087 | else | ||
| 2088 | retval = (O_OLCUC(tty) ? OF_OLCUC : 0) | ||
| 2089 | | (O_ONLCR(tty) ? OF_ONLCR : 0) | ||
| 2090 | | (O_OCRNL(tty) ? OF_OCRNL : 0) | ||
| 2091 | | (O_ONOCR(tty) ? OF_ONOCR : 0) | ||
| 2092 | | (O_ONLRET(tty) ? OF_ONLRET : 0) | ||
| 2093 | /* | (O_OFILL(tty) ? OF_TAB3 : 0) */ | ||
| 2094 | | (O_TABDLY(tty) ? OF_TABDLY : 0); | ||
| 2095 | break; | ||
| 2096 | case 'c': | ||
| 2097 | tflag = tty->termios.c_cflag; | ||
| 2098 | retval = (C_CSTOPB(tty) ? CF_CSTOPB : 0) | ||
| 2099 | | (C_CREAD(tty) ? CF_CREAD : 0) | ||
| 2100 | | (C_PARENB(tty) ? CF_PARENB : 0) | ||
| 2101 | | (C_PARODD(tty) ? CF_PARODD : 0) | ||
| 2102 | | (C_HUPCL(tty) ? CF_HUPCL : 0); | ||
| 2103 | switch (C_CSIZE(tty)) { | ||
| 2104 | case CS8: | ||
| 2105 | retval |= CF_CS8; | ||
| 2106 | break; | ||
| 2107 | case CS7: | ||
| 2108 | retval |= CF_CS7; | ||
| 2109 | break; | ||
| 2110 | case CS6: | ||
| 2111 | retval |= CF_CS6; | ||
| 2112 | break; | ||
| 2113 | case CS5: | ||
| 2114 | retval |= CF_CS5; | ||
| 2115 | break; | ||
| 2116 | default: | ||
| 2117 | retval |= CF_CS8; | ||
| 2118 | break; | ||
| 2119 | } | ||
| 2120 | break; | ||
| 2121 | case 'x': | ||
| 2122 | break; | ||
| 2123 | case 'l': | ||
| 2124 | break; | ||
| 2125 | default: | ||
| 2126 | return 0; | ||
| 2127 | } | ||
| 2128 | |||
| 2129 | return retval; | ||
| 2130 | } | ||
| 2131 | |||
| 2132 | |||
| 2133 | static int dgrp_tty_send_break(struct tty_struct *tty, int msec) | ||
| 2134 | { | ||
| 2135 | struct un_struct *un; | ||
| 2136 | struct ch_struct *ch; | ||
| 2137 | int ret = -EIO; | ||
| 2138 | |||
| 2139 | if (!tty) | ||
| 2140 | return ret; | ||
| 2141 | |||
| 2142 | un = tty->driver_data; | ||
| 2143 | if (!un) | ||
| 2144 | return ret; | ||
| 2145 | |||
| 2146 | ch = un->un_ch; | ||
| 2147 | if (!ch) | ||
| 2148 | return ret; | ||
| 2149 | |||
| 2150 | dgrp_send_break(ch, msec); | ||
| 2151 | return 0; | ||
| 2152 | } | ||
| 2153 | |||
| 2154 | |||
| 2155 | /* | ||
| 2156 | * This routine sends a break character out the serial port. | ||
| 2157 | * | ||
| 2158 | * duration is in 1/1000's of a second | ||
| 2159 | */ | ||
| 2160 | static int dgrp_send_break(struct ch_struct *ch, int msec) | ||
| 2161 | { | ||
| 2162 | ulong x; | ||
| 2163 | |||
| 2164 | wait_event_interruptible(ch->ch_flag_wait, | ||
| 2165 | ((ch->ch_flag & CH_TX_BREAK) == 0)); | ||
| 2166 | ch->ch_break_time += max(msec, 250); | ||
| 2167 | ch->ch_send |= RR_TX_BREAK; | ||
| 2168 | ch->ch_flag |= CH_TX_BREAK; | ||
| 2169 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 2170 | |||
| 2171 | x = (msec * HZ) / 1000; | ||
| 2172 | wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq); | ||
| 2173 | |||
| 2174 | return 0; | ||
| 2175 | } | ||
| 2176 | |||
| 2177 | |||
| 2178 | /* | ||
| 2179 | * Return modem signals to ld. | ||
| 2180 | */ | ||
| 2181 | static int dgrp_tty_tiocmget(struct tty_struct *tty) | ||
| 2182 | { | ||
| 2183 | unsigned int mlast; | ||
| 2184 | struct un_struct *un = tty->driver_data; | ||
| 2185 | struct ch_struct *ch; | ||
| 2186 | |||
| 2187 | if (!un) | ||
| 2188 | return -ENODEV; | ||
| 2189 | |||
| 2190 | ch = un->un_ch; | ||
| 2191 | if (!ch) | ||
| 2192 | return -ENODEV; | ||
| 2193 | |||
| 2194 | mlast = ((ch->ch_s_mlast & ~(DM_RTS | DM_DTR)) | | ||
| 2195 | (ch->ch_mout & (DM_RTS | DM_DTR))); | ||
| 2196 | |||
| 2197 | /* defined in /usr/include/asm/termios.h */ | ||
| 2198 | mlast = ((mlast & DM_RTS) ? TIOCM_RTS : 0) | ||
| 2199 | | ((mlast & DM_DTR) ? TIOCM_DTR : 0) | ||
| 2200 | | ((mlast & DM_CD) ? TIOCM_CAR : 0) | ||
| 2201 | | ((mlast & DM_RI) ? TIOCM_RNG : 0) | ||
| 2202 | | ((mlast & DM_DSR) ? TIOCM_DSR : 0) | ||
| 2203 | | ((mlast & DM_CTS) ? TIOCM_CTS : 0); | ||
| 2204 | |||
| 2205 | return mlast; | ||
| 2206 | } | ||
| 2207 | |||
| 2208 | |||
| 2209 | /* | ||
| 2210 | * Set modem lines | ||
| 2211 | */ | ||
| 2212 | static int dgrp_tty_tiocmset(struct tty_struct *tty, | ||
| 2213 | unsigned int set, unsigned int clear) | ||
| 2214 | { | ||
| 2215 | ulong lock_flags; | ||
| 2216 | struct un_struct *un = tty->driver_data; | ||
| 2217 | struct ch_struct *ch; | ||
| 2218 | |||
| 2219 | if (!un) | ||
| 2220 | return -ENODEV; | ||
| 2221 | |||
| 2222 | ch = un->un_ch; | ||
| 2223 | if (!ch) | ||
| 2224 | return -ENODEV; | ||
| 2225 | |||
| 2226 | if (set & TIOCM_RTS) | ||
| 2227 | ch->ch_mout |= DM_RTS; | ||
| 2228 | |||
| 2229 | if (set & TIOCM_DTR) | ||
| 2230 | ch->ch_mout |= DM_DTR; | ||
| 2231 | |||
| 2232 | if (clear & TIOCM_RTS) | ||
| 2233 | ch->ch_mout &= ~(DM_RTS); | ||
| 2234 | |||
| 2235 | if (clear & TIOCM_DTR) | ||
| 2236 | ch->ch_mout &= ~(DM_DTR); | ||
| 2237 | |||
| 2238 | spin_lock_irqsave(&(ch->ch_nd)->nd_lock, lock_flags); | ||
| 2239 | ch->ch_flag |= CH_PARAM; | ||
| 2240 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 2241 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 2242 | |||
| 2243 | spin_unlock_irqrestore(&(ch->ch_nd)->nd_lock, lock_flags); | ||
| 2244 | |||
| 2245 | return 0; | ||
| 2246 | } | ||
| 2247 | |||
| 2248 | |||
| 2249 | |||
| 2250 | /* | ||
| 2251 | * Get current modem status | ||
| 2252 | */ | ||
| 2253 | static int get_modem_info(struct ch_struct *ch, unsigned int *value) | ||
| 2254 | { | ||
| 2255 | unsigned int mlast; | ||
| 2256 | |||
| 2257 | mlast = ((ch->ch_s_mlast & ~(DM_RTS | DM_DTR)) | | ||
| 2258 | (ch->ch_mout & (DM_RTS | DM_DTR))); | ||
| 2259 | |||
| 2260 | /* defined in /usr/include/asm/termios.h */ | ||
| 2261 | mlast = ((mlast & DM_RTS) ? TIOCM_RTS : 0) | ||
| 2262 | | ((mlast & DM_DTR) ? TIOCM_DTR : 0) | ||
| 2263 | | ((mlast & DM_CD) ? TIOCM_CAR : 0) | ||
| 2264 | | ((mlast & DM_RI) ? TIOCM_RNG : 0) | ||
| 2265 | | ((mlast & DM_DSR) ? TIOCM_DSR : 0) | ||
| 2266 | | ((mlast & DM_CTS) ? TIOCM_CTS : 0); | ||
| 2267 | put_user(mlast, (unsigned int __user *) value); | ||
| 2268 | |||
| 2269 | return 0; | ||
| 2270 | } | ||
| 2271 | |||
| 2272 | /* | ||
| 2273 | * Set modem lines | ||
| 2274 | */ | ||
| 2275 | static int set_modem_info(struct ch_struct *ch, unsigned int command, | ||
| 2276 | unsigned int *value) | ||
| 2277 | { | ||
| 2278 | int error; | ||
| 2279 | unsigned int arg; | ||
| 2280 | int mval = 0; | ||
| 2281 | ulong lock_flags; | ||
| 2282 | |||
| 2283 | error = access_ok(VERIFY_READ, (void __user *) value, sizeof(int)); | ||
| 2284 | if (error == 0) | ||
| 2285 | return -EFAULT; | ||
| 2286 | |||
| 2287 | get_user(arg, (unsigned int __user *) value); | ||
| 2288 | mval |= ((arg & TIOCM_RTS) ? DM_RTS : 0) | ||
| 2289 | | ((arg & TIOCM_DTR) ? DM_DTR : 0); | ||
| 2290 | |||
| 2291 | switch (command) { | ||
| 2292 | case TIOCMBIS: /* set flags */ | ||
| 2293 | ch->ch_mout |= mval; | ||
| 2294 | break; | ||
| 2295 | case TIOCMBIC: /* clear flags */ | ||
| 2296 | ch->ch_mout &= ~mval; | ||
| 2297 | break; | ||
| 2298 | case TIOCMSET: | ||
| 2299 | ch->ch_mout = mval; | ||
| 2300 | break; | ||
| 2301 | default: | ||
| 2302 | return -EINVAL; | ||
| 2303 | } | ||
| 2304 | |||
| 2305 | spin_lock_irqsave(&(ch->ch_nd)->nd_lock, lock_flags); | ||
| 2306 | |||
| 2307 | ch->ch_flag |= CH_PARAM; | ||
| 2308 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 2309 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 2310 | |||
| 2311 | spin_unlock_irqrestore(&(ch->ch_nd)->nd_lock, lock_flags); | ||
| 2312 | |||
| 2313 | return 0; | ||
| 2314 | } | ||
| 2315 | |||
| 2316 | |||
| 2317 | /* | ||
| 2318 | * Assign the custom baud rate to the channel structure | ||
| 2319 | */ | ||
| 2320 | static void dgrp_set_custom_speed(struct ch_struct *ch, int newrate) | ||
| 2321 | { | ||
| 2322 | int testdiv; | ||
| 2323 | int testrate_high; | ||
| 2324 | int testrate_low; | ||
| 2325 | |||
| 2326 | int deltahigh, deltalow; | ||
| 2327 | |||
| 2328 | if (newrate < 0) | ||
| 2329 | newrate = 0; | ||
| 2330 | |||
| 2331 | /* | ||
| 2332 | * Since the divisor is stored in a 16-bit integer, we make sure | ||
| 2333 | * we don't allow any rates smaller than a 16-bit integer would allow. | ||
| 2334 | * And of course, rates above the dividend won't fly. | ||
| 2335 | */ | ||
| 2336 | if (newrate && newrate < ((PORTSERVER_DIVIDEND / 0xFFFF) + 1)) | ||
| 2337 | newrate = ((PORTSERVER_DIVIDEND / 0xFFFF) + 1); | ||
| 2338 | if (newrate && newrate > PORTSERVER_DIVIDEND) | ||
| 2339 | newrate = PORTSERVER_DIVIDEND; | ||
| 2340 | |||
| 2341 | while (newrate > 0) { | ||
| 2342 | testdiv = PORTSERVER_DIVIDEND / newrate; | ||
| 2343 | |||
| 2344 | /* | ||
| 2345 | * If we try to figure out what rate the PortServer would use | ||
| 2346 | * with the test divisor, it will be either equal or higher | ||
| 2347 | * than the requested baud rate. If we then determine the | ||
| 2348 | * rate with a divisor one higher, we will get the next lower | ||
| 2349 | * supported rate below the requested. | ||
| 2350 | */ | ||
| 2351 | testrate_high = PORTSERVER_DIVIDEND / testdiv; | ||
| 2352 | testrate_low = PORTSERVER_DIVIDEND / (testdiv + 1); | ||
| 2353 | |||
| 2354 | /* | ||
| 2355 | * If the rate for the requested divisor is correct, just | ||
| 2356 | * use it and be done. | ||
| 2357 | */ | ||
| 2358 | if (testrate_high == newrate) | ||
| 2359 | break; | ||
| 2360 | |||
| 2361 | /* | ||
| 2362 | * Otherwise, pick the rate that is closer (i.e. whichever rate | ||
| 2363 | * has a smaller delta). | ||
| 2364 | */ | ||
| 2365 | deltahigh = testrate_high - newrate; | ||
| 2366 | deltalow = newrate - testrate_low; | ||
| 2367 | |||
| 2368 | if (deltahigh < deltalow) | ||
| 2369 | newrate = testrate_high; | ||
| 2370 | else | ||
| 2371 | newrate = testrate_low; | ||
| 2372 | |||
| 2373 | break; | ||
| 2374 | } | ||
| 2375 | |||
| 2376 | ch->ch_custom_speed = newrate; | ||
| 2377 | |||
| 2378 | drp_param(ch); | ||
| 2379 | |||
| 2380 | return; | ||
| 2381 | } | ||
| 2382 | |||
| 2383 | |||
| 2384 | /* | ||
| 2385 | # dgrp_tty_digiseta() | ||
| 2386 | * | ||
| 2387 | * Ioctl to set the information from ditty. | ||
| 2388 | * | ||
| 2389 | * NOTE: DIGI_IXON, DSRPACE, DCDPACE, and DTRPACE are unsupported. JAR 990922 | ||
| 2390 | */ | ||
| 2391 | static int dgrp_tty_digiseta(struct tty_struct *tty, | ||
| 2392 | struct digi_struct *new_info) | ||
| 2393 | { | ||
| 2394 | struct un_struct *un = tty->driver_data; | ||
| 2395 | struct ch_struct *ch; | ||
| 2396 | |||
| 2397 | if (!un) | ||
| 2398 | return -ENODEV; | ||
| 2399 | |||
| 2400 | ch = un->un_ch; | ||
| 2401 | if (!ch) | ||
| 2402 | return -ENODEV; | ||
| 2403 | |||
| 2404 | if (copy_from_user(&ch->ch_digi, (void __user *) new_info, | ||
| 2405 | sizeof(struct digi_struct))) | ||
| 2406 | return -EFAULT; | ||
| 2407 | |||
| 2408 | if ((ch->ch_digi.digi_flags & RTSPACE) || | ||
| 2409 | (ch->ch_digi.digi_flags & CTSPACE)) | ||
| 2410 | tty->termios.c_cflag |= CRTSCTS; | ||
| 2411 | else | ||
| 2412 | tty->termios.c_cflag &= ~CRTSCTS; | ||
| 2413 | |||
| 2414 | if (ch->ch_digi.digi_maxcps < 1) | ||
| 2415 | ch->ch_digi.digi_maxcps = 1; | ||
| 2416 | |||
| 2417 | if (ch->ch_digi.digi_maxcps > 10000) | ||
| 2418 | ch->ch_digi.digi_maxcps = 10000; | ||
| 2419 | |||
| 2420 | if (ch->ch_digi.digi_bufsize < 10) | ||
| 2421 | ch->ch_digi.digi_bufsize = 10; | ||
| 2422 | |||
| 2423 | if (ch->ch_digi.digi_maxchar < 1) | ||
| 2424 | ch->ch_digi.digi_maxchar = 1; | ||
| 2425 | |||
| 2426 | if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize) | ||
| 2427 | ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize; | ||
| 2428 | |||
| 2429 | if (ch->ch_digi.digi_onlen > DIGI_PLEN) | ||
| 2430 | ch->ch_digi.digi_onlen = DIGI_PLEN; | ||
| 2431 | |||
| 2432 | if (ch->ch_digi.digi_offlen > DIGI_PLEN) | ||
| 2433 | ch->ch_digi.digi_offlen = DIGI_PLEN; | ||
| 2434 | |||
| 2435 | /* make the changes now */ | ||
| 2436 | drp_param(ch); | ||
| 2437 | |||
| 2438 | return 0; | ||
| 2439 | } | ||
| 2440 | |||
| 2441 | |||
| 2442 | |||
| 2443 | /* | ||
| 2444 | * dgrp_tty_digigetedelay() | ||
| 2445 | * | ||
| 2446 | * Ioctl to get the current edelay setting. | ||
| 2447 | * | ||
| 2448 | * | ||
| 2449 | * | ||
| 2450 | */ | ||
| 2451 | static int dgrp_tty_digigetedelay(struct tty_struct *tty, int *retinfo) | ||
| 2452 | { | ||
| 2453 | struct un_struct *un; | ||
| 2454 | struct ch_struct *ch; | ||
| 2455 | int tmp; | ||
| 2456 | |||
| 2457 | if (!retinfo) | ||
| 2458 | return -EFAULT; | ||
| 2459 | |||
| 2460 | if (!tty || tty->magic != TTY_MAGIC) | ||
| 2461 | return -EFAULT; | ||
| 2462 | |||
| 2463 | un = tty->driver_data; | ||
| 2464 | |||
| 2465 | if (!un) | ||
| 2466 | return -ENODEV; | ||
| 2467 | |||
| 2468 | ch = un->un_ch; | ||
| 2469 | if (!ch) | ||
| 2470 | return -ENODEV; | ||
| 2471 | |||
| 2472 | tmp = ch->ch_edelay; | ||
| 2473 | |||
| 2474 | if (copy_to_user((void __user *) retinfo, &tmp, sizeof(*retinfo))) | ||
| 2475 | return -EFAULT; | ||
| 2476 | |||
| 2477 | return 0; | ||
| 2478 | } | ||
| 2479 | |||
| 2480 | |||
| 2481 | /* | ||
| 2482 | * dgrp_tty_digisetedelay() | ||
| 2483 | * | ||
| 2484 | * Ioctl to set the EDELAY setting | ||
| 2485 | * | ||
| 2486 | */ | ||
| 2487 | static int dgrp_tty_digisetedelay(struct tty_struct *tty, int *new_info) | ||
| 2488 | { | ||
| 2489 | struct un_struct *un; | ||
| 2490 | struct ch_struct *ch; | ||
| 2491 | int new_digi; | ||
| 2492 | |||
| 2493 | if (!tty || tty->magic != TTY_MAGIC) | ||
| 2494 | return -EFAULT; | ||
| 2495 | |||
| 2496 | un = tty->driver_data; | ||
| 2497 | |||
| 2498 | if (!un) | ||
| 2499 | return -ENODEV; | ||
| 2500 | |||
| 2501 | ch = un->un_ch; | ||
| 2502 | if (!ch) | ||
| 2503 | return -ENODEV; | ||
| 2504 | |||
| 2505 | if (copy_from_user(&new_digi, (void __user *)new_info, sizeof(int))) | ||
| 2506 | return -EFAULT; | ||
| 2507 | |||
| 2508 | ch->ch_edelay = new_digi; | ||
| 2509 | |||
| 2510 | /* make the changes now */ | ||
| 2511 | drp_param(ch); | ||
| 2512 | |||
| 2513 | return 0; | ||
| 2514 | } | ||
| 2515 | |||
| 2516 | |||
| 2517 | /* | ||
| 2518 | * The usual assortment of ioctl's | ||
| 2519 | * | ||
| 2520 | * note: use tty_check_change to make sure that we are not | ||
| 2521 | * changing the state of a terminal when we are not a process | ||
| 2522 | * in the forground. See tty_io.c | ||
| 2523 | * rc = tty_check_change(tty); | ||
| 2524 | * if (rc) return rc; | ||
| 2525 | */ | ||
| 2526 | static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd, | ||
| 2527 | unsigned long arg) | ||
| 2528 | { | ||
| 2529 | struct un_struct *un; | ||
| 2530 | struct ch_struct *ch; | ||
| 2531 | int rc; | ||
| 2532 | struct digiflow_struct dflow; | ||
| 2533 | |||
| 2534 | if (!tty) | ||
| 2535 | return -ENODEV; | ||
| 2536 | |||
| 2537 | un = tty->driver_data; | ||
| 2538 | if (!un) | ||
| 2539 | return -ENODEV; | ||
| 2540 | |||
| 2541 | ch = un->un_ch; | ||
| 2542 | if (!ch) | ||
| 2543 | return -ENODEV; | ||
| 2544 | |||
| 2545 | switch (cmd) { | ||
| 2546 | |||
| 2547 | /* | ||
| 2548 | * Here are all the standard ioctl's that we MUST implement | ||
| 2549 | */ | ||
| 2550 | |||
| 2551 | case TCSBRK: | ||
| 2552 | /* | ||
| 2553 | * TCSBRK is SVID version: non-zero arg --> no break | ||
| 2554 | * this behaviour is exploited by tcdrain(). | ||
| 2555 | * | ||
| 2556 | * According to POSIX.1 spec (7.2.2.1.2) breaks should be | ||
| 2557 | * between 0.25 and 0.5 seconds | ||
| 2558 | */ | ||
| 2559 | |||
| 2560 | rc = tty_check_change(tty); | ||
| 2561 | if (rc) | ||
| 2562 | return rc; | ||
| 2563 | tty_wait_until_sent(tty, 0); | ||
| 2564 | |||
| 2565 | if (!arg) | ||
| 2566 | rc = dgrp_send_break(ch, 250); /* 1/4 second */ | ||
| 2567 | |||
| 2568 | if (dgrp_tty_chars_in_buffer(tty) != 0) | ||
| 2569 | return -EINTR; | ||
| 2570 | |||
| 2571 | return 0; | ||
| 2572 | |||
| 2573 | case TCSBRKP: | ||
| 2574 | /* support for POSIX tcsendbreak() | ||
| 2575 | * | ||
| 2576 | * According to POSIX.1 spec (7.2.2.1.2) breaks should be | ||
| 2577 | * between 0.25 and 0.5 seconds so we'll ask for something | ||
| 2578 | * in the middle: 0.375 seconds. | ||
| 2579 | */ | ||
| 2580 | rc = tty_check_change(tty); | ||
| 2581 | if (rc) | ||
| 2582 | return rc; | ||
| 2583 | tty_wait_until_sent(tty, 0); | ||
| 2584 | |||
| 2585 | rc = dgrp_send_break(ch, arg ? arg*250 : 250); | ||
| 2586 | |||
| 2587 | if (dgrp_tty_chars_in_buffer(tty) != 0) | ||
| 2588 | return -EINTR; | ||
| 2589 | return 0; | ||
| 2590 | |||
| 2591 | case TIOCSBRK: | ||
| 2592 | rc = tty_check_change(tty); | ||
| 2593 | if (rc) | ||
| 2594 | return rc; | ||
| 2595 | tty_wait_until_sent(tty, 0); | ||
| 2596 | |||
| 2597 | /* | ||
| 2598 | * RealPort doesn't support turning on a break unconditionally. | ||
| 2599 | * The RealPort device will stop sending a break automatically | ||
| 2600 | * after the specified time value that we send in. | ||
| 2601 | */ | ||
| 2602 | rc = dgrp_send_break(ch, 250); /* 1/4 second */ | ||
| 2603 | |||
| 2604 | if (dgrp_tty_chars_in_buffer(tty) != 0) | ||
| 2605 | return -EINTR; | ||
| 2606 | return 0; | ||
| 2607 | |||
| 2608 | case TIOCCBRK: | ||
| 2609 | /* | ||
| 2610 | * RealPort doesn't support turning off a break unconditionally. | ||
| 2611 | * The RealPort device will stop sending a break automatically | ||
| 2612 | * after the specified time value that was sent when turning on | ||
| 2613 | * the break. | ||
| 2614 | */ | ||
| 2615 | return 0; | ||
| 2616 | |||
| 2617 | case TIOCGSOFTCAR: | ||
| 2618 | rc = access_ok(VERIFY_WRITE, (void __user *) arg, | ||
| 2619 | sizeof(long)); | ||
| 2620 | if (rc == 0) | ||
| 2621 | return -EFAULT; | ||
| 2622 | put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) arg); | ||
| 2623 | return 0; | ||
| 2624 | |||
| 2625 | case TIOCSSOFTCAR: | ||
| 2626 | get_user(arg, (unsigned long __user *) arg); | ||
| 2627 | tty->termios.c_cflag = | ||
| 2628 | ((tty->termios.c_cflag & ~CLOCAL) | | ||
| 2629 | (arg ? CLOCAL : 0)); | ||
| 2630 | return 0; | ||
| 2631 | |||
| 2632 | case TIOCMGET: | ||
| 2633 | rc = access_ok(VERIFY_WRITE, (void __user *) arg, | ||
| 2634 | sizeof(unsigned int)); | ||
| 2635 | if (rc == 0) | ||
| 2636 | return -EFAULT; | ||
| 2637 | return get_modem_info(ch, (unsigned int *) arg); | ||
| 2638 | |||
| 2639 | case TIOCMBIS: | ||
| 2640 | case TIOCMBIC: | ||
| 2641 | case TIOCMSET: | ||
| 2642 | return set_modem_info(ch, cmd, (unsigned int *) arg); | ||
| 2643 | |||
| 2644 | /* | ||
| 2645 | * Here are any additional ioctl's that we want to implement | ||
| 2646 | */ | ||
| 2647 | |||
| 2648 | case TCFLSH: | ||
| 2649 | /* | ||
| 2650 | * The linux tty driver doesn't have a flush | ||
| 2651 | * input routine for the driver, assuming all backed | ||
| 2652 | * up data is in the line disc. buffers. However, | ||
| 2653 | * we all know that's not the case. Here, we | ||
| 2654 | * act on the ioctl, but then lie and say we didn't | ||
| 2655 | * so the line discipline will process the flush | ||
| 2656 | * also. | ||
| 2657 | */ | ||
| 2658 | rc = tty_check_change(tty); | ||
| 2659 | if (rc) | ||
| 2660 | return rc; | ||
| 2661 | |||
| 2662 | switch (arg) { | ||
| 2663 | case TCIFLUSH: | ||
| 2664 | case TCIOFLUSH: | ||
| 2665 | /* only flush input if this is the only open unit */ | ||
| 2666 | if (!IS_PRINT(MINOR(tty_devnum(tty)))) { | ||
| 2667 | ch->ch_rout = ch->ch_rin; | ||
| 2668 | ch->ch_send |= RR_RX_FLUSH; | ||
| 2669 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 2670 | (ch->ch_nd)->nd_tx_ready = 1; | ||
| 2671 | wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq); | ||
| 2672 | } | ||
| 2673 | if (arg == TCIFLUSH) | ||
| 2674 | break; | ||
| 2675 | |||
| 2676 | case TCOFLUSH: /* flush output, or the receive buffer */ | ||
| 2677 | /* | ||
| 2678 | * This is handled in the tty_ioctl.c code | ||
| 2679 | * calling tty_flush_buffer | ||
| 2680 | */ | ||
| 2681 | break; | ||
| 2682 | |||
| 2683 | default: | ||
| 2684 | /* POSIX.1 says return EINVAL if we got a bad arg */ | ||
| 2685 | return -EINVAL; | ||
| 2686 | } | ||
| 2687 | /* pretend we didn't recognize this IOCTL */ | ||
| 2688 | return -ENOIOCTLCMD; | ||
| 2689 | |||
| 2690 | #ifdef TIOCGETP | ||
| 2691 | case TIOCGETP: | ||
| 2692 | #endif | ||
| 2693 | /***************************************** | ||
| 2694 | Linux HPUX Function | ||
| 2695 | TCSETA TCSETA - set the termios | ||
| 2696 | TCSETAF TCSETAF - wait for drain first, then set termios | ||
| 2697 | TCSETAW TCSETAW - wait for drain, flush the input queue, then set termios | ||
| 2698 | - looking at the tty_ioctl code, these command all call our | ||
| 2699 | tty_set_termios at the driver's end, when a TCSETA* is sent, | ||
| 2700 | it is expecting the tty to have a termio structure, | ||
| 2701 | NOT a termios stucture. These two structures differ in size | ||
| 2702 | and the tty_ioctl code does a conversion before processing them both. | ||
| 2703 | - we should treat the TCSETAW TCSETAF ioctls the same, and let | ||
| 2704 | the tty_ioctl code do the conversion stuff. | ||
| 2705 | |||
| 2706 | TCSETS | ||
| 2707 | TCSETSF (none) | ||
| 2708 | TCSETSW | ||
| 2709 | - the associated tty structure has a termios structure. | ||
| 2710 | *****************************************/ | ||
| 2711 | |||
| 2712 | case TCGETS: | ||
| 2713 | case TCGETA: | ||
| 2714 | return -ENOIOCTLCMD; | ||
| 2715 | |||
| 2716 | case TCSETAW: | ||
| 2717 | case TCSETAF: | ||
| 2718 | case TCSETSF: | ||
| 2719 | case TCSETSW: | ||
| 2720 | /* | ||
| 2721 | * The linux tty driver doesn't have a flush | ||
| 2722 | * input routine for the driver, assuming all backed | ||
| 2723 | * up data is in the line disc. buffers. However, | ||
| 2724 | * we all know that's not the case. Here, we | ||
| 2725 | * act on the ioctl, but then lie and say we didn't | ||
| 2726 | * so the line discipline will process the flush | ||
| 2727 | * also. | ||
| 2728 | */ | ||
| 2729 | |||
| 2730 | /* | ||
| 2731 | * Also, now that we have TXPrint, we have to check | ||
| 2732 | * if this is the TXPrint device and the terminal | ||
| 2733 | * device is open. If so, do NOT run check_change, | ||
| 2734 | * as the terminal device is ALWAYS the parent. | ||
| 2735 | */ | ||
| 2736 | if (!IS_PRINT(MINOR(tty_devnum(tty))) || | ||
| 2737 | !ch->ch_tun.un_open_count) { | ||
| 2738 | rc = tty_check_change(tty); | ||
| 2739 | if (rc) | ||
| 2740 | return rc; | ||
| 2741 | } | ||
| 2742 | |||
| 2743 | /* wait for all the characters in tbuf to drain */ | ||
| 2744 | tty_wait_until_sent(tty, 0); | ||
| 2745 | |||
| 2746 | if ((cmd == TCSETSF) || (cmd == TCSETAF)) { | ||
| 2747 | /* flush the contents of the rbuf queue */ | ||
| 2748 | /* TODO: check if this is print device? */ | ||
| 2749 | ch->ch_send |= RR_RX_FLUSH; | ||
| 2750 | (ch->ch_nd)->nd_tx_ready = 1; | ||
| 2751 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 2752 | wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq); | ||
| 2753 | /* do we need to do this? just to be safe! */ | ||
| 2754 | ch->ch_rout = ch->ch_rin; | ||
| 2755 | } | ||
| 2756 | |||
| 2757 | /* pretend we didn't recognize this */ | ||
| 2758 | return -ENOIOCTLCMD; | ||
| 2759 | |||
| 2760 | case TCXONC: | ||
| 2761 | /* | ||
| 2762 | * The Linux Line Discipline (LD) would do this for us if we | ||
| 2763 | * let it, but we have the special firmware options to do this | ||
| 2764 | * the "right way" regardless of hardware or software flow | ||
| 2765 | * control so we'll do it outselves instead of letting the LD | ||
| 2766 | * do it. | ||
| 2767 | */ | ||
| 2768 | rc = tty_check_change(tty); | ||
| 2769 | if (rc) | ||
| 2770 | return rc; | ||
| 2771 | |||
| 2772 | switch (arg) { | ||
| 2773 | case TCOON: | ||
| 2774 | dgrp_tty_start(tty); | ||
| 2775 | return 0; | ||
| 2776 | case TCOOFF: | ||
| 2777 | dgrp_tty_stop(tty); | ||
| 2778 | return 0; | ||
| 2779 | case TCION: | ||
| 2780 | dgrp_tty_input_start(tty); | ||
| 2781 | return 0; | ||
| 2782 | case TCIOFF: | ||
| 2783 | dgrp_tty_input_stop(tty); | ||
| 2784 | return 0; | ||
| 2785 | default: | ||
| 2786 | return -EINVAL; | ||
| 2787 | } | ||
| 2788 | |||
| 2789 | case DIGI_GETA: | ||
| 2790 | /* get information for ditty */ | ||
| 2791 | if (copy_to_user((struct digi_struct __user *) arg, | ||
| 2792 | &ch->ch_digi, sizeof(struct digi_struct))) | ||
| 2793 | return -EFAULT; | ||
| 2794 | break; | ||
| 2795 | |||
| 2796 | case DIGI_SETAW: | ||
| 2797 | case DIGI_SETAF: | ||
| 2798 | /* wait for all the characters in tbuf to drain */ | ||
| 2799 | tty_wait_until_sent(tty, 0); | ||
| 2800 | |||
| 2801 | if (cmd == DIGI_SETAF) { | ||
| 2802 | /* flush the contents of the rbuf queue */ | ||
| 2803 | /* send down a packet with RR_RX_FLUSH set */ | ||
| 2804 | ch->ch_send |= RR_RX_FLUSH; | ||
| 2805 | (ch->ch_nd)->nd_tx_ready = 1; | ||
| 2806 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 2807 | wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq); | ||
| 2808 | /* do we need to do this? just to be safe! */ | ||
| 2809 | ch->ch_rout = ch->ch_rin; | ||
| 2810 | } | ||
| 2811 | |||
| 2812 | /* pretend we didn't recognize this */ | ||
| 2813 | |||
| 2814 | case DIGI_SETA: | ||
| 2815 | return dgrp_tty_digiseta(tty, (struct digi_struct *) arg); | ||
| 2816 | |||
| 2817 | case DIGI_SEDELAY: | ||
| 2818 | return dgrp_tty_digisetedelay(tty, (int *) arg); | ||
| 2819 | |||
| 2820 | case DIGI_GEDELAY: | ||
| 2821 | return dgrp_tty_digigetedelay(tty, (int *) arg); | ||
| 2822 | |||
| 2823 | case DIGI_GETFLOW: | ||
| 2824 | case DIGI_GETAFLOW: | ||
| 2825 | if (cmd == (DIGI_GETFLOW)) { | ||
| 2826 | dflow.startc = tty->termios.c_cc[VSTART]; | ||
| 2827 | dflow.stopc = tty->termios.c_cc[VSTOP]; | ||
| 2828 | } else { | ||
| 2829 | dflow.startc = ch->ch_xxon; | ||
| 2830 | dflow.stopc = ch->ch_xxoff; | ||
| 2831 | } | ||
| 2832 | |||
| 2833 | if (copy_to_user((char __user *)arg, &dflow, sizeof(dflow))) | ||
| 2834 | return -EFAULT; | ||
| 2835 | break; | ||
| 2836 | |||
| 2837 | case DIGI_SETFLOW: | ||
| 2838 | case DIGI_SETAFLOW: | ||
| 2839 | |||
| 2840 | if (copy_from_user(&dflow, (char __user *)arg, sizeof(dflow))) | ||
| 2841 | return -EFAULT; | ||
| 2842 | |||
| 2843 | if (cmd == (DIGI_SETFLOW)) { | ||
| 2844 | tty->termios.c_cc[VSTART] = dflow.startc; | ||
| 2845 | tty->termios.c_cc[VSTOP] = dflow.stopc; | ||
| 2846 | } else { | ||
| 2847 | ch->ch_xxon = dflow.startc; | ||
| 2848 | ch->ch_xxoff = dflow.stopc; | ||
| 2849 | } | ||
| 2850 | break; | ||
| 2851 | |||
| 2852 | case DIGI_GETCUSTOMBAUD: | ||
| 2853 | rc = access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(int)); | ||
| 2854 | if (rc == 0) | ||
| 2855 | return -EFAULT; | ||
| 2856 | put_user(ch->ch_custom_speed, (unsigned int __user *) arg); | ||
| 2857 | break; | ||
| 2858 | |||
| 2859 | case DIGI_SETCUSTOMBAUD: | ||
| 2860 | { | ||
| 2861 | int new_rate; | ||
| 2862 | |||
| 2863 | get_user(new_rate, (unsigned int __user *) arg); | ||
| 2864 | dgrp_set_custom_speed(ch, new_rate); | ||
| 2865 | |||
| 2866 | break; | ||
| 2867 | } | ||
| 2868 | |||
| 2869 | default: | ||
| 2870 | return -ENOIOCTLCMD; | ||
| 2871 | } | ||
| 2872 | |||
| 2873 | return 0; | ||
| 2874 | } | ||
| 2875 | |||
| 2876 | /* | ||
| 2877 | * This routine allows the tty driver to be notified when | ||
| 2878 | * the device's termios setting have changed. Note that we | ||
| 2879 | * should be prepared to accept the case where old == NULL | ||
| 2880 | * and try to do something rational. | ||
| 2881 | * | ||
| 2882 | * So we need to make sure that our copies of ch_oflag, | ||
| 2883 | * ch_clag, and ch_iflag reflect the tty->termios flags. | ||
| 2884 | */ | ||
| 2885 | static void dgrp_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | ||
| 2886 | { | ||
| 2887 | struct ktermios *ts; | ||
| 2888 | struct ch_struct *ch; | ||
| 2889 | struct un_struct *un; | ||
| 2890 | |||
| 2891 | /* seems silly, but we have to check all these! */ | ||
| 2892 | if (!tty) | ||
| 2893 | return; | ||
| 2894 | |||
| 2895 | un = tty->driver_data; | ||
| 2896 | if (!un) | ||
| 2897 | return; | ||
| 2898 | |||
| 2899 | ts = &tty->termios; | ||
| 2900 | |||
| 2901 | ch = un->un_ch; | ||
| 2902 | if (!ch) | ||
| 2903 | return; | ||
| 2904 | |||
| 2905 | drp_param(ch); | ||
| 2906 | |||
| 2907 | /* the CLOCAL flag has just been set */ | ||
| 2908 | if (!(old->c_cflag & CLOCAL) && C_CLOCAL(tty)) | ||
| 2909 | wake_up_interruptible(&un->un_open_wait); | ||
| 2910 | } | ||
| 2911 | |||
| 2912 | |||
| 2913 | /* | ||
| 2914 | * Throttle receiving data. We just set a bit and stop reading | ||
| 2915 | * data out of the channel buffer. It will back up and the | ||
| 2916 | * FEP will do whatever is necessary to stop the far end. | ||
| 2917 | */ | ||
| 2918 | static void dgrp_tty_throttle(struct tty_struct *tty) | ||
| 2919 | { | ||
| 2920 | struct ch_struct *ch; | ||
| 2921 | |||
| 2922 | if (!tty) | ||
| 2923 | return; | ||
| 2924 | |||
| 2925 | ch = ((struct un_struct *) tty->driver_data)->un_ch; | ||
| 2926 | if (!ch) | ||
| 2927 | return; | ||
| 2928 | |||
| 2929 | ch->ch_flag |= CH_RXSTOP; | ||
| 2930 | } | ||
| 2931 | |||
| 2932 | |||
| 2933 | static void dgrp_tty_unthrottle(struct tty_struct *tty) | ||
| 2934 | { | ||
| 2935 | struct ch_struct *ch; | ||
| 2936 | |||
| 2937 | if (!tty) | ||
| 2938 | return; | ||
| 2939 | |||
| 2940 | ch = ((struct un_struct *) tty->driver_data)->un_ch; | ||
| 2941 | if (!ch) | ||
| 2942 | return; | ||
| 2943 | |||
| 2944 | ch->ch_flag &= ~CH_RXSTOP; | ||
| 2945 | } | ||
| 2946 | |||
| 2947 | /* | ||
| 2948 | * Stop the transmitter | ||
| 2949 | */ | ||
| 2950 | static void dgrp_tty_stop(struct tty_struct *tty) | ||
| 2951 | { | ||
| 2952 | struct ch_struct *ch; | ||
| 2953 | |||
| 2954 | if (!tty) | ||
| 2955 | return; | ||
| 2956 | |||
| 2957 | ch = ((struct un_struct *) tty->driver_data)->un_ch; | ||
| 2958 | if (!ch) | ||
| 2959 | return; | ||
| 2960 | |||
| 2961 | ch->ch_send |= RR_TX_STOP; | ||
| 2962 | ch->ch_send &= ~RR_TX_START; | ||
| 2963 | |||
| 2964 | /* make the change NOW! */ | ||
| 2965 | (ch->ch_nd)->nd_tx_ready = 1; | ||
| 2966 | if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq)) | ||
| 2967 | wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq); | ||
| 2968 | } | ||
| 2969 | |||
| 2970 | /* | ||
| 2971 | * Start the transmitter | ||
| 2972 | */ | ||
| 2973 | static void dgrp_tty_start(struct tty_struct *tty) | ||
| 2974 | { | ||
| 2975 | struct ch_struct *ch; | ||
| 2976 | |||
| 2977 | if (!tty) | ||
| 2978 | return; | ||
| 2979 | |||
| 2980 | ch = ((struct un_struct *) tty->driver_data)->un_ch; | ||
| 2981 | if (!ch) | ||
| 2982 | return; | ||
| 2983 | |||
| 2984 | /* TODO: don't do anything if the transmitter is not stopped */ | ||
| 2985 | |||
| 2986 | ch->ch_send |= RR_TX_START; | ||
| 2987 | ch->ch_send &= ~RR_TX_STOP; | ||
| 2988 | |||
| 2989 | /* make the change NOW! */ | ||
| 2990 | (ch->ch_nd)->nd_tx_ready = 1; | ||
| 2991 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 2992 | if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq)) | ||
| 2993 | wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq); | ||
| 2994 | |||
| 2995 | } | ||
| 2996 | |||
| 2997 | /* | ||
| 2998 | * Stop the reciever | ||
| 2999 | */ | ||
| 3000 | static void dgrp_tty_input_stop(struct tty_struct *tty) | ||
| 3001 | { | ||
| 3002 | struct ch_struct *ch; | ||
| 3003 | |||
| 3004 | if (!tty) | ||
| 3005 | return; | ||
| 3006 | |||
| 3007 | ch = ((struct un_struct *) tty->driver_data)->un_ch; | ||
| 3008 | if (!ch) | ||
| 3009 | return; | ||
| 3010 | |||
| 3011 | ch->ch_send |= RR_RX_STOP; | ||
| 3012 | ch->ch_send &= ~RR_RX_START; | ||
| 3013 | (ch->ch_nd)->nd_tx_ready = 1; | ||
| 3014 | if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq)) | ||
| 3015 | wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq); | ||
| 3016 | |||
| 3017 | } | ||
| 3018 | |||
| 3019 | |||
| 3020 | static void dgrp_tty_send_xchar(struct tty_struct *tty, char c) | ||
| 3021 | { | ||
| 3022 | struct un_struct *un; | ||
| 3023 | struct ch_struct *ch; | ||
| 3024 | |||
| 3025 | if (!tty) | ||
| 3026 | return; | ||
| 3027 | |||
| 3028 | un = tty->driver_data; | ||
| 3029 | if (!un) | ||
| 3030 | return; | ||
| 3031 | |||
| 3032 | ch = un->un_ch; | ||
| 3033 | if (!ch) | ||
| 3034 | return; | ||
| 3035 | if (c == STOP_CHAR(tty)) | ||
| 3036 | ch->ch_send |= RR_RX_STOP; | ||
| 3037 | else if (c == START_CHAR(tty)) | ||
| 3038 | ch->ch_send |= RR_RX_START; | ||
| 3039 | |||
| 3040 | ch->ch_nd->nd_tx_ready = 1; | ||
| 3041 | ch->ch_nd->nd_tx_work = 1; | ||
| 3042 | |||
| 3043 | return; | ||
| 3044 | } | ||
| 3045 | |||
| 3046 | |||
| 3047 | static void dgrp_tty_input_start(struct tty_struct *tty) | ||
| 3048 | { | ||
| 3049 | struct ch_struct *ch; | ||
| 3050 | |||
| 3051 | if (!tty) | ||
| 3052 | return; | ||
| 3053 | |||
| 3054 | ch = ((struct un_struct *) tty->driver_data)->un_ch; | ||
| 3055 | if (!ch) | ||
| 3056 | return; | ||
| 3057 | |||
| 3058 | ch->ch_send |= RR_RX_START; | ||
| 3059 | ch->ch_send &= ~RR_RX_STOP; | ||
| 3060 | (ch->ch_nd)->nd_tx_ready = 1; | ||
| 3061 | (ch->ch_nd)->nd_tx_work = 1; | ||
| 3062 | if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq)) | ||
| 3063 | wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq); | ||
| 3064 | |||
| 3065 | } | ||
| 3066 | |||
| 3067 | |||
| 3068 | /* | ||
| 3069 | * Hangup the port. Like a close, but don't wait for output | ||
| 3070 | * to drain. | ||
| 3071 | * | ||
| 3072 | * How do we close all the channels that are open? | ||
| 3073 | */ | ||
| 3074 | static void dgrp_tty_hangup(struct tty_struct *tty) | ||
| 3075 | { | ||
| 3076 | struct ch_struct *ch; | ||
| 3077 | struct nd_struct *nd; | ||
| 3078 | struct un_struct *un; | ||
| 3079 | |||
| 3080 | if (!tty) | ||
| 3081 | return; | ||
| 3082 | |||
| 3083 | un = tty->driver_data; | ||
| 3084 | if (!un) | ||
| 3085 | return; | ||
| 3086 | |||
| 3087 | ch = un->un_ch; | ||
| 3088 | if (!ch) | ||
| 3089 | return; | ||
| 3090 | |||
| 3091 | nd = ch->ch_nd; | ||
| 3092 | |||
| 3093 | if (C_HUPCL(tty)) { | ||
| 3094 | /* LOWER DTR */ | ||
| 3095 | ch->ch_mout &= ~DM_DTR; | ||
| 3096 | /* Don't do this here */ | ||
| 3097 | /* ch->ch_flag |= CH_HANGUP; */ | ||
| 3098 | ch->ch_nd->nd_tx_ready = 1; | ||
| 3099 | ch->ch_nd->nd_tx_work = 1; | ||
| 3100 | if (waitqueue_active(&ch->ch_flag_wait)) | ||
| 3101 | wake_up_interruptible(&ch->ch_flag_wait); | ||
| 3102 | } | ||
| 3103 | |||
| 3104 | } | ||
| 3105 | |||
| 3106 | /************************************************************************/ | ||
| 3107 | /* */ | ||
| 3108 | /* TTY Initialization/Cleanup Functions */ | ||
| 3109 | /* */ | ||
| 3110 | /************************************************************************/ | ||
| 3111 | |||
| 3112 | /* | ||
| 3113 | * Uninitialize the TTY portion of the supplied node. Free all | ||
| 3114 | * memory and resources associated with this node. Do it in reverse | ||
| 3115 | * allocation order: this might possibly result in less fragmentation | ||
| 3116 | * of memory, though I don't know this for sure. | ||
| 3117 | */ | ||
| 3118 | void | ||
| 3119 | dgrp_tty_uninit(struct nd_struct *nd) | ||
| 3120 | { | ||
| 3121 | char id[3]; | ||
| 3122 | |||
| 3123 | ID_TO_CHAR(nd->nd_ID, id); | ||
| 3124 | |||
| 3125 | if (nd->nd_ttdriver_flags & SERIAL_TTDRV_REG) { | ||
| 3126 | tty_unregister_driver(nd->nd_serial_ttdriver); | ||
| 3127 | |||
| 3128 | kfree(nd->nd_serial_ttdriver->ttys); | ||
| 3129 | nd->nd_serial_ttdriver->ttys = NULL; | ||
| 3130 | |||
| 3131 | put_tty_driver(nd->nd_serial_ttdriver); | ||
| 3132 | nd->nd_ttdriver_flags &= ~SERIAL_TTDRV_REG; | ||
| 3133 | } | ||
| 3134 | |||
| 3135 | if (nd->nd_ttdriver_flags & CALLOUT_TTDRV_REG) { | ||
| 3136 | tty_unregister_driver(nd->nd_callout_ttdriver); | ||
| 3137 | |||
| 3138 | kfree(nd->nd_callout_ttdriver->ttys); | ||
| 3139 | nd->nd_callout_ttdriver->ttys = NULL; | ||
| 3140 | |||
| 3141 | put_tty_driver(nd->nd_callout_ttdriver); | ||
| 3142 | nd->nd_ttdriver_flags &= ~CALLOUT_TTDRV_REG; | ||
| 3143 | } | ||
| 3144 | |||
| 3145 | if (nd->nd_ttdriver_flags & XPRINT_TTDRV_REG) { | ||
| 3146 | tty_unregister_driver(nd->nd_xprint_ttdriver); | ||
| 3147 | |||
| 3148 | kfree(nd->nd_xprint_ttdriver->ttys); | ||
| 3149 | nd->nd_xprint_ttdriver->ttys = NULL; | ||
| 3150 | |||
| 3151 | put_tty_driver(nd->nd_xprint_ttdriver); | ||
| 3152 | nd->nd_ttdriver_flags &= ~XPRINT_TTDRV_REG; | ||
| 3153 | } | ||
| 3154 | } | ||
| 3155 | |||
| 3156 | |||
| 3157 | |||
| 3158 | /* | ||
| 3159 | * Initialize the TTY portion of the supplied node. | ||
| 3160 | */ | ||
| 3161 | int | ||
| 3162 | dgrp_tty_init(struct nd_struct *nd) | ||
| 3163 | { | ||
| 3164 | char id[3]; | ||
| 3165 | int rc; | ||
| 3166 | int i; | ||
| 3167 | |||
| 3168 | ID_TO_CHAR(nd->nd_ID, id); | ||
| 3169 | |||
| 3170 | /* | ||
| 3171 | * Initialize the TTDRIVER structures. | ||
| 3172 | */ | ||
| 3173 | |||
| 3174 | nd->nd_serial_ttdriver = alloc_tty_driver(CHAN_MAX); | ||
| 3175 | sprintf(nd->nd_serial_name, "tty_dgrp_%s_", id); | ||
| 3176 | |||
| 3177 | nd->nd_serial_ttdriver->owner = THIS_MODULE; | ||
| 3178 | nd->nd_serial_ttdriver->name = nd->nd_serial_name; | ||
| 3179 | nd->nd_serial_ttdriver->name_base = 0; | ||
| 3180 | nd->nd_serial_ttdriver->major = 0; | ||
| 3181 | nd->nd_serial_ttdriver->minor_start = 0; | ||
| 3182 | nd->nd_serial_ttdriver->type = TTY_DRIVER_TYPE_SERIAL; | ||
| 3183 | nd->nd_serial_ttdriver->subtype = SERIAL_TYPE_NORMAL; | ||
| 3184 | nd->nd_serial_ttdriver->init_termios = DefaultTermios; | ||
| 3185 | nd->nd_serial_ttdriver->driver_name = "dgrp"; | ||
| 3186 | nd->nd_serial_ttdriver->flags = (TTY_DRIVER_REAL_RAW | | ||
| 3187 | TTY_DRIVER_DYNAMIC_DEV | | ||
| 3188 | TTY_DRIVER_HARDWARE_BREAK); | ||
| 3189 | |||
| 3190 | /* The kernel wants space to store pointers to tty_structs. */ | ||
| 3191 | nd->nd_serial_ttdriver->ttys = | ||
| 3192 | kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL); | ||
| 3193 | if (!nd->nd_serial_ttdriver->ttys) | ||
| 3194 | return -ENOMEM; | ||
| 3195 | |||
| 3196 | tty_set_operations(nd->nd_serial_ttdriver, &dgrp_tty_ops); | ||
| 3197 | |||
| 3198 | if (!(nd->nd_ttdriver_flags & SERIAL_TTDRV_REG)) { | ||
| 3199 | /* | ||
| 3200 | * Register tty devices | ||
| 3201 | */ | ||
| 3202 | rc = tty_register_driver(nd->nd_serial_ttdriver); | ||
| 3203 | if (rc < 0) { | ||
| 3204 | /* | ||
| 3205 | * If errno is EBUSY, this means there are no more | ||
| 3206 | * slots available to have us auto-majored. | ||
| 3207 | * (Which is currently supported up to 256) | ||
| 3208 | * | ||
| 3209 | * We can still request majors above 256, | ||
| 3210 | * we just have to do it manually. | ||
| 3211 | */ | ||
| 3212 | if (rc == -EBUSY) { | ||
| 3213 | int i; | ||
| 3214 | int max_majors = 1U << (32 - MINORBITS); | ||
| 3215 | for (i = 256; i < max_majors; i++) { | ||
| 3216 | nd->nd_serial_ttdriver->major = i; | ||
| 3217 | rc = tty_register_driver(nd->nd_serial_ttdriver); | ||
| 3218 | if (rc >= 0) | ||
| 3219 | break; | ||
| 3220 | } | ||
| 3221 | /* Really fail now, since we ran out | ||
| 3222 | * of majors to try. */ | ||
| 3223 | if (i == max_majors) | ||
| 3224 | return rc; | ||
| 3225 | |||
| 3226 | } else { | ||
| 3227 | return rc; | ||
| 3228 | } | ||
| 3229 | } | ||
| 3230 | nd->nd_ttdriver_flags |= SERIAL_TTDRV_REG; | ||
| 3231 | } | ||
| 3232 | |||
| 3233 | nd->nd_callout_ttdriver = alloc_tty_driver(CHAN_MAX); | ||
| 3234 | sprintf(nd->nd_callout_name, "cu_dgrp_%s_", id); | ||
| 3235 | |||
| 3236 | nd->nd_callout_ttdriver->owner = THIS_MODULE; | ||
| 3237 | nd->nd_callout_ttdriver->name = nd->nd_callout_name; | ||
| 3238 | nd->nd_callout_ttdriver->name_base = 0; | ||
| 3239 | nd->nd_callout_ttdriver->major = nd->nd_serial_ttdriver->major; | ||
| 3240 | nd->nd_callout_ttdriver->minor_start = 0x40; | ||
| 3241 | nd->nd_callout_ttdriver->type = TTY_DRIVER_TYPE_SERIAL; | ||
| 3242 | nd->nd_callout_ttdriver->subtype = SERIAL_TYPE_CALLOUT; | ||
| 3243 | nd->nd_callout_ttdriver->init_termios = DefaultTermios; | ||
| 3244 | nd->nd_callout_ttdriver->driver_name = "dgrp"; | ||
| 3245 | nd->nd_callout_ttdriver->flags = (TTY_DRIVER_REAL_RAW | | ||
| 3246 | TTY_DRIVER_DYNAMIC_DEV | | ||
| 3247 | TTY_DRIVER_HARDWARE_BREAK); | ||
| 3248 | |||
| 3249 | /* The kernel wants space to store pointers to tty_structs. */ | ||
| 3250 | nd->nd_callout_ttdriver->ttys = | ||
| 3251 | kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL); | ||
| 3252 | if (!nd->nd_callout_ttdriver->ttys) | ||
| 3253 | return -ENOMEM; | ||
| 3254 | |||
| 3255 | tty_set_operations(nd->nd_callout_ttdriver, &dgrp_tty_ops); | ||
| 3256 | |||
| 3257 | if (dgrp_register_cudevices) { | ||
| 3258 | if (!(nd->nd_ttdriver_flags & CALLOUT_TTDRV_REG)) { | ||
| 3259 | /* | ||
| 3260 | * Register cu devices | ||
| 3261 | */ | ||
| 3262 | rc = tty_register_driver(nd->nd_callout_ttdriver); | ||
| 3263 | if (rc < 0) | ||
| 3264 | return rc; | ||
| 3265 | nd->nd_ttdriver_flags |= CALLOUT_TTDRV_REG; | ||
| 3266 | } | ||
| 3267 | } | ||
| 3268 | |||
| 3269 | |||
| 3270 | nd->nd_xprint_ttdriver = alloc_tty_driver(CHAN_MAX); | ||
| 3271 | sprintf(nd->nd_xprint_name, "pr_dgrp_%s_", id); | ||
| 3272 | |||
| 3273 | nd->nd_xprint_ttdriver->owner = THIS_MODULE; | ||
| 3274 | nd->nd_xprint_ttdriver->name = nd->nd_xprint_name; | ||
| 3275 | nd->nd_xprint_ttdriver->name_base = 0; | ||
| 3276 | nd->nd_xprint_ttdriver->major = nd->nd_serial_ttdriver->major; | ||
| 3277 | nd->nd_xprint_ttdriver->minor_start = 0x80; | ||
| 3278 | nd->nd_xprint_ttdriver->type = TTY_DRIVER_TYPE_SERIAL; | ||
| 3279 | nd->nd_xprint_ttdriver->subtype = SERIAL_TYPE_XPRINT; | ||
| 3280 | nd->nd_xprint_ttdriver->init_termios = DefaultTermios; | ||
| 3281 | nd->nd_xprint_ttdriver->driver_name = "dgrp"; | ||
| 3282 | nd->nd_xprint_ttdriver->flags = (TTY_DRIVER_REAL_RAW | | ||
| 3283 | TTY_DRIVER_DYNAMIC_DEV | | ||
| 3284 | TTY_DRIVER_HARDWARE_BREAK); | ||
| 3285 | |||
| 3286 | /* The kernel wants space to store pointers to tty_structs. */ | ||
| 3287 | nd->nd_xprint_ttdriver->ttys = | ||
| 3288 | kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL); | ||
| 3289 | if (!nd->nd_xprint_ttdriver->ttys) | ||
| 3290 | return -ENOMEM; | ||
| 3291 | |||
| 3292 | tty_set_operations(nd->nd_xprint_ttdriver, &dgrp_tty_ops); | ||
| 3293 | |||
| 3294 | if (dgrp_register_prdevices) { | ||
| 3295 | if (!(nd->nd_ttdriver_flags & XPRINT_TTDRV_REG)) { | ||
| 3296 | /* | ||
| 3297 | * Register transparent print devices | ||
| 3298 | */ | ||
| 3299 | rc = tty_register_driver(nd->nd_xprint_ttdriver); | ||
| 3300 | if (rc < 0) | ||
| 3301 | return rc; | ||
| 3302 | nd->nd_ttdriver_flags |= XPRINT_TTDRV_REG; | ||
| 3303 | } | ||
| 3304 | } | ||
| 3305 | |||
| 3306 | for (i = 0; i < CHAN_MAX; i++) { | ||
| 3307 | struct ch_struct *ch = nd->nd_chan + i; | ||
| 3308 | |||
| 3309 | ch->ch_nd = nd; | ||
| 3310 | ch->ch_digi = digi_init; | ||
| 3311 | ch->ch_edelay = 100; | ||
| 3312 | ch->ch_custom_speed = 0; | ||
| 3313 | ch->ch_portnum = i; | ||
| 3314 | ch->ch_tun.un_ch = ch; | ||
| 3315 | ch->ch_pun.un_ch = ch; | ||
| 3316 | ch->ch_tun.un_type = SERIAL_TYPE_NORMAL; | ||
| 3317 | ch->ch_pun.un_type = SERIAL_TYPE_XPRINT; | ||
| 3318 | |||
| 3319 | init_waitqueue_head(&(ch->ch_flag_wait)); | ||
| 3320 | init_waitqueue_head(&(ch->ch_sleep)); | ||
| 3321 | |||
| 3322 | init_waitqueue_head(&(ch->ch_tun.un_open_wait)); | ||
| 3323 | init_waitqueue_head(&(ch->ch_tun.un_close_wait)); | ||
| 3324 | |||
| 3325 | init_waitqueue_head(&(ch->ch_pun.un_open_wait)); | ||
| 3326 | init_waitqueue_head(&(ch->ch_pun.un_close_wait)); | ||
| 3327 | tty_port_init(&ch->port); | ||
| 3328 | tty_port_init(&ch->port); | ||
| 3329 | } | ||
| 3330 | return 0; | ||
| 3331 | } | ||
diff --git a/drivers/staging/dgrp/digirp.h b/drivers/staging/dgrp/digirp.h new file mode 100644 index 000000000000..33c1394fade7 --- /dev/null +++ b/drivers/staging/dgrp/digirp.h | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | /************************************************************************ | ||
| 2 | * HP-UX Realport Daemon interface file. | ||
| 3 | * | ||
| 4 | * Copyright (C) 1998, by Digi International. All Rights Reserved. | ||
| 5 | ************************************************************************/ | ||
| 6 | |||
| 7 | #ifndef _DIGIDRP_H | ||
| 8 | #define _DIGIDRP_H | ||
| 9 | |||
| 10 | /************************************************************************ | ||
| 11 | * This file contains defines for the ioctl() interface to | ||
| 12 | * the realport driver. This ioctl() interface is used by the | ||
| 13 | * daemon to set speed setup parameters honored by the driver. | ||
| 14 | ************************************************************************/ | ||
| 15 | |||
| 16 | struct link_struct { | ||
| 17 | int lk_fast_rate; /* Fast line rate to be used | ||
| 18 | when the delay is less-equal | ||
| 19 | to lk_fast_delay */ | ||
| 20 | |||
| 21 | int lk_fast_delay; /* Fast line rate delay in | ||
| 22 | milliseconds */ | ||
| 23 | |||
| 24 | int lk_slow_rate; /* Slow line rate to be used when | ||
| 25 | the delay is greater-equal | ||
| 26 | to lk_slow_delay */ | ||
| 27 | |||
| 28 | int lk_slow_delay; /* Slow line rate delay in | ||
| 29 | milliseconds */ | ||
| 30 | |||
| 31 | int lk_header_size; /* Estimated packet header size | ||
| 32 | when sent across the slowest | ||
| 33 | link. */ | ||
| 34 | }; | ||
| 35 | |||
| 36 | #define DIGI_GETLINK _IOW('e', 103, struct link_struct) /* Get link parameters */ | ||
| 37 | #define DIGI_SETLINK _IOW('e', 104, struct link_struct) /* Set link parameters */ | ||
| 38 | |||
| 39 | |||
| 40 | /************************************************************************ | ||
| 41 | * This module provides application access to special Digi | ||
| 42 | * serial line enhancements which are not standard UNIX(tm) features. | ||
| 43 | ************************************************************************/ | ||
| 44 | |||
| 45 | struct digiflow_struct { | ||
| 46 | unsigned char startc; /* flow cntl start char */ | ||
| 47 | unsigned char stopc; /* flow cntl stop char */ | ||
| 48 | }; | ||
| 49 | |||
| 50 | /************************************************************************ | ||
| 51 | * Values for digi_flags | ||
| 52 | ************************************************************************/ | ||
| 53 | #define DIGI_IXON 0x0001 /* Handle IXON in the FEP */ | ||
| 54 | #define DIGI_FAST 0x0002 /* Fast baud rates */ | ||
| 55 | #define RTSPACE 0x0004 /* RTS input flow control */ | ||
| 56 | #define CTSPACE 0x0008 /* CTS output flow control */ | ||
| 57 | #define DSRPACE 0x0010 /* DSR output flow control */ | ||
| 58 | #define DCDPACE 0x0020 /* DCD output flow control */ | ||
| 59 | #define DTRPACE 0x0040 /* DTR input flow control */ | ||
| 60 | #define DIGI_COOK 0x0080 /* Cooked processing done in FEP */ | ||
| 61 | #define DIGI_FORCEDCD 0x0100 /* Force carrier */ | ||
| 62 | #define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */ | ||
| 63 | #define DIGI_AIXON 0x0400 /* Aux flow control in fep */ | ||
| 64 | #define DIGI_PRINTER 0x0800 /* Hold port open for flow cntrl */ | ||
| 65 | #define DIGI_PP_INPUT 0x1000 /* Change parallel port to input */ | ||
| 66 | #define DIGI_422 0x4000 /* Change parallel port to input */ | ||
| 67 | #define DIGI_RTS_TOGGLE 0x8000 /* Support RTS Toggle */ | ||
| 68 | |||
| 69 | |||
| 70 | /************************************************************************ | ||
| 71 | * Values associated with transparent print | ||
| 72 | ************************************************************************/ | ||
| 73 | #define DIGI_PLEN 8 /* String length */ | ||
| 74 | #define DIGI_TSIZ 10 /* Terminal string len */ | ||
| 75 | |||
| 76 | |||
| 77 | /************************************************************************ | ||
| 78 | * Structure used with ioctl commands for DIGI parameters. | ||
| 79 | ************************************************************************/ | ||
| 80 | struct digi_struct { | ||
| 81 | unsigned short digi_flags; /* Flags (see above) */ | ||
| 82 | unsigned short digi_maxcps; /* Max printer CPS */ | ||
| 83 | unsigned short digi_maxchar; /* Max chars in print queue */ | ||
| 84 | unsigned short digi_bufsize; /* Buffer size */ | ||
| 85 | unsigned char digi_onlen; /* Length of ON string */ | ||
| 86 | unsigned char digi_offlen; /* Length of OFF string */ | ||
| 87 | char digi_onstr[DIGI_PLEN]; /* Printer on string */ | ||
| 88 | char digi_offstr[DIGI_PLEN]; /* Printer off string */ | ||
| 89 | char digi_term[DIGI_TSIZ]; /* terminal string */ | ||
| 90 | }; | ||
| 91 | |||
| 92 | /************************************************************************ | ||
| 93 | * Ioctl command arguments for DIGI parameters. | ||
| 94 | ************************************************************************/ | ||
| 95 | /* Read params */ | ||
| 96 | #define DIGI_GETA _IOR('e', 94, struct digi_struct) | ||
| 97 | |||
| 98 | /* Set params */ | ||
| 99 | #define DIGI_SETA _IOW('e', 95, struct digi_struct) | ||
| 100 | |||
| 101 | /* Drain & set params */ | ||
| 102 | #define DIGI_SETAW _IOW('e', 96, struct digi_struct) | ||
| 103 | |||
| 104 | /* Drain, flush & set params */ | ||
| 105 | #define DIGI_SETAF _IOW('e', 97, struct digi_struct) | ||
| 106 | |||
| 107 | /* Get startc/stopc flow control characters */ | ||
| 108 | #define DIGI_GETFLOW _IOR('e', 99, struct digiflow_struct) | ||
| 109 | |||
| 110 | /* Set startc/stopc flow control characters */ | ||
| 111 | #define DIGI_SETFLOW _IOW('e', 100, struct digiflow_struct) | ||
| 112 | |||
| 113 | /* Get Aux. startc/stopc flow control chars */ | ||
| 114 | #define DIGI_GETAFLOW _IOR('e', 101, struct digiflow_struct) | ||
| 115 | |||
| 116 | /* Set Aux. startc/stopc flow control chars */ | ||
| 117 | #define DIGI_SETAFLOW _IOW('e', 102, struct digiflow_struct) | ||
| 118 | |||
| 119 | /* Set integer baud rate */ | ||
| 120 | #define DIGI_SETCUSTOMBAUD _IOW('e', 106, int) | ||
| 121 | |||
| 122 | /* Get integer baud rate */ | ||
| 123 | #define DIGI_GETCUSTOMBAUD _IOR('e', 107, int) | ||
| 124 | |||
| 125 | #define DIGI_GEDELAY _IOR('d', 246, int) /* Get edelay */ | ||
| 126 | #define DIGI_SEDELAY _IOW('d', 247, int) /* Get edelay */ | ||
| 127 | |||
| 128 | |||
| 129 | #endif /* _DIGIDRP_H */ | ||
diff --git a/drivers/staging/dgrp/drp.h b/drivers/staging/dgrp/drp.h new file mode 100644 index 000000000000..84a1e7be4899 --- /dev/null +++ b/drivers/staging/dgrp/drp.h | |||
| @@ -0,0 +1,693 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright 1999 Digi International (www.digi.com) | ||
| 4 | * Gene Olson <gene at digi dot com> | ||
| 5 | * James Puzzo <jamesp at digi dot com> | ||
| 6 | * Scott Kilau <scottk at digi dot com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 11 | * any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the | ||
| 15 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | ||
| 16 | * PURPOSE. See the GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | */ | ||
| 19 | |||
| 20 | /************************************************************************ | ||
| 21 | * Master include file for Linux Realport Driver. | ||
| 22 | ************************************************************************/ | ||
| 23 | |||
| 24 | #ifndef __DRP_H | ||
| 25 | #define __DRP_H | ||
| 26 | |||
| 27 | #include <linux/types.h> | ||
| 28 | #include <linux/wait.h> | ||
| 29 | #include <linux/semaphore.h> | ||
| 30 | #include <linux/tty.h> | ||
| 31 | |||
| 32 | |||
| 33 | #include "digirp.h" | ||
| 34 | |||
| 35 | /************************************************************************ | ||
| 36 | * Tuning parameters. | ||
| 37 | ************************************************************************/ | ||
| 38 | |||
| 39 | #define CHAN_MAX 64 /* Max # ports per server */ | ||
| 40 | |||
| 41 | #define SEQ_MAX 128 /* Max # transmit sequences (2^n) */ | ||
| 42 | #define SEQ_MASK (SEQ_MAX-1) /* Sequence buffer modulus mask */ | ||
| 43 | |||
| 44 | #define TBUF_MAX 4096 /* Size of transmit buffer (2^n) */ | ||
| 45 | #define RBUF_MAX 4096 /* Size of receive buffer (2^n) */ | ||
| 46 | |||
| 47 | #define TBUF_MASK (TBUF_MAX-1) /* Transmit buffer modulus mask */ | ||
| 48 | #define RBUF_MASK (RBUF_MAX-1) /* Receive buffer modulus mask */ | ||
| 49 | |||
| 50 | #define TBUF_LOW 1000 /* Transmit low water mark */ | ||
| 51 | |||
| 52 | #define UIO_BASE 1000 /* Base for write operations */ | ||
| 53 | #define UIO_MIN 2000 /* Minimum size application buffer */ | ||
| 54 | #define UIO_MAX 8100 /* Unix I/O buffer size */ | ||
| 55 | |||
| 56 | #define MON_MAX 65536 /* Monitor buffer size (2^n) */ | ||
| 57 | #define MON_MASK (MON_MAX-1) /* Monitor wrap mask */ | ||
| 58 | |||
| 59 | #define DPA_MAX 65536 /* DPA buffer size (2^n) */ | ||
| 60 | #define DPA_MASK (DPA_MAX-1) /* DPA wrap mask */ | ||
| 61 | #define DPA_HIGH_WATER 58000 /* Enforce flow control when | ||
| 62 | * over this amount | ||
| 63 | */ | ||
| 64 | |||
| 65 | #define IDLE_MAX (20 * HZ) /* Max TCP link idle time */ | ||
| 66 | |||
| 67 | #define MAX_DESC_LEN 100 /* Maximum length of stored PS | ||
| 68 | * description | ||
| 69 | */ | ||
| 70 | |||
| 71 | #define WRITEBUFLEN ((4096) + 4) /* 4 extra for alignment play space */ | ||
| 72 | |||
| 73 | #define VPDSIZE 512 | ||
| 74 | |||
| 75 | /************************************************************************ | ||
| 76 | * Minor device decoding conventions. | ||
| 77 | ************************************************************************ | ||
| 78 | * | ||
| 79 | * For Linux, the net and mon devices are handled via "proc", so we | ||
| 80 | * only have to mux the "tty" devices. Since every PortServer will | ||
| 81 | * have an individual major number, the PortServer number does not | ||
| 82 | * need to be encoded, and in fact, does not need to exist. | ||
| 83 | * | ||
| 84 | */ | ||
| 85 | |||
| 86 | /* | ||
| 87 | * Port device decoding conventions: | ||
| 88 | * | ||
| 89 | * Device 00 - 3f 64 dial-in modem devices. (tty) | ||
| 90 | * Device 40 - 7f 64 dial-out tty devices. (cu) | ||
| 91 | * Device 80 - bf 64 dial-out printer devices. | ||
| 92 | * | ||
| 93 | * IS_PRINT(dev) This is a printer device. | ||
| 94 | * | ||
| 95 | * OPEN_CATEGORY(dev) Specifies the device category. No two | ||
| 96 | * devices of different categories may be open | ||
| 97 | * at the same time. | ||
| 98 | * | ||
| 99 | * The following require the category returned by OPEN_CATEGORY(). | ||
| 100 | * | ||
| 101 | * OPEN_WAIT_AVAIL(cat) Waits on open until the device becomes | ||
| 102 | * available. Fails if NDELAY specified. | ||
| 103 | * | ||
| 104 | * OPEN_WAIT_CARRIER(cat) Waits on open if carrier is not present. | ||
| 105 | * Succeeds if NDELAY is given. | ||
| 106 | * | ||
| 107 | * OPEN_FORCES_CARRIER(cat) Carrier is forced high on open. | ||
| 108 | * | ||
| 109 | */ | ||
| 110 | |||
| 111 | #define PORT_NUM(dev) ((dev) & 0x3f) | ||
| 112 | |||
| 113 | #define OPEN_CATEGORY(dev) ((((dev) & 0x80) & 0x40)) | ||
| 114 | #define IS_PRINT(dev) (((dev) & 0xff) >= 0x80) | ||
| 115 | |||
| 116 | #define OPEN_WAIT_AVAIL(cat) (((cat) & 0x40) == 0x000) | ||
| 117 | #define OPEN_WAIT_CARRIER(cat) (((cat) & 0x40) == 0x000) | ||
| 118 | #define OPEN_FORCES_CARRIER(cat) (((cat) & 0x40) != 0x000) | ||
| 119 | |||
| 120 | |||
| 121 | /************************************************************************ | ||
| 122 | * Modem signal defines for 16450/16550 compatible FEP. | ||
| 123 | * set in ch_mout, ch_mflow, ch_mlast etc | ||
| 124 | ************************************************************************/ | ||
| 125 | |||
| 126 | /* TODO : Re-verify that these modem signal definitions are correct */ | ||
| 127 | |||
| 128 | #define DM_DTR 0x01 | ||
| 129 | #define DM_RTS 0x02 | ||
| 130 | #define DM_RTS_TOGGLE 0x04 | ||
| 131 | |||
| 132 | #define DM_OUT1 0x04 | ||
| 133 | #define DM_OUT2 0x08 | ||
| 134 | |||
| 135 | #define DM_CTS 0x10 | ||
| 136 | #define DM_DSR 0x20 | ||
| 137 | #define DM_RI 0x40 | ||
| 138 | #define DM_CD 0x80 /* This is the DCD flag */ | ||
| 139 | |||
| 140 | |||
| 141 | /************************************************************************ | ||
| 142 | * Realport Event Flags. | ||
| 143 | ************************************************************************/ | ||
| 144 | |||
| 145 | #define EV_OPU 0x0001 /* Ouput paused by client */ | ||
| 146 | #define EV_OPS 0x0002 /* Output paused by XOFF */ | ||
| 147 | #define EV_OPX 0x0004 /* Output paused by XXOFF */ | ||
| 148 | #define EV_OPH 0x0008 /* Output paused by MFLOW */ | ||
| 149 | #define EV_IPU 0x0010 /* Input paused by client */ | ||
| 150 | #define EV_IPS 0x0020 /* Input paused by hi/low water */ | ||
| 151 | #define EV_TXB 0x0040 /* Transmit break pending */ | ||
| 152 | #define EV_TXI 0x0080 /* Transmit immediate pending */ | ||
| 153 | #define EV_TXF 0x0100 /* Transmit flow control pending */ | ||
| 154 | #define EV_RXB 0x0200 /* Break received */ | ||
| 155 | |||
| 156 | |||
| 157 | /************************************************************************ | ||
| 158 | * Realport CFLAGS. | ||
| 159 | ************************************************************************/ | ||
| 160 | |||
| 161 | #define CF_CS5 0x0000 /* 5 bit characters */ | ||
| 162 | #define CF_CS6 0x0010 /* 6 bit characters */ | ||
| 163 | #define CF_CS7 0x0020 /* 7 bit characters */ | ||
| 164 | #define CF_CS8 0x0030 /* 8 bit characters */ | ||
| 165 | #define CF_CSIZE 0x0030 /* Character size */ | ||
| 166 | #define CF_CSTOPB 0x0040 /* Two stop bits */ | ||
| 167 | #define CF_CREAD 0x0080 /* Enable receiver */ | ||
| 168 | #define CF_PARENB 0x0100 /* Enable parity */ | ||
| 169 | #define CF_PARODD 0x0200 /* Odd parity */ | ||
| 170 | #define CF_HUPCL 0x0400 /* Drop DTR on close */ | ||
| 171 | |||
| 172 | |||
| 173 | /************************************************************************ | ||
| 174 | * Realport XFLAGS. | ||
| 175 | ************************************************************************/ | ||
| 176 | |||
| 177 | #define XF_XPAR 0x0001 /* Enable Mark/Space Parity */ | ||
| 178 | #define XF_XMODEM 0x0002 /* Enable in-band modem signalling */ | ||
| 179 | #define XF_XCASE 0x0004 /* Convert special characters */ | ||
| 180 | #define XF_XEDATA 0x0008 /* Error data in stream */ | ||
| 181 | #define XF_XTOSS 0x0010 /* Toss IXANY characters */ | ||
| 182 | #define XF_XIXON 0x0020 /* xxon/xxoff enable */ | ||
| 183 | |||
| 184 | |||
| 185 | /************************************************************************ | ||
| 186 | * Realport IFLAGS. | ||
| 187 | ************************************************************************/ | ||
| 188 | |||
| 189 | #define IF_IGNBRK 0x0001 /* Ignore input break */ | ||
| 190 | #define IF_BRKINT 0x0002 /* Break interrupt */ | ||
| 191 | #define IF_IGNPAR 0x0004 /* Ignore error characters */ | ||
| 192 | #define IF_PARMRK 0x0008 /* Error chars marked with 0xff */ | ||
| 193 | #define IF_INPCK 0x0010 /* Input parity checking enabled */ | ||
| 194 | #define IF_ISTRIP 0x0020 /* Input chars masked with 0x7F */ | ||
| 195 | #define IF_IXON 0x0400 /* Output software flow control */ | ||
| 196 | #define IF_IXANY 0x0800 /* Restart output on any char */ | ||
| 197 | #define IF_IXOFF 0x1000 /* Input software flow control */ | ||
| 198 | #define IF_DOSMODE 0x8000 /* 16450-compatible errors */ | ||
| 199 | |||
| 200 | |||
| 201 | /************************************************************************ | ||
| 202 | * Realport OFLAGS. | ||
| 203 | ************************************************************************/ | ||
| 204 | |||
| 205 | #define OF_OLCUC 0x0002 /* Map lower to upper case */ | ||
| 206 | #define OF_ONLCR 0x0004 /* Map NL to CR-NL */ | ||
| 207 | #define OF_OCRNL 0x0008 /* Map CR to NL */ | ||
| 208 | #define OF_ONOCR 0x0010 /* No CR output at column 0 */ | ||
| 209 | #define OF_ONLRET 0x0020 /* Assume NL does NL/CR */ | ||
| 210 | #define OF_TAB3 0x1800 /* Tabs expand to 8 spaces */ | ||
| 211 | #define OF_TABDLY 0x1800 /* Tab delay */ | ||
| 212 | |||
| 213 | /************************************************************************ | ||
| 214 | * Unit flag definitions for un_flag. | ||
| 215 | ************************************************************************/ | ||
| 216 | |||
| 217 | /* These are the DIGI unit flags */ | ||
| 218 | #define UN_EXCL 0x00010000 /* Exclusive open */ | ||
| 219 | #define UN_STICKY 0x00020000 /* TTY Settings are now sticky */ | ||
| 220 | #define UN_BUSY 0x00040000 /* Some work this channel */ | ||
| 221 | #define UN_PWAIT 0x00080000 /* Printer waiting for terminal */ | ||
| 222 | #define UN_TIME 0x00100000 /* Waiting on time */ | ||
| 223 | #define UN_EMPTY 0x00200000 /* Waiting output queue empty */ | ||
| 224 | #define UN_LOW 0x00400000 /* Waiting output low water */ | ||
| 225 | #define UN_DIGI_MASK 0x00FF0000 /* Waiting output low water */ | ||
| 226 | |||
| 227 | /* | ||
| 228 | * Definitions for async_struct (and serial_struct) flags field | ||
| 229 | * | ||
| 230 | * these are the ASYNC flags copied from serial.h | ||
| 231 | * | ||
| 232 | */ | ||
| 233 | #define UN_HUP_NOTIFY 0x0001 /* Notify getty on hangups and | ||
| 234 | * closes on the callout port | ||
| 235 | */ | ||
| 236 | #define UN_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */ | ||
| 237 | #define UN_SAK 0x0004 /* Secure Attention Key (Orange book) */ | ||
| 238 | #define UN_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */ | ||
| 239 | |||
| 240 | #define UN_SPD_MASK 0x0030 | ||
| 241 | #define UN_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */ | ||
| 242 | #define UN_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */ | ||
| 243 | #define UN_SPD_CUST 0x0030 /* Use user-specified divisor */ | ||
| 244 | |||
| 245 | #define UN_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */ | ||
| 246 | #define UN_AUTO_IRQ 0x0080 /* Do automatic IRQ during autoconfiguration */ | ||
| 247 | |||
| 248 | #define UN_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */ | ||
| 249 | #define UN_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */ | ||
| 250 | #define UN_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */ | ||
| 251 | |||
| 252 | #define UN_FLAGS 0x0FFF /* Possible legal async flags */ | ||
| 253 | #define UN_USR_MASK 0x0430 /* Legal flags that non-privileged | ||
| 254 | * users can set or reset | ||
| 255 | */ | ||
| 256 | |||
| 257 | #define UN_INITIALIZED 0x80000000 /* Serial port was initialized */ | ||
| 258 | #define UN_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */ | ||
| 259 | #define UN_NORMAL_ACTIVE 0x20000000 /* Normal device is active */ | ||
| 260 | #define UN_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */ | ||
| 261 | #define UN_CLOSING 0x08000000 /* Serial port is closing */ | ||
| 262 | #define UN_CTS_FLOW 0x04000000 /* Do CTS flow control */ | ||
| 263 | #define UN_CHECK_CD 0x02000000 /* i.e., CLOCAL */ | ||
| 264 | #define UN_SHARE_IRQ 0x01000000 /* for multifunction cards */ | ||
| 265 | |||
| 266 | |||
| 267 | /************************************************************************ | ||
| 268 | * Structure for terminal or printer unit. struct un_struct | ||
| 269 | * | ||
| 270 | * Note that in some places the code assumes the "tty_t" is placed | ||
| 271 | * first in the structure. | ||
| 272 | ************************************************************************/ | ||
| 273 | |||
| 274 | struct un_struct { | ||
| 275 | struct tty_struct *un_tty; /* System TTY struct */ | ||
| 276 | struct ch_struct *un_ch; /* Associated channel */ | ||
| 277 | |||
| 278 | ushort un_open_count; /* Successful open count */ | ||
| 279 | int un_flag; /* Unit flags */ | ||
| 280 | ushort un_tbusy; /* Busy transmit count */ | ||
| 281 | |||
| 282 | wait_queue_head_t un_open_wait; | ||
| 283 | wait_queue_head_t un_close_wait; | ||
| 284 | ushort un_type; | ||
| 285 | struct device *un_sysfs; | ||
| 286 | }; | ||
| 287 | |||
| 288 | |||
| 289 | /************************************************************************ | ||
| 290 | * Channel State Numbers for ch_state. | ||
| 291 | ************************************************************************/ | ||
| 292 | |||
| 293 | /* | ||
| 294 | * The ordering is important. | ||
| 295 | * | ||
| 296 | * state <= CS_WAIT_CANCEL implies the channel is definitely closed. | ||
| 297 | * | ||
| 298 | * state >= CS_WAIT_FAIL implies the channel is definitely open. | ||
| 299 | * | ||
| 300 | * state >= CS_READY implies data is allowed on the channel. | ||
| 301 | */ | ||
| 302 | |||
| 303 | enum dgrp_ch_state_t { | ||
| 304 | CS_IDLE = 0, /* Channel is idle */ | ||
| 305 | CS_WAIT_OPEN = 1, /* Waiting for Immediate Open Resp */ | ||
| 306 | CS_WAIT_CANCEL = 2, /* Waiting for Per/Incom Cancel Resp */ | ||
| 307 | CS_WAIT_FAIL = 3, /* Waiting for Immed Open Failure */ | ||
| 308 | CS_SEND_QUERY = 4, /* Ready to send Port Query */ | ||
| 309 | CS_WAIT_QUERY = 5, /* Waiting for Port Query Response */ | ||
| 310 | CS_READY = 6, /* Ready to accept commands and data */ | ||
| 311 | CS_SEND_CLOSE = 7, /* Ready to send Close Request */ | ||
| 312 | CS_WAIT_CLOSE = 8 /* Waiting for Close Response */ | ||
| 313 | }; | ||
| 314 | |||
| 315 | /************************************************************************ | ||
| 316 | * Device flag definitions for ch_flag. | ||
| 317 | ************************************************************************/ | ||
| 318 | |||
| 319 | /* | ||
| 320 | * Note that the state of the two carrier based flags is key. When | ||
| 321 | * we check for carrier state transitions, we look at the current | ||
| 322 | * physical state of the DCD line and compare it with PHYS_CD (which | ||
| 323 | * was the state the last time we checked), and we also determine | ||
| 324 | * a new virtual state (composite of the physical state, FORCEDCD, | ||
| 325 | * CLOCAL, etc.) and compare it with VIRT_CD. | ||
| 326 | * | ||
| 327 | * VIRTUAL transitions high will have the side effect of waking blocked | ||
| 328 | * opens. | ||
| 329 | * | ||
| 330 | * PHYSICAL transitions low will cause hangups to occur _IF_ the virtual | ||
| 331 | * state is also low. We DON'T want to hangup on a PURE virtual drop. | ||
| 332 | */ | ||
| 333 | |||
| 334 | #define CH_HANGUP 0x00002 /* Server port ready to close */ | ||
| 335 | |||
| 336 | #define CH_VIRT_CD 0x00004 /* Carrier was virtually present */ | ||
| 337 | #define CH_PHYS_CD 0x00008 /* Carrier was physically present */ | ||
| 338 | |||
| 339 | #define CH_CLOCAL 0x00010 /* CLOCAL set in cflags */ | ||
| 340 | #define CH_BAUD0 0x00020 /* Baud rate zero hangup */ | ||
| 341 | |||
| 342 | #define CH_FAST_READ 0x00040 /* Fast reads are enabled */ | ||
| 343 | #define CH_FAST_WRITE 0x00080 /* Fast writes are enabled */ | ||
| 344 | |||
| 345 | #define CH_PRON 0x00100 /* Printer on string active */ | ||
| 346 | #define CH_RX_FLUSH 0x00200 /* Flushing receive data */ | ||
| 347 | #define CH_LOW 0x00400 /* Thread waiting for LOW water */ | ||
| 348 | #define CH_EMPTY 0x00800 /* Thread waiting for EMPTY */ | ||
| 349 | #define CH_DRAIN 0x01000 /* Close is waiting to drain */ | ||
| 350 | #define CH_INPUT 0x02000 /* Thread waiting for INPUT */ | ||
| 351 | #define CH_RXSTOP 0x04000 /* Stop output to ldisc */ | ||
| 352 | #define CH_PARAM 0x08000 /* A parameter was updated */ | ||
| 353 | #define CH_WAITING_SYNC 0x10000 /* A pending sync was assigned | ||
| 354 | * to this port. | ||
| 355 | */ | ||
| 356 | #define CH_PORT_GONE 0x20000 /* Port has disappeared */ | ||
| 357 | #define CH_TX_BREAK 0x40000 /* TX Break to be sent, | ||
| 358 | * but has not yet. | ||
| 359 | */ | ||
| 360 | |||
| 361 | /************************************************************************ | ||
| 362 | * Types of Open Requests for ch_otype. | ||
| 363 | ************************************************************************/ | ||
| 364 | |||
| 365 | #define OTYPE_IMMEDIATE 0 /* Immediate Open */ | ||
| 366 | #define OTYPE_PERSISTENT 1 /* Persistent Open */ | ||
| 367 | #define OTYPE_INCOMING 2 /* Incoming Open */ | ||
| 368 | |||
| 369 | |||
| 370 | /************************************************************************ | ||
| 371 | * Request/Response flags. | ||
| 372 | ************************************************************************/ | ||
| 373 | |||
| 374 | #define RR_SEQUENCE 0x0001 /* Get server RLAST, TIN */ | ||
| 375 | #define RR_STATUS 0x0002 /* Get server MINT, EINT */ | ||
| 376 | #define RR_BUFFER 0x0004 /* Get server RSIZE, TSIZE */ | ||
| 377 | #define RR_CAPABILITY 0x0008 /* Get server port capabilities */ | ||
| 378 | |||
| 379 | #define RR_TX_FLUSH 0x0040 /* Flush output buffers */ | ||
| 380 | #define RR_RX_FLUSH 0x0080 /* Flush input buffers */ | ||
| 381 | |||
| 382 | #define RR_TX_STOP 0x0100 /* Pause output */ | ||
| 383 | #define RR_RX_STOP 0x0200 /* Pause input */ | ||
| 384 | #define RR_TX_START 0x0400 /* Start output */ | ||
| 385 | #define RR_RX_START 0x0800 /* Start input */ | ||
| 386 | |||
| 387 | #define RR_TX_BREAK 0x1000 /* Send BREAK */ | ||
| 388 | #define RR_TX_ICHAR 0x2000 /* Send character immediate */ | ||
| 389 | |||
| 390 | |||
| 391 | /************************************************************************ | ||
| 392 | * Channel information structure. struct ch_struct | ||
| 393 | ************************************************************************/ | ||
| 394 | |||
| 395 | struct ch_struct { | ||
| 396 | struct digi_struct ch_digi; /* Digi variables */ | ||
| 397 | int ch_edelay; /* Digi edelay */ | ||
| 398 | |||
| 399 | struct tty_port port; | ||
| 400 | struct un_struct ch_tun; /* Terminal unit info */ | ||
| 401 | struct un_struct ch_pun; /* Printer unit info */ | ||
| 402 | |||
| 403 | struct nd_struct *ch_nd; /* Node pointer */ | ||
| 404 | u8 *ch_tbuf; /* Local Transmit Buffer */ | ||
| 405 | u8 *ch_rbuf; /* Local Receive Buffer */ | ||
| 406 | ulong ch_cpstime; /* Printer CPS time */ | ||
| 407 | ulong ch_waketime; /* Printer wake time */ | ||
| 408 | |||
| 409 | ulong ch_flag; /* CH_* flags */ | ||
| 410 | |||
| 411 | enum dgrp_ch_state_t ch_state; /* CS_* Protocol state */ | ||
| 412 | ushort ch_send; /* Bit vector of RR_* requests */ | ||
| 413 | ushort ch_expect; /* Bit vector of RR_* responses */ | ||
| 414 | ushort ch_wait_carrier; /* Thread count waiting for carrier */ | ||
| 415 | ushort ch_wait_count[3]; /* Thread count waiting by otype */ | ||
| 416 | |||
| 417 | ushort ch_portnum; /* Port number */ | ||
| 418 | ushort ch_open_count; /* Successful open count */ | ||
| 419 | ushort ch_category; /* Device category */ | ||
| 420 | ushort ch_open_error; /* Last open error number */ | ||
| 421 | ushort ch_break_time; /* Pending break request time */ | ||
| 422 | ushort ch_cpsrem; /* Printer CPS remainder */ | ||
| 423 | ushort ch_ocook; /* Realport fastcook oflags */ | ||
| 424 | ushort ch_inwait; /* Thread count in CLIST input */ | ||
| 425 | |||
| 426 | ushort ch_tin; /* Local transmit buffer in ptr */ | ||
| 427 | ushort ch_tout; /* Local transmit buffer out ptr */ | ||
| 428 | ushort ch_s_tin; /* Realport TIN */ | ||
| 429 | ushort ch_s_tpos; /* Realport TPOS */ | ||
| 430 | ushort ch_s_tsize; /* Realport TSIZE */ | ||
| 431 | ushort ch_s_treq; /* Realport TREQ */ | ||
| 432 | ushort ch_s_elast; /* Realport ELAST */ | ||
| 433 | |||
| 434 | ushort ch_rin; /* Local receive buffer in ptr */ | ||
| 435 | ushort ch_rout; /* Local receive buffer out ptr */ | ||
| 436 | ushort ch_s_rin; /* Realport RIN */ | ||
| 437 | /* David Fries 7-13-2001, ch_s_rin should be renamed ch_s_rout because | ||
| 438 | * the variable we want to represent is the PortServer's ROUT, which is | ||
| 439 | * the sequence number for the next byte the PortServer will send us. | ||
| 440 | * RIN is the sequence number for the next byte the PortServer will | ||
| 441 | * receive from the uart. The port server will send data as long as | ||
| 442 | * ROUT is less than RWIN. What would happen is the port is opened, it | ||
| 443 | * receives data, it gives the value of RIN, we set the RWIN to | ||
| 444 | * RIN+RBUF_MAX-1, it sends us RWIN-ROUT bytes which overflows. ROUT | ||
| 445 | * is set to zero when the port is opened, so we start at zero and | ||
| 446 | * count up as data is received. | ||
| 447 | */ | ||
| 448 | ushort ch_s_rwin; /* Realport RWIN */ | ||
| 449 | ushort ch_s_rsize; /* Realport RSIZE */ | ||
| 450 | |||
| 451 | ushort ch_tmax; /* Local TMAX */ | ||
| 452 | ushort ch_ttime; /* Local TTIME */ | ||
| 453 | ushort ch_rmax; /* Local RMAX */ | ||
| 454 | ushort ch_rtime; /* Local RTIME */ | ||
| 455 | ushort ch_rlow; /* Local RLOW */ | ||
| 456 | ushort ch_rhigh; /* Local RHIGH */ | ||
| 457 | |||
| 458 | ushort ch_s_tmax; /* Realport TMAX */ | ||
| 459 | ushort ch_s_ttime; /* Realport TTIME */ | ||
| 460 | ushort ch_s_rmax; /* Realport RMAX */ | ||
| 461 | ushort ch_s_rtime; /* Realport RTIME */ | ||
| 462 | ushort ch_s_rlow; /* Realport RLOW */ | ||
| 463 | ushort ch_s_rhigh; /* Realport RHIGH */ | ||
| 464 | |||
| 465 | ushort ch_brate; /* Local baud rate */ | ||
| 466 | ushort ch_cflag; /* Local tty cflags */ | ||
| 467 | ushort ch_iflag; /* Local tty iflags */ | ||
| 468 | ushort ch_oflag; /* Local tty oflags */ | ||
| 469 | ushort ch_xflag; /* Local tty xflags */ | ||
| 470 | |||
| 471 | ushort ch_s_brate; /* Realport BRATE */ | ||
| 472 | ushort ch_s_cflag; /* Realport CFLAG */ | ||
| 473 | ushort ch_s_iflag; /* Realport IFLAG */ | ||
| 474 | ushort ch_s_oflag; /* Realport OFLAG */ | ||
| 475 | ushort ch_s_xflag; /* Realport XFLAG */ | ||
| 476 | |||
| 477 | u8 ch_otype; /* Open request type */ | ||
| 478 | u8 ch_pscan_savechar; /* Last character read by parity scan */ | ||
| 479 | u8 ch_pscan_state; /* PScan State based on last 2 chars */ | ||
| 480 | u8 ch_otype_waiting; /* Type of open pending in server */ | ||
| 481 | u8 ch_flush_seq; /* Receive flush end sequence */ | ||
| 482 | u8 ch_s_mlast; /* Realport MLAST */ | ||
| 483 | |||
| 484 | u8 ch_mout; /* Local MOUT */ | ||
| 485 | u8 ch_mflow; /* Local MFLOW */ | ||
| 486 | u8 ch_mctrl; /* Local MCTRL */ | ||
| 487 | u8 ch_xon; /* Local XON */ | ||
| 488 | u8 ch_xoff; /* Local XOFF */ | ||
| 489 | u8 ch_lnext; /* Local LNEXT */ | ||
| 490 | u8 ch_xxon; /* Local XXON */ | ||
| 491 | u8 ch_xxoff; /* Local XXOFF */ | ||
| 492 | |||
| 493 | u8 ch_s_mout; /* Realport MOUT */ | ||
| 494 | u8 ch_s_mflow; /* Realport MFLOW */ | ||
| 495 | u8 ch_s_mctrl; /* Realport MCTRL */ | ||
| 496 | u8 ch_s_xon; /* Realport XON */ | ||
| 497 | u8 ch_s_xoff; /* Realport XOFF */ | ||
| 498 | u8 ch_s_lnext; /* Realport LNEXT */ | ||
| 499 | u8 ch_s_xxon; /* Realport XXON */ | ||
| 500 | u8 ch_s_xxoff; /* Realport XXOFF */ | ||
| 501 | |||
| 502 | wait_queue_head_t ch_flag_wait; /* Wait queue for ch_flag changes */ | ||
| 503 | wait_queue_head_t ch_sleep; /* Wait queue for my_sleep() */ | ||
| 504 | |||
| 505 | int ch_custom_speed; /* Realport custom speed */ | ||
| 506 | int ch_txcount; /* Running TX count */ | ||
| 507 | int ch_rxcount; /* Running RX count */ | ||
| 508 | }; | ||
| 509 | |||
| 510 | |||
| 511 | /************************************************************************ | ||
| 512 | * Node State definitions. | ||
| 513 | ************************************************************************/ | ||
| 514 | |||
| 515 | enum dgrp_nd_state_t { | ||
| 516 | NS_CLOSED = 0, /* Network device is closed */ | ||
| 517 | NS_IDLE = 1, /* Network connection inactive */ | ||
| 518 | NS_SEND_QUERY = 2, /* Send server query */ | ||
| 519 | NS_WAIT_QUERY = 3, /* Wait for query response */ | ||
| 520 | NS_READY = 4, /* Network ready */ | ||
| 521 | NS_SEND_ERROR = 5 /* Must send error hangup */ | ||
| 522 | }; | ||
| 523 | |||
| 524 | #define ND_STATE_STR(x) \ | ||
| 525 | ((x) == NS_CLOSED ? "CLOSED" : \ | ||
| 526 | ((x) == NS_IDLE ? "IDLE" : \ | ||
| 527 | ((x) == NS_SEND_QUERY ? "SEND_QUERY" : \ | ||
| 528 | ((x) == NS_WAIT_QUERY ? "WAIT_QUERY" : \ | ||
| 529 | ((x) == NS_READY ? "READY" : \ | ||
| 530 | ((x) == NS_SEND_ERROR ? "SEND_ERROR" : "UNKNOWN")))))) | ||
| 531 | |||
| 532 | /************************************************************************ | ||
| 533 | * Node Flag definitions. | ||
| 534 | ************************************************************************/ | ||
| 535 | |||
| 536 | #define ND_SELECT 0x0001 /* Multiple net read selects */ | ||
| 537 | #define ND_DEB_WAIT 0x0002 /* Debug Device waiting */ | ||
| 538 | |||
| 539 | |||
| 540 | /************************************************************************ | ||
| 541 | * Monitoring flag definitions. | ||
| 542 | ************************************************************************/ | ||
| 543 | |||
| 544 | #define MON_WAIT_DATA 0x0001 /* Waiting for buffer data */ | ||
| 545 | #define MON_WAIT_SPACE 0x0002 /* Waiting for buffer space */ | ||
| 546 | |||
| 547 | /************************************************************************ | ||
| 548 | * DPA flag definitions. | ||
| 549 | ************************************************************************/ | ||
| 550 | |||
| 551 | #define DPA_WAIT_DATA 0x0001 /* Waiting for buffer data */ | ||
| 552 | #define DPA_WAIT_SPACE 0x0002 /* Waiting for buffer space */ | ||
| 553 | |||
| 554 | |||
| 555 | /************************************************************************ | ||
| 556 | * Definitions taken from Realport Dump. | ||
| 557 | ************************************************************************/ | ||
| 558 | |||
| 559 | #define RPDUMP_MAGIC "Digi-RealPort-1.0" | ||
| 560 | |||
| 561 | #define RPDUMP_MESSAGE 0xE2 /* Descriptive message */ | ||
| 562 | #define RPDUMP_RESET 0xE7 /* Connection reset */ | ||
| 563 | #define RPDUMP_CLIENT 0xE8 /* Client data */ | ||
| 564 | #define RPDUMP_SERVER 0xE9 /* Server data */ | ||
| 565 | |||
| 566 | |||
| 567 | /************************************************************************ | ||
| 568 | * Node request/response definitions. | ||
| 569 | ************************************************************************/ | ||
| 570 | |||
| 571 | #define NR_ECHO 0x0001 /* Server echo packet */ | ||
| 572 | #define NR_IDENT 0x0002 /* Server Product ID */ | ||
| 573 | #define NR_CAPABILITY 0x0004 /* Server Capabilties */ | ||
| 574 | #define NR_VPD 0x0008 /* Server VPD, if any */ | ||
| 575 | #define NR_PASSWORD 0x0010 /* Server Password */ | ||
| 576 | |||
| 577 | /************************************************************************ | ||
| 578 | * Registration status of the node's Linux struct tty_driver structures. | ||
| 579 | ************************************************************************/ | ||
| 580 | #define SERIAL_TTDRV_REG 0x0001 /* nd_serial_ttdriver registered */ | ||
| 581 | #define CALLOUT_TTDRV_REG 0x0002 /* nd_callout_ttdriver registered */ | ||
| 582 | #define XPRINT_TTDRV_REG 0x0004 /* nd_xprint_ttdriver registered */ | ||
| 583 | |||
| 584 | |||
| 585 | /************************************************************************ | ||
| 586 | * Node structure. There exists one of these for each associated | ||
| 587 | * realport server. | ||
| 588 | ************************************************************************/ | ||
| 589 | |||
| 590 | struct nd_struct { | ||
| 591 | struct list_head list; | ||
| 592 | long nd_major; /* Node's major number */ | ||
| 593 | long nd_ID; /* Node's ID code */ | ||
| 594 | |||
| 595 | char nd_serial_name[50]; /* "tty_dgrp_<id>_" + null */ | ||
| 596 | char nd_callout_name[50]; /* "cu_dgrp_<id>_" + null */ | ||
| 597 | char nd_xprint_name[50]; /* "pr_dgrp_<id>_" + null */ | ||
| 598 | |||
| 599 | char password[16]; /* Password for server, if needed */ | ||
| 600 | int nd_tty_ref_cnt; /* Linux tty reference count */ | ||
| 601 | |||
| 602 | struct proc_dir_entry *nd_net_de; /* Dir entry for /proc/dgrp/net */ | ||
| 603 | struct proc_dir_entry *nd_mon_de; /* Dir entry for /proc/dgrp/mon */ | ||
| 604 | struct proc_dir_entry *nd_ports_de; /* Dir entry for /proc/dgrp/ports*/ | ||
| 605 | struct proc_dir_entry *nd_dpa_de; /* Dir entry for /proc/dgrp/dpa */ | ||
| 606 | |||
| 607 | spinlock_t nd_lock; /* General node lock */ | ||
| 608 | |||
| 609 | struct semaphore nd_net_semaphore; /* Net read/write lock */ | ||
| 610 | struct semaphore nd_mon_semaphore; /* Monitor buffer lock */ | ||
| 611 | spinlock_t nd_dpa_lock; /* DPA buffer lock */ | ||
| 612 | |||
| 613 | enum dgrp_nd_state_t nd_state; /* NS_* network state */ | ||
| 614 | int nd_chan_count; /* # active channels */ | ||
| 615 | int nd_flag; /* Node flags */ | ||
| 616 | int nd_send; /* Responses to send */ | ||
| 617 | int nd_expect; /* Responses we expect */ | ||
| 618 | |||
| 619 | u8 *nd_iobuf; /* Network R/W Buffer */ | ||
| 620 | wait_queue_head_t nd_tx_waitq; /* Network select wait queue */ | ||
| 621 | |||
| 622 | u8 *nd_inputbuf; /* Input Buffer */ | ||
| 623 | u8 *nd_inputflagbuf; /* Input Flags Buffer */ | ||
| 624 | |||
| 625 | int nd_tx_deposit; /* Accumulated transmit deposits */ | ||
| 626 | int nd_tx_charge; /* Accumulated transmit charges */ | ||
| 627 | int nd_tx_credit; /* Current TX credit */ | ||
| 628 | int nd_tx_ready; /* Ready to transmit */ | ||
| 629 | int nd_tx_work; /* TX work waiting */ | ||
| 630 | ulong nd_tx_time; /* Last transmit time */ | ||
| 631 | ulong nd_poll_time; /* Next scheduled poll time */ | ||
| 632 | |||
| 633 | int nd_delay; /* Current TX delay */ | ||
| 634 | int nd_rate; /* Current TX rate */ | ||
| 635 | struct link_struct nd_link; /* Link speed params. */ | ||
| 636 | |||
| 637 | int nd_seq_in; /* TX seq in ptr */ | ||
| 638 | int nd_seq_out; /* TX seq out ptr */ | ||
| 639 | int nd_unack; /* Unacknowledged byte count */ | ||
| 640 | int nd_remain; /* Remaining receive bytes */ | ||
| 641 | int nd_tx_module; /* Current TX module # */ | ||
| 642 | int nd_rx_module; /* Current RX module # */ | ||
| 643 | char *nd_error; /* Protocol error message */ | ||
| 644 | |||
| 645 | int nd_write_count; /* drp_write() call count */ | ||
| 646 | int nd_read_count; /* drp_read() count */ | ||
| 647 | int nd_send_count; /* TCP message sent */ | ||
| 648 | int nd_tx_byte; /* Transmit byte count */ | ||
| 649 | int nd_rx_byte; /* Receive byte count */ | ||
| 650 | |||
| 651 | ulong nd_mon_lbolt; /* Monitor start time */ | ||
| 652 | int nd_mon_flag; /* Monitor flags */ | ||
| 653 | int nd_mon_in; /* Monitor in pointer */ | ||
| 654 | int nd_mon_out; /* Monitor out pointer */ | ||
| 655 | wait_queue_head_t nd_mon_wqueue; /* Monitor wait queue (on flags) */ | ||
| 656 | u8 *nd_mon_buf; /* Monitor buffer */ | ||
| 657 | |||
| 658 | ulong nd_dpa_lbolt; /* DPA start time */ | ||
| 659 | int nd_dpa_flag; /* DPA flags */ | ||
| 660 | int nd_dpa_in; /* DPA in pointer */ | ||
| 661 | int nd_dpa_out; /* DPA out pointer */ | ||
| 662 | wait_queue_head_t nd_dpa_wqueue; /* DPA wait queue (on flags) */ | ||
| 663 | u8 *nd_dpa_buf; /* DPA buffer */ | ||
| 664 | |||
| 665 | uint nd_dpa_debug; | ||
| 666 | uint nd_dpa_port; | ||
| 667 | |||
| 668 | wait_queue_head_t nd_seq_wque[SEQ_MAX]; /* TX thread wait queues */ | ||
| 669 | u8 nd_seq_wait[SEQ_MAX]; /* Transmit thread wait count */ | ||
| 670 | |||
| 671 | ushort nd_seq_size[SEQ_MAX]; /* Transmit seq packet size */ | ||
| 672 | ulong nd_seq_time[SEQ_MAX]; /* Transmit seq packet time */ | ||
| 673 | |||
| 674 | ushort nd_hw_ver; /* HW version returned from PS */ | ||
| 675 | ushort nd_sw_ver; /* SW version returned from PS */ | ||
| 676 | uint nd_hw_id; /* HW ID returned from PS */ | ||
| 677 | u8 nd_ps_desc[MAX_DESC_LEN+1]; /* Description from PS */ | ||
| 678 | uint nd_vpd_len; /* VPD len, if any */ | ||
| 679 | u8 nd_vpd[VPDSIZE]; /* VPD, if any */ | ||
| 680 | |||
| 681 | ulong nd_ttdriver_flags; /* Registration status */ | ||
| 682 | struct tty_driver *nd_serial_ttdriver; /* Linux TTYDRIVER structure */ | ||
| 683 | struct tty_driver *nd_callout_ttdriver; /* Linux TTYDRIVER structure */ | ||
| 684 | struct tty_driver *nd_xprint_ttdriver; /* Linux TTYDRIVER structure */ | ||
| 685 | |||
| 686 | u8 *nd_writebuf; /* Used to cache data read | ||
| 687 | * from user | ||
| 688 | */ | ||
| 689 | struct ch_struct nd_chan[CHAN_MAX]; /* Channel array */ | ||
| 690 | struct device *nd_class_dev; /* Hang our sysfs stuff off of here */ | ||
| 691 | }; | ||
| 692 | |||
| 693 | #endif /* __DRP_H */ | ||
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 2cdbf280cdab..d751edfda839 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c | |||
| @@ -443,7 +443,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, | |||
| 443 | spin_lock_init(&channel->lock); | 443 | spin_lock_init(&channel->lock); |
| 444 | channel->pointer_read = 0; | 444 | channel->pointer_read = 0; |
| 445 | channel->pointer_write = 0; | 445 | channel->pointer_write = 0; |
| 446 | tty_dev = tty_register_device(tty, i, NULL); | 446 | tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL); |
| 447 | if (IS_ERR(tty_dev)) { | 447 | if (IS_ERR(tty_dev)) { |
| 448 | dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); | 448 | dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); |
| 449 | continue; | 449 | continue; |
| @@ -543,7 +543,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, | |||
| 543 | struct ipoctal_channel *channel = tty->driver_data; | 543 | struct ipoctal_channel *channel = tty->driver_data; |
| 544 | speed_t baud; | 544 | speed_t baud; |
| 545 | 545 | ||
| 546 | cflag = tty->termios->c_cflag; | 546 | cflag = tty->termios.c_cflag; |
| 547 | 547 | ||
| 548 | /* Disable and reset everything before change the setup */ | 548 | /* Disable and reset everything before change the setup */ |
| 549 | iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); | 549 | iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); |
| @@ -564,7 +564,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, | |||
| 564 | default: | 564 | default: |
| 565 | mr1 |= MR1_CHRL_8_BITS; | 565 | mr1 |= MR1_CHRL_8_BITS; |
| 566 | /* By default, select CS8 */ | 566 | /* By default, select CS8 */ |
| 567 | tty->termios->c_cflag = (cflag & ~CSIZE) | CS8; | 567 | tty->termios.c_cflag = (cflag & ~CSIZE) | CS8; |
| 568 | break; | 568 | break; |
| 569 | } | 569 | } |
| 570 | 570 | ||
| @@ -578,7 +578,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, | |||
| 578 | mr1 |= MR1_PARITY_OFF; | 578 | mr1 |= MR1_PARITY_OFF; |
| 579 | 579 | ||
| 580 | /* Mark or space parity is not supported */ | 580 | /* Mark or space parity is not supported */ |
| 581 | tty->termios->c_cflag &= ~CMSPAR; | 581 | tty->termios.c_cflag &= ~CMSPAR; |
| 582 | 582 | ||
| 583 | /* Set stop bits */ | 583 | /* Set stop bits */ |
| 584 | if (cflag & CSTOPB) | 584 | if (cflag & CSTOPB) |
| @@ -611,10 +611,10 @@ static void ipoctal_set_termios(struct tty_struct *tty, | |||
| 611 | } | 611 | } |
| 612 | 612 | ||
| 613 | baud = tty_get_baud_rate(tty); | 613 | baud = tty_get_baud_rate(tty); |
| 614 | tty_termios_encode_baud_rate(tty->termios, baud, baud); | 614 | tty_termios_encode_baud_rate(&tty->termios, baud, baud); |
| 615 | 615 | ||
| 616 | /* Set baud rate */ | 616 | /* Set baud rate */ |
| 617 | switch (tty->termios->c_ospeed) { | 617 | switch (baud) { |
| 618 | case 75: | 618 | case 75: |
| 619 | csr |= TX_CLK_75 | RX_CLK_75; | 619 | csr |= TX_CLK_75 | RX_CLK_75; |
| 620 | break; | 620 | break; |
| @@ -655,7 +655,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, | |||
| 655 | default: | 655 | default: |
| 656 | csr |= TX_CLK_38400 | RX_CLK_38400; | 656 | csr |= TX_CLK_38400 | RX_CLK_38400; |
| 657 | /* In case of default, we establish 38400 bps */ | 657 | /* In case of default, we establish 38400 bps */ |
| 658 | tty_termios_encode_baud_rate(tty->termios, 38400, 38400); | 658 | tty_termios_encode_baud_rate(&tty->termios, 38400, 38400); |
| 659 | break; | 659 | break; |
| 660 | } | 660 | } |
| 661 | 661 | ||
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index c56609c6094b..5c969ade2eb7 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c | |||
| @@ -313,10 +313,8 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | tty = tty_port_tty_get(&port->port); | 315 | tty = tty_port_tty_get(&port->port); |
| 316 | if (!tty) { | 316 | if (!tty) |
| 317 | dbg("%s - bad tty pointer - exiting", __func__); | ||
| 318 | return; | 317 | return; |
| 319 | } | ||
| 320 | 318 | ||
| 321 | data = urb->transfer_buffer; | 319 | data = urb->transfer_buffer; |
| 322 | 320 | ||
| @@ -362,7 +360,7 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
| 362 | goto exit; | 360 | goto exit; |
| 363 | } | 361 | } |
| 364 | 362 | ||
| 365 | if (tty && RxCount) { | 363 | if (RxCount) { |
| 366 | flag_data = 0; | 364 | flag_data = 0; |
| 367 | for (i = 0; i < RxCount; ++i) { | 365 | for (i = 0; i < RxCount; ++i) { |
| 368 | /* Look ahead code here */ | 366 | /* Look ahead code here */ |
| @@ -426,7 +424,7 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
| 426 | dbg("%s - failed resubmitting read urb, error %d", | 424 | dbg("%s - failed resubmitting read urb, error %d", |
| 427 | __func__, result); | 425 | __func__, result); |
| 428 | else { | 426 | else { |
| 429 | if (tty && RxCount) { | 427 | if (RxCount) { |
| 430 | tty_flip_buffer_push(tty); | 428 | tty_flip_buffer_push(tty); |
| 431 | tty_schedule_flip(tty); | 429 | tty_schedule_flip(tty); |
| 432 | } | 430 | } |
| @@ -895,8 +893,6 @@ static int qt_open(struct tty_struct *tty, | |||
| 895 | * Put this here to make it responsive to stty and defaults set by | 893 | * Put this here to make it responsive to stty and defaults set by |
| 896 | * the tty layer | 894 | * the tty layer |
| 897 | */ | 895 | */ |
| 898 | /* FIXME: is this needed? */ | ||
| 899 | /* qt_set_termios(tty, port, NULL); */ | ||
| 900 | 896 | ||
| 901 | /* Check to see if we've set up our endpoint info yet */ | 897 | /* Check to see if we've set up our endpoint info yet */ |
| 902 | if (port0->open_ports == 1) { | 898 | if (port0->open_ports == 1) { |
| @@ -1193,7 +1189,7 @@ static void qt_set_termios(struct tty_struct *tty, | |||
| 1193 | struct usb_serial_port *port, | 1189 | struct usb_serial_port *port, |
| 1194 | struct ktermios *old_termios) | 1190 | struct ktermios *old_termios) |
| 1195 | { | 1191 | { |
| 1196 | struct ktermios *termios = tty->termios; | 1192 | struct ktermios *termios = &tty->termios; |
| 1197 | unsigned char new_LCR = 0; | 1193 | unsigned char new_LCR = 0; |
| 1198 | unsigned int cflag = termios->c_cflag; | 1194 | unsigned int cflag = termios->c_cflag; |
| 1199 | unsigned int index; | 1195 | unsigned int index; |
| @@ -1202,7 +1198,7 @@ static void qt_set_termios(struct tty_struct *tty, | |||
| 1202 | 1198 | ||
| 1203 | index = tty->index - port->serial->minor; | 1199 | index = tty->index - port->serial->minor; |
| 1204 | 1200 | ||
| 1205 | switch (cflag) { | 1201 | switch (cflag & CSIZE) { |
| 1206 | case CS5: | 1202 | case CS5: |
| 1207 | new_LCR |= SERIAL_5_DATA; | 1203 | new_LCR |= SERIAL_5_DATA; |
| 1208 | break; | 1204 | break; |
| @@ -1213,6 +1209,8 @@ static void qt_set_termios(struct tty_struct *tty, | |||
| 1213 | new_LCR |= SERIAL_7_DATA; | 1209 | new_LCR |= SERIAL_7_DATA; |
| 1214 | break; | 1210 | break; |
| 1215 | default: | 1211 | default: |
| 1212 | termios->c_cflag &= ~CSIZE; | ||
| 1213 | termios->c_cflag |= CS8; | ||
| 1216 | case CS8: | 1214 | case CS8: |
| 1217 | new_LCR |= SERIAL_8_DATA; | 1215 | new_LCR |= SERIAL_8_DATA; |
| 1218 | break; | 1216 | break; |
| @@ -1299,7 +1297,7 @@ static void qt_set_termios(struct tty_struct *tty, | |||
| 1299 | dbg(__FILE__ "BoxSetSW_FlowCtrl (diabling) failed\n"); | 1297 | dbg(__FILE__ "BoxSetSW_FlowCtrl (diabling) failed\n"); |
| 1300 | 1298 | ||
| 1301 | } | 1299 | } |
| 1302 | tty->termios->c_cflag &= ~CMSPAR; | 1300 | termios->c_cflag &= ~CMSPAR; |
| 1303 | /* FIXME: Error cases should be returning the actual bits changed only */ | 1301 | /* FIXME: Error cases should be returning the actual bits changed only */ |
| 1304 | } | 1302 | } |
| 1305 | 1303 | ||
diff --git a/drivers/staging/speakup/serialio.h b/drivers/staging/speakup/serialio.h index 614271f9b99f..55d68b5ad165 100644 --- a/drivers/staging/speakup/serialio.h +++ b/drivers/staging/speakup/serialio.h | |||
| @@ -1,8 +1,7 @@ | |||
| 1 | #ifndef _SPEAKUP_SERIAL_H | 1 | #ifndef _SPEAKUP_SERIAL_H |
| 2 | #define _SPEAKUP_SERIAL_H | 2 | #define _SPEAKUP_SERIAL_H |
| 3 | 3 | ||
| 4 | #include <linux/serial.h> /* for rs_table, serial constants & | 4 | #include <linux/serial.h> /* for rs_table, serial constants */ |
| 5 | serial_uart_config */ | ||
| 6 | #include <linux/serial_reg.h> /* for more serial constants */ | 5 | #include <linux/serial_reg.h> /* for more serial constants */ |
| 7 | #ifndef __sparc__ | 6 | #ifndef __sparc__ |
| 8 | #include <asm/serial.h> | 7 | #include <asm/serial.h> |
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index 830cd62d8492..d8e05eeab232 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig | |||
| @@ -214,8 +214,8 @@ config CYCLADES | |||
| 214 | If you haven't heard about it, it's safe to say N. | 214 | If you haven't heard about it, it's safe to say N. |
| 215 | 215 | ||
| 216 | config CYZ_INTR | 216 | config CYZ_INTR |
| 217 | bool "Cyclades-Z interrupt mode operation (EXPERIMENTAL)" | 217 | bool "Cyclades-Z interrupt mode operation" |
| 218 | depends on EXPERIMENTAL && CYCLADES | 218 | depends on CYCLADES |
| 219 | help | 219 | help |
| 220 | The Cyclades-Z family of multiport cards allows 2 (two) driver op | 220 | The Cyclades-Z family of multiport cards allows 2 (two) driver op |
| 221 | modes: polling and interrupt. In polling mode, the driver will check | 221 | modes: polling and interrupt. In polling mode, the driver will check |
| @@ -285,7 +285,7 @@ config SYNCLINK_GT | |||
| 285 | 285 | ||
| 286 | config NOZOMI | 286 | config NOZOMI |
| 287 | tristate "HSDPA Broadband Wireless Data Card - Globe Trotter" | 287 | tristate "HSDPA Broadband Wireless Data Card - Globe Trotter" |
| 288 | depends on PCI && EXPERIMENTAL | 288 | depends on PCI |
| 289 | help | 289 | help |
| 290 | If you have a HSDPA driver Broadband Wireless Data Card - | 290 | If you have a HSDPA driver Broadband Wireless Data Card - |
| 291 | Globe Trotter PCMCIA card, say Y here. | 291 | Globe Trotter PCMCIA card, say Y here. |
| @@ -294,7 +294,7 @@ config NOZOMI | |||
| 294 | will be called nozomi. | 294 | will be called nozomi. |
| 295 | 295 | ||
| 296 | config ISI | 296 | config ISI |
| 297 | tristate "Multi-Tech multiport card support (EXPERIMENTAL)" | 297 | tristate "Multi-Tech multiport card support" |
| 298 | depends on SERIAL_NONSTANDARD && PCI | 298 | depends on SERIAL_NONSTANDARD && PCI |
| 299 | select FW_LOADER | 299 | select FW_LOADER |
| 300 | help | 300 | help |
| @@ -317,7 +317,6 @@ config N_HDLC | |||
| 317 | 317 | ||
| 318 | config N_GSM | 318 | config N_GSM |
| 319 | tristate "GSM MUX line discipline support (EXPERIMENTAL)" | 319 | tristate "GSM MUX line discipline support (EXPERIMENTAL)" |
| 320 | depends on EXPERIMENTAL | ||
| 321 | depends on NET | 320 | depends on NET |
| 322 | help | 321 | help |
| 323 | This line discipline provides support for the GSM MUX protocol and | 322 | This line discipline provides support for the GSM MUX protocol and |
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 6cc4358f68c1..42d0a2581a87 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c | |||
| @@ -420,7 +420,7 @@ static void check_modem_status(struct serial_state *info) | |||
| 420 | tty_hangup(port->tty); | 420 | tty_hangup(port->tty); |
| 421 | } | 421 | } |
| 422 | } | 422 | } |
| 423 | if (port->flags & ASYNC_CTS_FLOW) { | 423 | if (tty_port_cts_enabled(port)) { |
| 424 | if (port->tty->hw_stopped) { | 424 | if (port->tty->hw_stopped) { |
| 425 | if (!(status & SER_CTS)) { | 425 | if (!(status & SER_CTS)) { |
| 426 | #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) | 426 | #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) |
| @@ -646,7 +646,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info) | |||
| 646 | custom.adkcon = AC_UARTBRK; | 646 | custom.adkcon = AC_UARTBRK; |
| 647 | mb(); | 647 | mb(); |
| 648 | 648 | ||
| 649 | if (tty->termios->c_cflag & HUPCL) | 649 | if (tty->termios.c_cflag & HUPCL) |
| 650 | info->MCR &= ~(SER_DTR|SER_RTS); | 650 | info->MCR &= ~(SER_DTR|SER_RTS); |
| 651 | rtsdtr_ctrl(info->MCR); | 651 | rtsdtr_ctrl(info->MCR); |
| 652 | 652 | ||
| @@ -670,7 +670,7 @@ static void change_speed(struct tty_struct *tty, struct serial_state *info, | |||
| 670 | int bits; | 670 | int bits; |
| 671 | unsigned long flags; | 671 | unsigned long flags; |
| 672 | 672 | ||
| 673 | cflag = tty->termios->c_cflag; | 673 | cflag = tty->termios.c_cflag; |
| 674 | 674 | ||
| 675 | /* Byte size is always 8 bits plus parity bit if requested */ | 675 | /* Byte size is always 8 bits plus parity bit if requested */ |
| 676 | 676 | ||
| @@ -707,8 +707,8 @@ static void change_speed(struct tty_struct *tty, struct serial_state *info, | |||
| 707 | /* If the quotient is zero refuse the change */ | 707 | /* If the quotient is zero refuse the change */ |
| 708 | if (!quot && old_termios) { | 708 | if (!quot && old_termios) { |
| 709 | /* FIXME: Will need updating for new tty in the end */ | 709 | /* FIXME: Will need updating for new tty in the end */ |
| 710 | tty->termios->c_cflag &= ~CBAUD; | 710 | tty->termios.c_cflag &= ~CBAUD; |
| 711 | tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); | 711 | tty->termios.c_cflag |= (old_termios->c_cflag & CBAUD); |
| 712 | baud = tty_get_baud_rate(tty); | 712 | baud = tty_get_baud_rate(tty); |
| 713 | if (!baud) | 713 | if (!baud) |
| 714 | baud = 9600; | 714 | baud = 9600; |
| @@ -984,7 +984,7 @@ static void rs_throttle(struct tty_struct * tty) | |||
| 984 | if (I_IXOFF(tty)) | 984 | if (I_IXOFF(tty)) |
| 985 | rs_send_xchar(tty, STOP_CHAR(tty)); | 985 | rs_send_xchar(tty, STOP_CHAR(tty)); |
| 986 | 986 | ||
| 987 | if (tty->termios->c_cflag & CRTSCTS) | 987 | if (tty->termios.c_cflag & CRTSCTS) |
| 988 | info->MCR &= ~SER_RTS; | 988 | info->MCR &= ~SER_RTS; |
| 989 | 989 | ||
| 990 | local_irq_save(flags); | 990 | local_irq_save(flags); |
| @@ -1012,7 +1012,7 @@ static void rs_unthrottle(struct tty_struct * tty) | |||
| 1012 | else | 1012 | else |
| 1013 | rs_send_xchar(tty, START_CHAR(tty)); | 1013 | rs_send_xchar(tty, START_CHAR(tty)); |
| 1014 | } | 1014 | } |
| 1015 | if (tty->termios->c_cflag & CRTSCTS) | 1015 | if (tty->termios.c_cflag & CRTSCTS) |
| 1016 | info->MCR |= SER_RTS; | 1016 | info->MCR |= SER_RTS; |
| 1017 | local_irq_save(flags); | 1017 | local_irq_save(flags); |
| 1018 | rtsdtr_ctrl(info->MCR); | 1018 | rtsdtr_ctrl(info->MCR); |
| @@ -1033,7 +1033,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state, | |||
| 1033 | if (!retinfo) | 1033 | if (!retinfo) |
| 1034 | return -EFAULT; | 1034 | return -EFAULT; |
| 1035 | memset(&tmp, 0, sizeof(tmp)); | 1035 | memset(&tmp, 0, sizeof(tmp)); |
| 1036 | tty_lock(); | 1036 | tty_lock(tty); |
| 1037 | tmp.line = tty->index; | 1037 | tmp.line = tty->index; |
| 1038 | tmp.port = state->port; | 1038 | tmp.port = state->port; |
| 1039 | tmp.flags = state->tport.flags; | 1039 | tmp.flags = state->tport.flags; |
| @@ -1042,7 +1042,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state, | |||
| 1042 | tmp.close_delay = state->tport.close_delay; | 1042 | tmp.close_delay = state->tport.close_delay; |
| 1043 | tmp.closing_wait = state->tport.closing_wait; | 1043 | tmp.closing_wait = state->tport.closing_wait; |
| 1044 | tmp.custom_divisor = state->custom_divisor; | 1044 | tmp.custom_divisor = state->custom_divisor; |
| 1045 | tty_unlock(); | 1045 | tty_unlock(tty); |
| 1046 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) | 1046 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) |
| 1047 | return -EFAULT; | 1047 | return -EFAULT; |
| 1048 | return 0; | 1048 | return 0; |
| @@ -1059,12 +1059,12 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, | |||
| 1059 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) | 1059 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) |
| 1060 | return -EFAULT; | 1060 | return -EFAULT; |
| 1061 | 1061 | ||
| 1062 | tty_lock(); | 1062 | tty_lock(tty); |
| 1063 | change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) || | 1063 | change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) || |
| 1064 | new_serial.custom_divisor != state->custom_divisor; | 1064 | new_serial.custom_divisor != state->custom_divisor; |
| 1065 | if (new_serial.irq || new_serial.port != state->port || | 1065 | if (new_serial.irq || new_serial.port != state->port || |
| 1066 | new_serial.xmit_fifo_size != state->xmit_fifo_size) { | 1066 | new_serial.xmit_fifo_size != state->xmit_fifo_size) { |
| 1067 | tty_unlock(); | 1067 | tty_unlock(tty); |
| 1068 | return -EINVAL; | 1068 | return -EINVAL; |
| 1069 | } | 1069 | } |
| 1070 | 1070 | ||
| @@ -1074,7 +1074,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, | |||
| 1074 | (new_serial.xmit_fifo_size != state->xmit_fifo_size) || | 1074 | (new_serial.xmit_fifo_size != state->xmit_fifo_size) || |
| 1075 | ((new_serial.flags & ~ASYNC_USR_MASK) != | 1075 | ((new_serial.flags & ~ASYNC_USR_MASK) != |
| 1076 | (port->flags & ~ASYNC_USR_MASK))) { | 1076 | (port->flags & ~ASYNC_USR_MASK))) { |
| 1077 | tty_unlock(); | 1077 | tty_unlock(tty); |
| 1078 | return -EPERM; | 1078 | return -EPERM; |
| 1079 | } | 1079 | } |
| 1080 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | | 1080 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | |
| @@ -1084,7 +1084,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, | |||
| 1084 | } | 1084 | } |
| 1085 | 1085 | ||
| 1086 | if (new_serial.baud_base < 9600) { | 1086 | if (new_serial.baud_base < 9600) { |
| 1087 | tty_unlock(); | 1087 | tty_unlock(tty); |
| 1088 | return -EINVAL; | 1088 | return -EINVAL; |
| 1089 | } | 1089 | } |
| 1090 | 1090 | ||
| @@ -1116,7 +1116,7 @@ check_and_exit: | |||
| 1116 | } | 1116 | } |
| 1117 | } else | 1117 | } else |
| 1118 | retval = startup(tty, state); | 1118 | retval = startup(tty, state); |
| 1119 | tty_unlock(); | 1119 | tty_unlock(tty); |
| 1120 | return retval; | 1120 | return retval; |
| 1121 | } | 1121 | } |
| 1122 | 1122 | ||
| @@ -1330,7 +1330,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 1330 | { | 1330 | { |
| 1331 | struct serial_state *info = tty->driver_data; | 1331 | struct serial_state *info = tty->driver_data; |
| 1332 | unsigned long flags; | 1332 | unsigned long flags; |
| 1333 | unsigned int cflag = tty->termios->c_cflag; | 1333 | unsigned int cflag = tty->termios.c_cflag; |
| 1334 | 1334 | ||
| 1335 | change_speed(tty, info, old_termios); | 1335 | change_speed(tty, info, old_termios); |
| 1336 | 1336 | ||
| @@ -1347,7 +1347,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 1347 | if (!(old_termios->c_cflag & CBAUD) && | 1347 | if (!(old_termios->c_cflag & CBAUD) && |
| 1348 | (cflag & CBAUD)) { | 1348 | (cflag & CBAUD)) { |
| 1349 | info->MCR |= SER_DTR; | 1349 | info->MCR |= SER_DTR; |
| 1350 | if (!(tty->termios->c_cflag & CRTSCTS) || | 1350 | if (!(tty->termios.c_cflag & CRTSCTS) || |
| 1351 | !test_bit(TTY_THROTTLED, &tty->flags)) { | 1351 | !test_bit(TTY_THROTTLED, &tty->flags)) { |
| 1352 | info->MCR |= SER_RTS; | 1352 | info->MCR |= SER_RTS; |
| 1353 | } | 1353 | } |
| @@ -1358,7 +1358,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 1358 | 1358 | ||
| 1359 | /* Handle turning off CRTSCTS */ | 1359 | /* Handle turning off CRTSCTS */ |
| 1360 | if ((old_termios->c_cflag & CRTSCTS) && | 1360 | if ((old_termios->c_cflag & CRTSCTS) && |
| 1361 | !(tty->termios->c_cflag & CRTSCTS)) { | 1361 | !(tty->termios.c_cflag & CRTSCTS)) { |
| 1362 | tty->hw_stopped = 0; | 1362 | tty->hw_stopped = 0; |
| 1363 | rs_start(tty); | 1363 | rs_start(tty); |
| 1364 | } | 1364 | } |
| @@ -1371,7 +1371,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 1371 | * or not. Hence, this may change..... | 1371 | * or not. Hence, this may change..... |
| 1372 | */ | 1372 | */ |
| 1373 | if (!(old_termios->c_cflag & CLOCAL) && | 1373 | if (!(old_termios->c_cflag & CLOCAL) && |
| 1374 | (tty->termios->c_cflag & CLOCAL)) | 1374 | (tty->termios.c_cflag & CLOCAL)) |
| 1375 | wake_up_interruptible(&info->open_wait); | 1375 | wake_up_interruptible(&info->open_wait); |
| 1376 | #endif | 1376 | #endif |
| 1377 | } | 1377 | } |
| @@ -1710,10 +1710,6 @@ static int __init amiga_serial_probe(struct platform_device *pdev) | |||
| 1710 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | 1710 | serial_driver->flags = TTY_DRIVER_REAL_RAW; |
| 1711 | tty_set_operations(serial_driver, &serial_ops); | 1711 | tty_set_operations(serial_driver, &serial_ops); |
| 1712 | 1712 | ||
| 1713 | error = tty_register_driver(serial_driver); | ||
| 1714 | if (error) | ||
| 1715 | goto fail_put_tty_driver; | ||
| 1716 | |||
| 1717 | state = rs_table; | 1713 | state = rs_table; |
| 1718 | state->port = (int)&custom.serdatr; /* Just to give it a value */ | 1714 | state->port = (int)&custom.serdatr; /* Just to give it a value */ |
| 1719 | state->custom_divisor = 0; | 1715 | state->custom_divisor = 0; |
| @@ -1724,6 +1720,11 @@ static int __init amiga_serial_probe(struct platform_device *pdev) | |||
| 1724 | state->icount.overrun = state->icount.brk = 0; | 1720 | state->icount.overrun = state->icount.brk = 0; |
| 1725 | tty_port_init(&state->tport); | 1721 | tty_port_init(&state->tport); |
| 1726 | state->tport.ops = &amiga_port_ops; | 1722 | state->tport.ops = &amiga_port_ops; |
| 1723 | tty_port_link_device(&state->tport, serial_driver, 0); | ||
| 1724 | |||
| 1725 | error = tty_register_driver(serial_driver); | ||
| 1726 | if (error) | ||
| 1727 | goto fail_put_tty_driver; | ||
| 1727 | 1728 | ||
| 1728 | printk(KERN_INFO "ttyS0 is the amiga builtin serial port\n"); | 1729 | printk(KERN_INFO "ttyS0 is the amiga builtin serial port\n"); |
| 1729 | 1730 | ||
diff --git a/drivers/tty/bfin_jtag_comm.c b/drivers/tty/bfin_jtag_comm.c index 61fc74fe1747..02b7d3a09696 100644 --- a/drivers/tty/bfin_jtag_comm.c +++ b/drivers/tty/bfin_jtag_comm.c | |||
| @@ -263,6 +263,7 @@ static int __init bfin_jc_init(void) | |||
| 263 | bfin_jc_driver->subtype = SERIAL_TYPE_NORMAL; | 263 | bfin_jc_driver->subtype = SERIAL_TYPE_NORMAL; |
| 264 | bfin_jc_driver->init_termios = tty_std_termios; | 264 | bfin_jc_driver->init_termios = tty_std_termios; |
| 265 | tty_set_operations(bfin_jc_driver, &bfin_jc_ops); | 265 | tty_set_operations(bfin_jc_driver, &bfin_jc_ops); |
| 266 | tty_port_link_device(&port, bfin_jc_driver, 0); | ||
| 266 | 267 | ||
| 267 | ret = tty_register_driver(bfin_jc_driver); | 268 | ret = tty_register_driver(bfin_jc_driver); |
| 268 | if (ret) | 269 | if (ret) |
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index e61cabdd69df..0a6a0bc1b598 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c | |||
| @@ -727,7 +727,7 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, | |||
| 727 | else | 727 | else |
| 728 | tty_hangup(tty); | 728 | tty_hangup(tty); |
| 729 | } | 729 | } |
| 730 | if ((mdm_change & CyCTS) && (info->port.flags & ASYNC_CTS_FLOW)) { | 730 | if ((mdm_change & CyCTS) && tty_port_cts_enabled(&info->port)) { |
| 731 | if (tty->hw_stopped) { | 731 | if (tty->hw_stopped) { |
| 732 | if (mdm_status & CyCTS) { | 732 | if (mdm_status & CyCTS) { |
| 733 | /* cy_start isn't used | 733 | /* cy_start isn't used |
| @@ -1459,7 +1459,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
| 1459 | info->port.xmit_buf = NULL; | 1459 | info->port.xmit_buf = NULL; |
| 1460 | free_page((unsigned long)temp); | 1460 | free_page((unsigned long)temp); |
| 1461 | } | 1461 | } |
| 1462 | if (tty->termios->c_cflag & HUPCL) | 1462 | if (tty->termios.c_cflag & HUPCL) |
| 1463 | cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR); | 1463 | cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR); |
| 1464 | 1464 | ||
| 1465 | cyy_issue_cmd(info, CyCHAN_CTL | CyDIS_RCVR); | 1465 | cyy_issue_cmd(info, CyCHAN_CTL | CyDIS_RCVR); |
| @@ -1488,7 +1488,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
| 1488 | free_page((unsigned long)temp); | 1488 | free_page((unsigned long)temp); |
| 1489 | } | 1489 | } |
| 1490 | 1490 | ||
| 1491 | if (tty->termios->c_cflag & HUPCL) | 1491 | if (tty->termios.c_cflag & HUPCL) |
| 1492 | tty_port_lower_dtr_rts(&info->port); | 1492 | tty_port_lower_dtr_rts(&info->port); |
| 1493 | 1493 | ||
| 1494 | set_bit(TTY_IO_ERROR, &tty->flags); | 1494 | set_bit(TTY_IO_ERROR, &tty->flags); |
| @@ -1599,7 +1599,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
| 1599 | * If the port is the middle of closing, bail out now | 1599 | * If the port is the middle of closing, bail out now |
| 1600 | */ | 1600 | */ |
| 1601 | if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) { | 1601 | if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) { |
| 1602 | wait_event_interruptible_tty(info->port.close_wait, | 1602 | wait_event_interruptible_tty(tty, info->port.close_wait, |
| 1603 | !(info->port.flags & ASYNC_CLOSING)); | 1603 | !(info->port.flags & ASYNC_CLOSING)); |
| 1604 | return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; | 1604 | return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; |
| 1605 | } | 1605 | } |
| @@ -1999,14 +1999,11 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty) | |||
| 1999 | int baud, baud_rate = 0; | 1999 | int baud, baud_rate = 0; |
| 2000 | int i; | 2000 | int i; |
| 2001 | 2001 | ||
| 2002 | if (!tty->termios) /* XXX can this happen at all? */ | ||
| 2003 | return; | ||
| 2004 | |||
| 2005 | if (info->line == -1) | 2002 | if (info->line == -1) |
| 2006 | return; | 2003 | return; |
| 2007 | 2004 | ||
| 2008 | cflag = tty->termios->c_cflag; | 2005 | cflag = tty->termios.c_cflag; |
| 2009 | iflag = tty->termios->c_iflag; | 2006 | iflag = tty->termios.c_iflag; |
| 2010 | 2007 | ||
| 2011 | /* | 2008 | /* |
| 2012 | * Set up the tty->alt_speed kludge | 2009 | * Set up the tty->alt_speed kludge |
| @@ -2825,7 +2822,7 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 2825 | cy_set_line_char(info, tty); | 2822 | cy_set_line_char(info, tty); |
| 2826 | 2823 | ||
| 2827 | if ((old_termios->c_cflag & CRTSCTS) && | 2824 | if ((old_termios->c_cflag & CRTSCTS) && |
| 2828 | !(tty->termios->c_cflag & CRTSCTS)) { | 2825 | !(tty->termios.c_cflag & CRTSCTS)) { |
| 2829 | tty->hw_stopped = 0; | 2826 | tty->hw_stopped = 0; |
| 2830 | cy_start(tty); | 2827 | cy_start(tty); |
| 2831 | } | 2828 | } |
| @@ -2837,7 +2834,7 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 2837 | * or not. Hence, this may change..... | 2834 | * or not. Hence, this may change..... |
| 2838 | */ | 2835 | */ |
| 2839 | if (!(old_termios->c_cflag & CLOCAL) && | 2836 | if (!(old_termios->c_cflag & CLOCAL) && |
| 2840 | (tty->termios->c_cflag & CLOCAL)) | 2837 | (tty->termios.c_cflag & CLOCAL)) |
| 2841 | wake_up_interruptible(&info->port.open_wait); | 2838 | wake_up_interruptible(&info->port.open_wait); |
| 2842 | #endif | 2839 | #endif |
| 2843 | } /* cy_set_termios */ | 2840 | } /* cy_set_termios */ |
| @@ -2899,7 +2896,7 @@ static void cy_throttle(struct tty_struct *tty) | |||
| 2899 | info->throttle = 1; | 2896 | info->throttle = 1; |
| 2900 | } | 2897 | } |
| 2901 | 2898 | ||
| 2902 | if (tty->termios->c_cflag & CRTSCTS) { | 2899 | if (tty->termios.c_cflag & CRTSCTS) { |
| 2903 | if (!cy_is_Z(card)) { | 2900 | if (!cy_is_Z(card)) { |
| 2904 | spin_lock_irqsave(&card->card_lock, flags); | 2901 | spin_lock_irqsave(&card->card_lock, flags); |
| 2905 | cyy_change_rts_dtr(info, 0, TIOCM_RTS); | 2902 | cyy_change_rts_dtr(info, 0, TIOCM_RTS); |
| @@ -2938,7 +2935,7 @@ static void cy_unthrottle(struct tty_struct *tty) | |||
| 2938 | cy_send_xchar(tty, START_CHAR(tty)); | 2935 | cy_send_xchar(tty, START_CHAR(tty)); |
| 2939 | } | 2936 | } |
| 2940 | 2937 | ||
| 2941 | if (tty->termios->c_cflag & CRTSCTS) { | 2938 | if (tty->termios.c_cflag & CRTSCTS) { |
| 2942 | card = info->card; | 2939 | card = info->card; |
| 2943 | if (!cy_is_Z(card)) { | 2940 | if (!cy_is_Z(card)) { |
| 2944 | spin_lock_irqsave(&card->card_lock, flags); | 2941 | spin_lock_irqsave(&card->card_lock, flags); |
| @@ -3289,9 +3286,10 @@ static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, | |||
| 3289 | static int __init cy_detect_isa(void) | 3286 | static int __init cy_detect_isa(void) |
| 3290 | { | 3287 | { |
| 3291 | #ifdef CONFIG_ISA | 3288 | #ifdef CONFIG_ISA |
| 3289 | struct cyclades_card *card; | ||
| 3292 | unsigned short cy_isa_irq, nboard; | 3290 | unsigned short cy_isa_irq, nboard; |
| 3293 | void __iomem *cy_isa_address; | 3291 | void __iomem *cy_isa_address; |
| 3294 | unsigned short i, j, cy_isa_nchan; | 3292 | unsigned short i, j, k, cy_isa_nchan; |
| 3295 | int isparam = 0; | 3293 | int isparam = 0; |
| 3296 | 3294 | ||
| 3297 | nboard = 0; | 3295 | nboard = 0; |
| @@ -3349,7 +3347,8 @@ static int __init cy_detect_isa(void) | |||
| 3349 | } | 3347 | } |
| 3350 | /* fill the next cy_card structure available */ | 3348 | /* fill the next cy_card structure available */ |
| 3351 | for (j = 0; j < NR_CARDS; j++) { | 3349 | for (j = 0; j < NR_CARDS; j++) { |
| 3352 | if (cy_card[j].base_addr == NULL) | 3350 | card = &cy_card[j]; |
| 3351 | if (card->base_addr == NULL) | ||
| 3353 | break; | 3352 | break; |
| 3354 | } | 3353 | } |
| 3355 | if (j == NR_CARDS) { /* no more cy_cards available */ | 3354 | if (j == NR_CARDS) { /* no more cy_cards available */ |
| @@ -3363,7 +3362,7 @@ static int __init cy_detect_isa(void) | |||
| 3363 | 3362 | ||
| 3364 | /* allocate IRQ */ | 3363 | /* allocate IRQ */ |
| 3365 | if (request_irq(cy_isa_irq, cyy_interrupt, | 3364 | if (request_irq(cy_isa_irq, cyy_interrupt, |
| 3366 | 0, "Cyclom-Y", &cy_card[j])) { | 3365 | 0, "Cyclom-Y", card)) { |
| 3367 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but " | 3366 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but " |
| 3368 | "could not allocate IRQ#%d.\n", | 3367 | "could not allocate IRQ#%d.\n", |
| 3369 | (unsigned long)cy_isa_address, cy_isa_irq); | 3368 | (unsigned long)cy_isa_address, cy_isa_irq); |
| @@ -3372,16 +3371,16 @@ static int __init cy_detect_isa(void) | |||
| 3372 | } | 3371 | } |
| 3373 | 3372 | ||
| 3374 | /* set cy_card */ | 3373 | /* set cy_card */ |
| 3375 | cy_card[j].base_addr = cy_isa_address; | 3374 | card->base_addr = cy_isa_address; |
| 3376 | cy_card[j].ctl_addr.p9050 = NULL; | 3375 | card->ctl_addr.p9050 = NULL; |
| 3377 | cy_card[j].irq = (int)cy_isa_irq; | 3376 | card->irq = (int)cy_isa_irq; |
| 3378 | cy_card[j].bus_index = 0; | 3377 | card->bus_index = 0; |
| 3379 | cy_card[j].first_line = cy_next_channel; | 3378 | card->first_line = cy_next_channel; |
| 3380 | cy_card[j].num_chips = cy_isa_nchan / CyPORTS_PER_CHIP; | 3379 | card->num_chips = cy_isa_nchan / CyPORTS_PER_CHIP; |
| 3381 | cy_card[j].nports = cy_isa_nchan; | 3380 | card->nports = cy_isa_nchan; |
| 3382 | if (cy_init_card(&cy_card[j])) { | 3381 | if (cy_init_card(card)) { |
| 3383 | cy_card[j].base_addr = NULL; | 3382 | card->base_addr = NULL; |
| 3384 | free_irq(cy_isa_irq, &cy_card[j]); | 3383 | free_irq(cy_isa_irq, card); |
| 3385 | iounmap(cy_isa_address); | 3384 | iounmap(cy_isa_address); |
| 3386 | continue; | 3385 | continue; |
| 3387 | } | 3386 | } |
| @@ -3393,9 +3392,10 @@ static int __init cy_detect_isa(void) | |||
| 3393 | (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), | 3392 | (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), |
| 3394 | cy_isa_irq, cy_isa_nchan, cy_next_channel); | 3393 | cy_isa_irq, cy_isa_nchan, cy_next_channel); |
| 3395 | 3394 | ||
| 3396 | for (j = cy_next_channel; | 3395 | for (k = 0, j = cy_next_channel; |
| 3397 | j < cy_next_channel + cy_isa_nchan; j++) | 3396 | j < cy_next_channel + cy_isa_nchan; j++, k++) |
| 3398 | tty_register_device(cy_serial_driver, j, NULL); | 3397 | tty_port_register_device(&card->ports[k].port, |
| 3398 | cy_serial_driver, j, NULL); | ||
| 3399 | cy_next_channel += cy_isa_nchan; | 3399 | cy_next_channel += cy_isa_nchan; |
| 3400 | } | 3400 | } |
| 3401 | return nboard; | 3401 | return nboard; |
| @@ -3695,10 +3695,11 @@ err: | |||
| 3695 | static int __devinit cy_pci_probe(struct pci_dev *pdev, | 3695 | static int __devinit cy_pci_probe(struct pci_dev *pdev, |
| 3696 | const struct pci_device_id *ent) | 3696 | const struct pci_device_id *ent) |
| 3697 | { | 3697 | { |
| 3698 | struct cyclades_card *card; | ||
| 3698 | void __iomem *addr0 = NULL, *addr2 = NULL; | 3699 | void __iomem *addr0 = NULL, *addr2 = NULL; |
| 3699 | char *card_name = NULL; | 3700 | char *card_name = NULL; |
| 3700 | u32 uninitialized_var(mailbox); | 3701 | u32 uninitialized_var(mailbox); |
| 3701 | unsigned int device_id, nchan = 0, card_no, i; | 3702 | unsigned int device_id, nchan = 0, card_no, i, j; |
| 3702 | unsigned char plx_ver; | 3703 | unsigned char plx_ver; |
| 3703 | int retval, irq; | 3704 | int retval, irq; |
| 3704 | 3705 | ||
| @@ -3829,7 +3830,8 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
| 3829 | } | 3830 | } |
| 3830 | /* fill the next cy_card structure available */ | 3831 | /* fill the next cy_card structure available */ |
| 3831 | for (card_no = 0; card_no < NR_CARDS; card_no++) { | 3832 | for (card_no = 0; card_no < NR_CARDS; card_no++) { |
| 3832 | if (cy_card[card_no].base_addr == NULL) | 3833 | card = &cy_card[card_no]; |
| 3834 | if (card->base_addr == NULL) | ||
| 3833 | break; | 3835 | break; |
| 3834 | } | 3836 | } |
| 3835 | if (card_no == NR_CARDS) { /* no more cy_cards available */ | 3837 | if (card_no == NR_CARDS) { /* no more cy_cards available */ |
| @@ -3843,27 +3845,26 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
| 3843 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { | 3845 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
| 3844 | /* allocate IRQ */ | 3846 | /* allocate IRQ */ |
| 3845 | retval = request_irq(irq, cyy_interrupt, | 3847 | retval = request_irq(irq, cyy_interrupt, |
| 3846 | IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]); | 3848 | IRQF_SHARED, "Cyclom-Y", card); |
| 3847 | if (retval) { | 3849 | if (retval) { |
| 3848 | dev_err(&pdev->dev, "could not allocate IRQ\n"); | 3850 | dev_err(&pdev->dev, "could not allocate IRQ\n"); |
| 3849 | goto err_unmap; | 3851 | goto err_unmap; |
| 3850 | } | 3852 | } |
| 3851 | cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP; | 3853 | card->num_chips = nchan / CyPORTS_PER_CHIP; |
| 3852 | } else { | 3854 | } else { |
| 3853 | struct FIRM_ID __iomem *firm_id = addr2 + ID_ADDRESS; | 3855 | struct FIRM_ID __iomem *firm_id = addr2 + ID_ADDRESS; |
| 3854 | struct ZFW_CTRL __iomem *zfw_ctrl; | 3856 | struct ZFW_CTRL __iomem *zfw_ctrl; |
| 3855 | 3857 | ||
| 3856 | zfw_ctrl = addr2 + (readl(&firm_id->zfwctrl_addr) & 0xfffff); | 3858 | zfw_ctrl = addr2 + (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
| 3857 | 3859 | ||
| 3858 | cy_card[card_no].hw_ver = mailbox; | 3860 | card->hw_ver = mailbox; |
| 3859 | cy_card[card_no].num_chips = (unsigned int)-1; | 3861 | card->num_chips = (unsigned int)-1; |
| 3860 | cy_card[card_no].board_ctrl = &zfw_ctrl->board_ctrl; | 3862 | card->board_ctrl = &zfw_ctrl->board_ctrl; |
| 3861 | #ifdef CONFIG_CYZ_INTR | 3863 | #ifdef CONFIG_CYZ_INTR |
| 3862 | /* allocate IRQ only if board has an IRQ */ | 3864 | /* allocate IRQ only if board has an IRQ */ |
| 3863 | if (irq != 0 && irq != 255) { | 3865 | if (irq != 0 && irq != 255) { |
| 3864 | retval = request_irq(irq, cyz_interrupt, | 3866 | retval = request_irq(irq, cyz_interrupt, |
| 3865 | IRQF_SHARED, "Cyclades-Z", | 3867 | IRQF_SHARED, "Cyclades-Z", card); |
| 3866 | &cy_card[card_no]); | ||
| 3867 | if (retval) { | 3868 | if (retval) { |
| 3868 | dev_err(&pdev->dev, "could not allocate IRQ\n"); | 3869 | dev_err(&pdev->dev, "could not allocate IRQ\n"); |
| 3869 | goto err_unmap; | 3870 | goto err_unmap; |
| @@ -3873,17 +3874,17 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
| 3873 | } | 3874 | } |
| 3874 | 3875 | ||
| 3875 | /* set cy_card */ | 3876 | /* set cy_card */ |
| 3876 | cy_card[card_no].base_addr = addr2; | 3877 | card->base_addr = addr2; |
| 3877 | cy_card[card_no].ctl_addr.p9050 = addr0; | 3878 | card->ctl_addr.p9050 = addr0; |
| 3878 | cy_card[card_no].irq = irq; | 3879 | card->irq = irq; |
| 3879 | cy_card[card_no].bus_index = 1; | 3880 | card->bus_index = 1; |
| 3880 | cy_card[card_no].first_line = cy_next_channel; | 3881 | card->first_line = cy_next_channel; |
| 3881 | cy_card[card_no].nports = nchan; | 3882 | card->nports = nchan; |
| 3882 | retval = cy_init_card(&cy_card[card_no]); | 3883 | retval = cy_init_card(card); |
| 3883 | if (retval) | 3884 | if (retval) |
| 3884 | goto err_null; | 3885 | goto err_null; |
| 3885 | 3886 | ||
| 3886 | pci_set_drvdata(pdev, &cy_card[card_no]); | 3887 | pci_set_drvdata(pdev, card); |
| 3887 | 3888 | ||
| 3888 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || | 3889 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || |
| 3889 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { | 3890 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
| @@ -3909,14 +3910,15 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
| 3909 | 3910 | ||
| 3910 | dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from " | 3911 | dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from " |
| 3911 | "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel); | 3912 | "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel); |
| 3912 | for (i = cy_next_channel; i < cy_next_channel + nchan; i++) | 3913 | for (j = 0, i = cy_next_channel; i < cy_next_channel + nchan; i++, j++) |
| 3913 | tty_register_device(cy_serial_driver, i, &pdev->dev); | 3914 | tty_port_register_device(&card->ports[j].port, |
| 3915 | cy_serial_driver, i, &pdev->dev); | ||
| 3914 | cy_next_channel += nchan; | 3916 | cy_next_channel += nchan; |
| 3915 | 3917 | ||
| 3916 | return 0; | 3918 | return 0; |
| 3917 | err_null: | 3919 | err_null: |
| 3918 | cy_card[card_no].base_addr = NULL; | 3920 | card->base_addr = NULL; |
| 3919 | free_irq(irq, &cy_card[card_no]); | 3921 | free_irq(irq, card); |
| 3920 | err_unmap: | 3922 | err_unmap: |
| 3921 | iounmap(addr0); | 3923 | iounmap(addr0); |
| 3922 | if (addr2) | 3924 | if (addr2) |
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 4813684cb634..4ab936b7aac6 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c | |||
| @@ -738,16 +738,17 @@ static int __devinit ehv_bc_tty_probe(struct platform_device *pdev) | |||
| 738 | goto error; | 738 | goto error; |
| 739 | } | 739 | } |
| 740 | 740 | ||
| 741 | bc->dev = tty_register_device(ehv_bc_driver, i, &pdev->dev); | 741 | tty_port_init(&bc->port); |
| 742 | bc->port.ops = &ehv_bc_tty_port_ops; | ||
| 743 | |||
| 744 | bc->dev = tty_port_register_device(&bc->port, ehv_bc_driver, i, | ||
| 745 | &pdev->dev); | ||
| 742 | if (IS_ERR(bc->dev)) { | 746 | if (IS_ERR(bc->dev)) { |
| 743 | ret = PTR_ERR(bc->dev); | 747 | ret = PTR_ERR(bc->dev); |
| 744 | dev_err(&pdev->dev, "could not register tty (ret=%i)\n", ret); | 748 | dev_err(&pdev->dev, "could not register tty (ret=%i)\n", ret); |
| 745 | goto error; | 749 | goto error; |
| 746 | } | 750 | } |
| 747 | 751 | ||
| 748 | tty_port_init(&bc->port); | ||
| 749 | bc->port.ops = &ehv_bc_tty_port_ops; | ||
| 750 | |||
| 751 | dev_set_drvdata(&pdev->dev, bc); | 752 | dev_set_drvdata(&pdev->dev, bc); |
| 752 | 753 | ||
| 753 | dev_info(&pdev->dev, "registered /dev/%s%u for byte channel %u\n", | 754 | dev_info(&pdev->dev, "registered /dev/%s%u for byte channel %u\n", |
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig index 0282a83f51fb..f47b734c6a7a 100644 --- a/drivers/tty/hvc/Kconfig +++ b/drivers/tty/hvc/Kconfig | |||
| @@ -76,7 +76,7 @@ config HVC_XEN_FRONTEND | |||
| 76 | 76 | ||
| 77 | config HVC_UDBG | 77 | config HVC_UDBG |
| 78 | bool "udbg based fake hypervisor console" | 78 | bool "udbg based fake hypervisor console" |
| 79 | depends on PPC && EXPERIMENTAL | 79 | depends on PPC |
| 80 | select HVC_DRIVER | 80 | select HVC_DRIVER |
| 81 | default n | 81 | default n |
| 82 | help | 82 | help |
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 2d691eb7c40a..4a652999380f 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c | |||
| @@ -299,20 +299,33 @@ static void hvc_unthrottle(struct tty_struct *tty) | |||
| 299 | hvc_kick(); | 299 | hvc_kick(); |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | static int hvc_install(struct tty_driver *driver, struct tty_struct *tty) | ||
| 303 | { | ||
| 304 | struct hvc_struct *hp; | ||
| 305 | int rc; | ||
| 306 | |||
| 307 | /* Auto increments kref reference if found. */ | ||
| 308 | if (!(hp = hvc_get_by_index(tty->index))) | ||
| 309 | return -ENODEV; | ||
| 310 | |||
| 311 | tty->driver_data = hp; | ||
| 312 | |||
| 313 | rc = tty_port_install(&hp->port, driver, tty); | ||
| 314 | if (rc) | ||
| 315 | tty_port_put(&hp->port); | ||
| 316 | return rc; | ||
| 317 | } | ||
| 318 | |||
| 302 | /* | 319 | /* |
| 303 | * The TTY interface won't be used until after the vio layer has exposed the vty | 320 | * The TTY interface won't be used until after the vio layer has exposed the vty |
| 304 | * adapter to the kernel. | 321 | * adapter to the kernel. |
| 305 | */ | 322 | */ |
| 306 | static int hvc_open(struct tty_struct *tty, struct file * filp) | 323 | static int hvc_open(struct tty_struct *tty, struct file * filp) |
| 307 | { | 324 | { |
| 308 | struct hvc_struct *hp; | 325 | struct hvc_struct *hp = tty->driver_data; |
| 309 | unsigned long flags; | 326 | unsigned long flags; |
| 310 | int rc = 0; | 327 | int rc = 0; |
| 311 | 328 | ||
| 312 | /* Auto increments kref reference if found. */ | ||
| 313 | if (!(hp = hvc_get_by_index(tty->index))) | ||
| 314 | return -ENODEV; | ||
| 315 | |||
| 316 | spin_lock_irqsave(&hp->port.lock, flags); | 329 | spin_lock_irqsave(&hp->port.lock, flags); |
| 317 | /* Check and then increment for fast path open. */ | 330 | /* Check and then increment for fast path open. */ |
| 318 | if (hp->port.count++ > 0) { | 331 | if (hp->port.count++ > 0) { |
| @@ -322,7 +335,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
| 322 | } /* else count == 0 */ | 335 | } /* else count == 0 */ |
| 323 | spin_unlock_irqrestore(&hp->port.lock, flags); | 336 | spin_unlock_irqrestore(&hp->port.lock, flags); |
| 324 | 337 | ||
| 325 | tty->driver_data = hp; | ||
| 326 | tty_port_tty_set(&hp->port, tty); | 338 | tty_port_tty_set(&hp->port, tty); |
| 327 | 339 | ||
| 328 | if (hp->ops->notifier_add) | 340 | if (hp->ops->notifier_add) |
| @@ -389,6 +401,11 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) | |||
| 389 | hp->vtermno, hp->port.count); | 401 | hp->vtermno, hp->port.count); |
| 390 | spin_unlock_irqrestore(&hp->port.lock, flags); | 402 | spin_unlock_irqrestore(&hp->port.lock, flags); |
| 391 | } | 403 | } |
| 404 | } | ||
| 405 | |||
| 406 | static void hvc_cleanup(struct tty_struct *tty) | ||
| 407 | { | ||
| 408 | struct hvc_struct *hp = tty->driver_data; | ||
| 392 | 409 | ||
| 393 | tty_port_put(&hp->port); | 410 | tty_port_put(&hp->port); |
| 394 | } | 411 | } |
| @@ -541,7 +558,7 @@ static int hvc_write_room(struct tty_struct *tty) | |||
| 541 | struct hvc_struct *hp = tty->driver_data; | 558 | struct hvc_struct *hp = tty->driver_data; |
| 542 | 559 | ||
| 543 | if (!hp) | 560 | if (!hp) |
| 544 | return -1; | 561 | return 0; |
| 545 | 562 | ||
| 546 | return hp->outbuf_size - hp->n_outbuf; | 563 | return hp->outbuf_size - hp->n_outbuf; |
| 547 | } | 564 | } |
| @@ -792,8 +809,10 @@ static void hvc_poll_put_char(struct tty_driver *driver, int line, char ch) | |||
| 792 | #endif | 809 | #endif |
| 793 | 810 | ||
| 794 | static const struct tty_operations hvc_ops = { | 811 | static const struct tty_operations hvc_ops = { |
| 812 | .install = hvc_install, | ||
| 795 | .open = hvc_open, | 813 | .open = hvc_open, |
| 796 | .close = hvc_close, | 814 | .close = hvc_close, |
| 815 | .cleanup = hvc_cleanup, | ||
| 797 | .write = hvc_write, | 816 | .write = hvc_write, |
| 798 | .hangup = hvc_hangup, | 817 | .hangup = hvc_hangup, |
| 799 | .unthrottle = hvc_unthrottle, | 818 | .unthrottle = hvc_unthrottle, |
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index d56788c83974..cab5c7adf8e8 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c | |||
| @@ -1102,27 +1102,20 @@ static struct hvcs_struct *hvcs_get_by_index(int index) | |||
| 1102 | return NULL; | 1102 | return NULL; |
| 1103 | } | 1103 | } |
| 1104 | 1104 | ||
| 1105 | /* | 1105 | static int hvcs_install(struct tty_driver *driver, struct tty_struct *tty) |
| 1106 | * This is invoked via the tty_open interface when a user app connects to the | ||
| 1107 | * /dev node. | ||
| 1108 | */ | ||
| 1109 | static int hvcs_open(struct tty_struct *tty, struct file *filp) | ||
| 1110 | { | 1106 | { |
| 1111 | struct hvcs_struct *hvcsd; | 1107 | struct hvcs_struct *hvcsd; |
| 1112 | int rc, retval = 0; | ||
| 1113 | unsigned long flags; | ||
| 1114 | unsigned int irq; | ||
| 1115 | struct vio_dev *vdev; | 1108 | struct vio_dev *vdev; |
| 1116 | unsigned long unit_address; | 1109 | unsigned long unit_address, flags; |
| 1117 | 1110 | unsigned int irq; | |
| 1118 | if (tty->driver_data) | 1111 | int retval; |
| 1119 | goto fast_open; | ||
| 1120 | 1112 | ||
| 1121 | /* | 1113 | /* |
| 1122 | * Is there a vty-server that shares the same index? | 1114 | * Is there a vty-server that shares the same index? |
| 1123 | * This function increments the kref index. | 1115 | * This function increments the kref index. |
| 1124 | */ | 1116 | */ |
| 1125 | if (!(hvcsd = hvcs_get_by_index(tty->index))) { | 1117 | hvcsd = hvcs_get_by_index(tty->index); |
| 1118 | if (!hvcsd) { | ||
| 1126 | printk(KERN_WARNING "HVCS: open failed, no device associated" | 1119 | printk(KERN_WARNING "HVCS: open failed, no device associated" |
| 1127 | " with tty->index %d.\n", tty->index); | 1120 | " with tty->index %d.\n", tty->index); |
| 1128 | return -ENODEV; | 1121 | return -ENODEV; |
| @@ -1130,11 +1123,16 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp) | |||
| 1130 | 1123 | ||
| 1131 | spin_lock_irqsave(&hvcsd->lock, flags); | 1124 | spin_lock_irqsave(&hvcsd->lock, flags); |
| 1132 | 1125 | ||
| 1133 | if (hvcsd->connected == 0) | 1126 | if (hvcsd->connected == 0) { |
| 1134 | if ((retval = hvcs_partner_connect(hvcsd))) | 1127 | retval = hvcs_partner_connect(hvcsd); |
| 1135 | goto error_release; | 1128 | if (retval) { |
| 1129 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
| 1130 | printk(KERN_WARNING "HVCS: partner connect failed.\n"); | ||
| 1131 | goto err_put; | ||
| 1132 | } | ||
| 1133 | } | ||
| 1136 | 1134 | ||
| 1137 | hvcsd->port.count = 1; | 1135 | hvcsd->port.count = 0; |
| 1138 | hvcsd->port.tty = tty; | 1136 | hvcsd->port.tty = tty; |
| 1139 | tty->driver_data = hvcsd; | 1137 | tty->driver_data = hvcsd; |
| 1140 | 1138 | ||
| @@ -1155,37 +1153,48 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp) | |||
| 1155 | * This must be done outside of the spinlock because it requests irqs | 1153 | * This must be done outside of the spinlock because it requests irqs |
| 1156 | * and will grab the spinlock and free the connection if it fails. | 1154 | * and will grab the spinlock and free the connection if it fails. |
| 1157 | */ | 1155 | */ |
| 1158 | if (((rc = hvcs_enable_device(hvcsd, unit_address, irq, vdev)))) { | 1156 | retval = hvcs_enable_device(hvcsd, unit_address, irq, vdev); |
| 1159 | tty_port_put(&hvcsd->port); | 1157 | if (retval) { |
| 1160 | printk(KERN_WARNING "HVCS: enable device failed.\n"); | 1158 | printk(KERN_WARNING "HVCS: enable device failed.\n"); |
| 1161 | return rc; | 1159 | goto err_put; |
| 1162 | } | 1160 | } |
| 1163 | 1161 | ||
| 1164 | goto open_success; | 1162 | retval = tty_port_install(&hvcsd->port, driver, tty); |
| 1163 | if (retval) | ||
| 1164 | goto err_irq; | ||
| 1165 | 1165 | ||
| 1166 | fast_open: | 1166 | return 0; |
| 1167 | hvcsd = tty->driver_data; | 1167 | err_irq: |
| 1168 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
| 1169 | vio_disable_interrupts(hvcsd->vdev); | ||
| 1170 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
| 1171 | free_irq(irq, hvcsd); | ||
| 1172 | err_put: | ||
| 1173 | tty_port_put(&hvcsd->port); | ||
| 1174 | |||
| 1175 | return retval; | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | /* | ||
| 1179 | * This is invoked via the tty_open interface when a user app connects to the | ||
| 1180 | * /dev node. | ||
| 1181 | */ | ||
| 1182 | static int hvcs_open(struct tty_struct *tty, struct file *filp) | ||
| 1183 | { | ||
| 1184 | struct hvcs_struct *hvcsd = tty->driver_data; | ||
| 1185 | unsigned long flags; | ||
| 1168 | 1186 | ||
| 1169 | spin_lock_irqsave(&hvcsd->lock, flags); | 1187 | spin_lock_irqsave(&hvcsd->lock, flags); |
| 1170 | tty_port_get(&hvcsd->port); | ||
| 1171 | hvcsd->port.count++; | 1188 | hvcsd->port.count++; |
| 1172 | hvcsd->todo_mask |= HVCS_SCHED_READ; | 1189 | hvcsd->todo_mask |= HVCS_SCHED_READ; |
| 1173 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 1190 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
| 1174 | 1191 | ||
| 1175 | open_success: | ||
| 1176 | hvcs_kick(); | 1192 | hvcs_kick(); |
| 1177 | 1193 | ||
| 1178 | printk(KERN_INFO "HVCS: vty-server@%X connection opened.\n", | 1194 | printk(KERN_INFO "HVCS: vty-server@%X connection opened.\n", |
| 1179 | hvcsd->vdev->unit_address ); | 1195 | hvcsd->vdev->unit_address ); |
| 1180 | 1196 | ||
| 1181 | return 0; | 1197 | return 0; |
| 1182 | |||
| 1183 | error_release: | ||
| 1184 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
| 1185 | tty_port_put(&hvcsd->port); | ||
| 1186 | |||
| 1187 | printk(KERN_WARNING "HVCS: partner connect failed.\n"); | ||
| 1188 | return retval; | ||
| 1189 | } | 1198 | } |
| 1190 | 1199 | ||
| 1191 | static void hvcs_close(struct tty_struct *tty, struct file *filp) | 1200 | static void hvcs_close(struct tty_struct *tty, struct file *filp) |
| @@ -1236,7 +1245,6 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) | |||
| 1236 | tty->driver_data = NULL; | 1245 | tty->driver_data = NULL; |
| 1237 | 1246 | ||
| 1238 | free_irq(irq, hvcsd); | 1247 | free_irq(irq, hvcsd); |
| 1239 | tty_port_put(&hvcsd->port); | ||
| 1240 | return; | 1248 | return; |
| 1241 | } else if (hvcsd->port.count < 0) { | 1249 | } else if (hvcsd->port.count < 0) { |
| 1242 | printk(KERN_ERR "HVCS: vty-server@%X open_count: %d" | 1250 | printk(KERN_ERR "HVCS: vty-server@%X open_count: %d" |
| @@ -1245,6 +1253,12 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) | |||
| 1245 | } | 1253 | } |
| 1246 | 1254 | ||
| 1247 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 1255 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
| 1256 | } | ||
| 1257 | |||
| 1258 | static void hvcs_cleanup(struct tty_struct * tty) | ||
| 1259 | { | ||
| 1260 | struct hvcs_struct *hvcsd = tty->driver_data; | ||
| 1261 | |||
| 1248 | tty_port_put(&hvcsd->port); | 1262 | tty_port_put(&hvcsd->port); |
| 1249 | } | 1263 | } |
| 1250 | 1264 | ||
| @@ -1431,8 +1445,10 @@ static int hvcs_chars_in_buffer(struct tty_struct *tty) | |||
| 1431 | } | 1445 | } |
| 1432 | 1446 | ||
| 1433 | static const struct tty_operations hvcs_ops = { | 1447 | static const struct tty_operations hvcs_ops = { |
| 1448 | .install = hvcs_install, | ||
| 1434 | .open = hvcs_open, | 1449 | .open = hvcs_open, |
| 1435 | .close = hvcs_close, | 1450 | .close = hvcs_close, |
| 1451 | .cleanup = hvcs_cleanup, | ||
| 1436 | .hangup = hvcs_hangup, | 1452 | .hangup = hvcs_hangup, |
| 1437 | .write = hvcs_write, | 1453 | .write = hvcs_write, |
| 1438 | .write_room = hvcs_write_room, | 1454 | .write_room = hvcs_write_room, |
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index 6f5bc49c441f..0083bc1f63f4 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c | |||
| @@ -1080,6 +1080,8 @@ static int __init hvsi_init(void) | |||
| 1080 | struct hvsi_struct *hp = &hvsi_ports[i]; | 1080 | struct hvsi_struct *hp = &hvsi_ports[i]; |
| 1081 | int ret = 1; | 1081 | int ret = 1; |
| 1082 | 1082 | ||
| 1083 | tty_port_link_device(&hp->port, hvsi_driver, i); | ||
| 1084 | |||
| 1083 | ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp); | 1085 | ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp); |
| 1084 | if (ret) | 1086 | if (ret) |
| 1085 | printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n", | 1087 | printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n", |
diff --git a/drivers/tty/hvc/hvsi_lib.c b/drivers/tty/hvc/hvsi_lib.c index 59c135dd5d20..3396eb9d57a3 100644 --- a/drivers/tty/hvc/hvsi_lib.c +++ b/drivers/tty/hvc/hvsi_lib.c | |||
| @@ -400,7 +400,7 @@ void hvsilib_close(struct hvsi_priv *pv, struct hvc_struct *hp) | |||
| 400 | spin_unlock_irqrestore(&hp->lock, flags); | 400 | spin_unlock_irqrestore(&hp->lock, flags); |
| 401 | 401 | ||
| 402 | /* Clear our own DTR */ | 402 | /* Clear our own DTR */ |
| 403 | if (!pv->tty || (pv->tty->termios->c_cflag & HUPCL)) | 403 | if (!pv->tty || (pv->tty->termios.c_cflag & HUPCL)) |
| 404 | hvsilib_write_mctrl(pv, 0); | 404 | hvsilib_write_mctrl(pv, 0); |
| 405 | 405 | ||
| 406 | /* Tear down the connection */ | 406 | /* Tear down the connection */ |
diff --git a/drivers/tty/ipwireless/network.c b/drivers/tty/ipwireless/network.c index 57c8b481113f..d2af155dec8b 100644 --- a/drivers/tty/ipwireless/network.c +++ b/drivers/tty/ipwireless/network.c | |||
| @@ -274,7 +274,12 @@ static void do_go_online(struct work_struct *work_go_online) | |||
| 274 | network->xaccm[0] = ~0U; | 274 | network->xaccm[0] = ~0U; |
| 275 | network->xaccm[3] = 0x60000000U; | 275 | network->xaccm[3] = 0x60000000U; |
| 276 | network->raccm = ~0U; | 276 | network->raccm = ~0U; |
| 277 | ppp_register_channel(channel); | 277 | if (ppp_register_channel(channel) < 0) { |
| 278 | printk(KERN_ERR IPWIRELESS_PCCARD_NAME | ||
| 279 | ": unable to register PPP channel\n"); | ||
| 280 | kfree(channel); | ||
| 281 | return; | ||
| 282 | } | ||
| 278 | spin_lock_irqsave(&network->lock, flags); | 283 | spin_lock_irqsave(&network->lock, flags); |
| 279 | network->ppp_channel = channel; | 284 | network->ppp_channel = channel; |
| 280 | } | 285 | } |
diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index f8b5fa0093a3..160f0ad9589d 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c | |||
| @@ -476,7 +476,7 @@ static int add_tty(int j, | |||
| 476 | mutex_init(&ttys[j]->ipw_tty_mutex); | 476 | mutex_init(&ttys[j]->ipw_tty_mutex); |
| 477 | tty_port_init(&ttys[j]->port); | 477 | tty_port_init(&ttys[j]->port); |
| 478 | 478 | ||
| 479 | tty_register_device(ipw_tty_driver, j, NULL); | 479 | tty_port_register_device(&ttys[j]->port, ipw_tty_driver, j, NULL); |
| 480 | ipwireless_associate_network_tty(network, channel_idx, ttys[j]); | 480 | ipwireless_associate_network_tty(network, channel_idx, ttys[j]); |
| 481 | 481 | ||
| 482 | if (secondary_channel_idx != -1) | 482 | if (secondary_channel_idx != -1) |
diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index e1235accab74..d7492e183607 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c | |||
| @@ -600,7 +600,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
| 600 | port->status &= ~ISI_DCD; | 600 | port->status &= ~ISI_DCD; |
| 601 | } | 601 | } |
| 602 | 602 | ||
| 603 | if (port->port.flags & ASYNC_CTS_FLOW) { | 603 | if (tty_port_cts_enabled(&port->port)) { |
| 604 | if (tty->hw_stopped) { | 604 | if (tty->hw_stopped) { |
| 605 | if (header & ISI_CTS) { | 605 | if (header & ISI_CTS) { |
| 606 | port->port.tty->hw_stopped = 0; | 606 | port->port.tty->hw_stopped = 0; |
| @@ -702,7 +702,7 @@ static void isicom_config_port(struct tty_struct *tty) | |||
| 702 | 702 | ||
| 703 | /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ | 703 | /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ |
| 704 | if (baud < 1 || baud > 4) | 704 | if (baud < 1 || baud > 4) |
| 705 | tty->termios->c_cflag &= ~CBAUDEX; | 705 | tty->termios.c_cflag &= ~CBAUDEX; |
| 706 | else | 706 | else |
| 707 | baud += 15; | 707 | baud += 15; |
| 708 | } | 708 | } |
| @@ -1196,8 +1196,8 @@ static void isicom_set_termios(struct tty_struct *tty, | |||
| 1196 | if (isicom_paranoia_check(port, tty->name, "isicom_set_termios")) | 1196 | if (isicom_paranoia_check(port, tty->name, "isicom_set_termios")) |
| 1197 | return; | 1197 | return; |
| 1198 | 1198 | ||
| 1199 | if (tty->termios->c_cflag == old_termios->c_cflag && | 1199 | if (tty->termios.c_cflag == old_termios->c_cflag && |
| 1200 | tty->termios->c_iflag == old_termios->c_iflag) | 1200 | tty->termios.c_iflag == old_termios->c_iflag) |
| 1201 | return; | 1201 | return; |
| 1202 | 1202 | ||
| 1203 | spin_lock_irqsave(&port->card->card_lock, flags); | 1203 | spin_lock_irqsave(&port->card->card_lock, flags); |
| @@ -1205,7 +1205,7 @@ static void isicom_set_termios(struct tty_struct *tty, | |||
| 1205 | spin_unlock_irqrestore(&port->card->card_lock, flags); | 1205 | spin_unlock_irqrestore(&port->card->card_lock, flags); |
| 1206 | 1206 | ||
| 1207 | if ((old_termios->c_cflag & CRTSCTS) && | 1207 | if ((old_termios->c_cflag & CRTSCTS) && |
| 1208 | !(tty->termios->c_cflag & CRTSCTS)) { | 1208 | !(tty->termios.c_cflag & CRTSCTS)) { |
| 1209 | tty->hw_stopped = 0; | 1209 | tty->hw_stopped = 0; |
| 1210 | isicom_start(tty); | 1210 | isicom_start(tty); |
| 1211 | } | 1211 | } |
| @@ -1611,7 +1611,8 @@ static int __devinit isicom_probe(struct pci_dev *pdev, | |||
| 1611 | goto errunri; | 1611 | goto errunri; |
| 1612 | 1612 | ||
| 1613 | for (index = 0; index < board->port_count; index++) | 1613 | for (index = 0; index < board->port_count; index++) |
| 1614 | tty_register_device(isicom_normal, board->index * 16 + index, | 1614 | tty_port_register_device(&board->ports[index].port, |
| 1615 | isicom_normal, board->index * 16 + index, | ||
| 1615 | &pdev->dev); | 1616 | &pdev->dev); |
| 1616 | 1617 | ||
| 1617 | return 0; | 1618 | return 0; |
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 324467d28a54..56e616b9109a 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c | |||
| @@ -169,6 +169,7 @@ static DEFINE_SPINLOCK(moxa_lock); | |||
| 169 | static unsigned long baseaddr[MAX_BOARDS]; | 169 | static unsigned long baseaddr[MAX_BOARDS]; |
| 170 | static unsigned int type[MAX_BOARDS]; | 170 | static unsigned int type[MAX_BOARDS]; |
| 171 | static unsigned int numports[MAX_BOARDS]; | 171 | static unsigned int numports[MAX_BOARDS]; |
| 172 | static struct tty_port moxa_service_port; | ||
| 172 | 173 | ||
| 173 | MODULE_AUTHOR("William Chen"); | 174 | MODULE_AUTHOR("William Chen"); |
| 174 | MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver"); | 175 | MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver"); |
| @@ -367,10 +368,10 @@ static int moxa_ioctl(struct tty_struct *tty, | |||
| 367 | tmp.dcd = 1; | 368 | tmp.dcd = 1; |
| 368 | 369 | ||
| 369 | ttyp = tty_port_tty_get(&p->port); | 370 | ttyp = tty_port_tty_get(&p->port); |
| 370 | if (!ttyp || !ttyp->termios) | 371 | if (!ttyp) |
| 371 | tmp.cflag = p->cflag; | 372 | tmp.cflag = p->cflag; |
| 372 | else | 373 | else |
| 373 | tmp.cflag = ttyp->termios->c_cflag; | 374 | tmp.cflag = ttyp->termios.c_cflag; |
| 374 | tty_kref_put(ttyp); | 375 | tty_kref_put(ttyp); |
| 375 | copy: | 376 | copy: |
| 376 | if (copy_to_user(argm, &tmp, sizeof(tmp))) | 377 | if (copy_to_user(argm, &tmp, sizeof(tmp))) |
| @@ -834,7 +835,7 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev) | |||
| 834 | const struct firmware *fw; | 835 | const struct firmware *fw; |
| 835 | const char *file; | 836 | const char *file; |
| 836 | struct moxa_port *p; | 837 | struct moxa_port *p; |
| 837 | unsigned int i; | 838 | unsigned int i, first_idx; |
| 838 | int ret; | 839 | int ret; |
| 839 | 840 | ||
| 840 | brd->ports = kcalloc(MAX_PORTS_PER_BOARD, sizeof(*brd->ports), | 841 | brd->ports = kcalloc(MAX_PORTS_PER_BOARD, sizeof(*brd->ports), |
| @@ -887,6 +888,11 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev) | |||
| 887 | mod_timer(&moxaTimer, jiffies + HZ / 50); | 888 | mod_timer(&moxaTimer, jiffies + HZ / 50); |
| 888 | spin_unlock_bh(&moxa_lock); | 889 | spin_unlock_bh(&moxa_lock); |
| 889 | 890 | ||
| 891 | first_idx = (brd - moxa_boards) * MAX_PORTS_PER_BOARD; | ||
| 892 | for (i = 0; i < brd->numPorts; i++) | ||
| 893 | tty_port_register_device(&brd->ports[i].port, moxaDriver, | ||
| 894 | first_idx + i, dev); | ||
| 895 | |||
| 890 | return 0; | 896 | return 0; |
| 891 | err_free: | 897 | err_free: |
| 892 | kfree(brd->ports); | 898 | kfree(brd->ports); |
| @@ -896,7 +902,7 @@ err: | |||
| 896 | 902 | ||
| 897 | static void moxa_board_deinit(struct moxa_board_conf *brd) | 903 | static void moxa_board_deinit(struct moxa_board_conf *brd) |
| 898 | { | 904 | { |
| 899 | unsigned int a, opened; | 905 | unsigned int a, opened, first_idx; |
| 900 | 906 | ||
| 901 | mutex_lock(&moxa_openlock); | 907 | mutex_lock(&moxa_openlock); |
| 902 | spin_lock_bh(&moxa_lock); | 908 | spin_lock_bh(&moxa_lock); |
| @@ -925,6 +931,10 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) | |||
| 925 | mutex_lock(&moxa_openlock); | 931 | mutex_lock(&moxa_openlock); |
| 926 | } | 932 | } |
| 927 | 933 | ||
| 934 | first_idx = (brd - moxa_boards) * MAX_PORTS_PER_BOARD; | ||
| 935 | for (a = 0; a < brd->numPorts; a++) | ||
| 936 | tty_unregister_device(moxaDriver, first_idx + a); | ||
| 937 | |||
| 928 | iounmap(brd->basemem); | 938 | iounmap(brd->basemem); |
| 929 | brd->basemem = NULL; | 939 | brd->basemem = NULL; |
| 930 | kfree(brd->ports); | 940 | kfree(brd->ports); |
| @@ -967,6 +977,7 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev, | |||
| 967 | board->basemem = ioremap_nocache(pci_resource_start(pdev, 2), 0x4000); | 977 | board->basemem = ioremap_nocache(pci_resource_start(pdev, 2), 0x4000); |
| 968 | if (board->basemem == NULL) { | 978 | if (board->basemem == NULL) { |
| 969 | dev_err(&pdev->dev, "can't remap io space 2\n"); | 979 | dev_err(&pdev->dev, "can't remap io space 2\n"); |
| 980 | retval = -ENOMEM; | ||
| 970 | goto err_reg; | 981 | goto err_reg; |
| 971 | } | 982 | } |
| 972 | 983 | ||
| @@ -1031,9 +1042,14 @@ static int __init moxa_init(void) | |||
| 1031 | 1042 | ||
| 1032 | printk(KERN_INFO "MOXA Intellio family driver version %s\n", | 1043 | printk(KERN_INFO "MOXA Intellio family driver version %s\n", |
| 1033 | MOXA_VERSION); | 1044 | MOXA_VERSION); |
| 1034 | moxaDriver = alloc_tty_driver(MAX_PORTS + 1); | 1045 | |
| 1035 | if (!moxaDriver) | 1046 | tty_port_init(&moxa_service_port); |
| 1036 | return -ENOMEM; | 1047 | |
| 1048 | moxaDriver = tty_alloc_driver(MAX_PORTS + 1, | ||
| 1049 | TTY_DRIVER_REAL_RAW | | ||
| 1050 | TTY_DRIVER_DYNAMIC_DEV); | ||
| 1051 | if (IS_ERR(moxaDriver)) | ||
| 1052 | return PTR_ERR(moxaDriver); | ||
| 1037 | 1053 | ||
| 1038 | moxaDriver->name = "ttyMX"; | 1054 | moxaDriver->name = "ttyMX"; |
| 1039 | moxaDriver->major = ttymajor; | 1055 | moxaDriver->major = ttymajor; |
| @@ -1044,8 +1060,9 @@ static int __init moxa_init(void) | |||
| 1044 | moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; | 1060 | moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; |
| 1045 | moxaDriver->init_termios.c_ispeed = 9600; | 1061 | moxaDriver->init_termios.c_ispeed = 9600; |
| 1046 | moxaDriver->init_termios.c_ospeed = 9600; | 1062 | moxaDriver->init_termios.c_ospeed = 9600; |
| 1047 | moxaDriver->flags = TTY_DRIVER_REAL_RAW; | ||
| 1048 | tty_set_operations(moxaDriver, &moxa_ops); | 1063 | tty_set_operations(moxaDriver, &moxa_ops); |
| 1064 | /* Having one more port only for ioctls is ugly */ | ||
| 1065 | tty_port_link_device(&moxa_service_port, moxaDriver, MAX_PORTS); | ||
| 1049 | 1066 | ||
| 1050 | if (tty_register_driver(moxaDriver)) { | 1067 | if (tty_register_driver(moxaDriver)) { |
| 1051 | printk(KERN_ERR "can't register MOXA Smartio tty driver!\n"); | 1068 | printk(KERN_ERR "can't register MOXA Smartio tty driver!\n"); |
| @@ -1178,7 +1195,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
| 1178 | mutex_lock(&ch->port.mutex); | 1195 | mutex_lock(&ch->port.mutex); |
| 1179 | if (!(ch->port.flags & ASYNC_INITIALIZED)) { | 1196 | if (!(ch->port.flags & ASYNC_INITIALIZED)) { |
| 1180 | ch->statusflags = 0; | 1197 | ch->statusflags = 0; |
| 1181 | moxa_set_tty_param(tty, tty->termios); | 1198 | moxa_set_tty_param(tty, &tty->termios); |
| 1182 | MoxaPortLineCtrl(ch, 1, 1); | 1199 | MoxaPortLineCtrl(ch, 1, 1); |
| 1183 | MoxaPortEnable(ch); | 1200 | MoxaPortEnable(ch); |
| 1184 | MoxaSetFifo(ch, ch->type == PORT_16550A); | 1201 | MoxaSetFifo(ch, ch->type == PORT_16550A); |
| @@ -1193,7 +1210,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
| 1193 | static void moxa_close(struct tty_struct *tty, struct file *filp) | 1210 | static void moxa_close(struct tty_struct *tty, struct file *filp) |
| 1194 | { | 1211 | { |
| 1195 | struct moxa_port *ch = tty->driver_data; | 1212 | struct moxa_port *ch = tty->driver_data; |
| 1196 | ch->cflag = tty->termios->c_cflag; | 1213 | ch->cflag = tty->termios.c_cflag; |
| 1197 | tty_port_close(&ch->port, tty, filp); | 1214 | tty_port_close(&ch->port, tty, filp); |
| 1198 | } | 1215 | } |
| 1199 | 1216 | ||
| @@ -1464,7 +1481,7 @@ static void moxa_poll(unsigned long ignored) | |||
| 1464 | 1481 | ||
| 1465 | static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_termios) | 1482 | static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_termios) |
| 1466 | { | 1483 | { |
| 1467 | register struct ktermios *ts = tty->termios; | 1484 | register struct ktermios *ts = &tty->termios; |
| 1468 | struct moxa_port *ch = tty->driver_data; | 1485 | struct moxa_port *ch = tty->driver_data; |
| 1469 | int rts, cts, txflow, rxflow, xany, baud; | 1486 | int rts, cts, txflow, rxflow, xany, baud; |
| 1470 | 1487 | ||
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 90cc680c4f0e..cfda47dabd28 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c | |||
| @@ -643,7 +643,7 @@ static int mxser_change_speed(struct tty_struct *tty, | |||
| 643 | int ret = 0; | 643 | int ret = 0; |
| 644 | unsigned char status; | 644 | unsigned char status; |
| 645 | 645 | ||
| 646 | cflag = tty->termios->c_cflag; | 646 | cflag = tty->termios.c_cflag; |
| 647 | if (!info->ioaddr) | 647 | if (!info->ioaddr) |
| 648 | return ret; | 648 | return ret; |
| 649 | 649 | ||
| @@ -830,7 +830,7 @@ static void mxser_check_modem_status(struct tty_struct *tty, | |||
| 830 | wake_up_interruptible(&port->port.open_wait); | 830 | wake_up_interruptible(&port->port.open_wait); |
| 831 | } | 831 | } |
| 832 | 832 | ||
| 833 | if (port->port.flags & ASYNC_CTS_FLOW) { | 833 | if (tty_port_cts_enabled(&port->port)) { |
| 834 | if (tty->hw_stopped) { | 834 | if (tty->hw_stopped) { |
| 835 | if (status & UART_MSR_CTS) { | 835 | if (status & UART_MSR_CTS) { |
| 836 | tty->hw_stopped = 0; | 836 | tty->hw_stopped = 0; |
| @@ -1520,10 +1520,10 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
| 1520 | 1520 | ||
| 1521 | tty = tty_port_tty_get(port); | 1521 | tty = tty_port_tty_get(port); |
| 1522 | 1522 | ||
| 1523 | if (!tty || !tty->termios) | 1523 | if (!tty) |
| 1524 | ms.cflag = ip->normal_termios.c_cflag; | 1524 | ms.cflag = ip->normal_termios.c_cflag; |
| 1525 | else | 1525 | else |
| 1526 | ms.cflag = tty->termios->c_cflag; | 1526 | ms.cflag = tty->termios.c_cflag; |
| 1527 | tty_kref_put(tty); | 1527 | tty_kref_put(tty); |
| 1528 | spin_lock_irq(&ip->slock); | 1528 | spin_lock_irq(&ip->slock); |
| 1529 | status = inb(ip->ioaddr + UART_MSR); | 1529 | status = inb(ip->ioaddr + UART_MSR); |
| @@ -1589,13 +1589,13 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
| 1589 | 1589 | ||
| 1590 | tty = tty_port_tty_get(&ip->port); | 1590 | tty = tty_port_tty_get(&ip->port); |
| 1591 | 1591 | ||
| 1592 | if (!tty || !tty->termios) { | 1592 | if (!tty) { |
| 1593 | cflag = ip->normal_termios.c_cflag; | 1593 | cflag = ip->normal_termios.c_cflag; |
| 1594 | iflag = ip->normal_termios.c_iflag; | 1594 | iflag = ip->normal_termios.c_iflag; |
| 1595 | me->baudrate[p] = tty_termios_baud_rate(&ip->normal_termios); | 1595 | me->baudrate[p] = tty_termios_baud_rate(&ip->normal_termios); |
| 1596 | } else { | 1596 | } else { |
| 1597 | cflag = tty->termios->c_cflag; | 1597 | cflag = tty->termios.c_cflag; |
| 1598 | iflag = tty->termios->c_iflag; | 1598 | iflag = tty->termios.c_iflag; |
| 1599 | me->baudrate[p] = tty_get_baud_rate(tty); | 1599 | me->baudrate[p] = tty_get_baud_rate(tty); |
| 1600 | } | 1600 | } |
| 1601 | tty_kref_put(tty); | 1601 | tty_kref_put(tty); |
| @@ -1853,7 +1853,7 @@ static void mxser_stoprx(struct tty_struct *tty) | |||
| 1853 | } | 1853 | } |
| 1854 | } | 1854 | } |
| 1855 | 1855 | ||
| 1856 | if (tty->termios->c_cflag & CRTSCTS) { | 1856 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1857 | info->MCR &= ~UART_MCR_RTS; | 1857 | info->MCR &= ~UART_MCR_RTS; |
| 1858 | outb(info->MCR, info->ioaddr + UART_MCR); | 1858 | outb(info->MCR, info->ioaddr + UART_MCR); |
| 1859 | } | 1859 | } |
| @@ -1890,7 +1890,7 @@ static void mxser_unthrottle(struct tty_struct *tty) | |||
| 1890 | } | 1890 | } |
| 1891 | } | 1891 | } |
| 1892 | 1892 | ||
| 1893 | if (tty->termios->c_cflag & CRTSCTS) { | 1893 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1894 | info->MCR |= UART_MCR_RTS; | 1894 | info->MCR |= UART_MCR_RTS; |
| 1895 | outb(info->MCR, info->ioaddr + UART_MCR); | 1895 | outb(info->MCR, info->ioaddr + UART_MCR); |
| 1896 | } | 1896 | } |
| @@ -1939,14 +1939,14 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi | |||
| 1939 | spin_unlock_irqrestore(&info->slock, flags); | 1939 | spin_unlock_irqrestore(&info->slock, flags); |
| 1940 | 1940 | ||
| 1941 | if ((old_termios->c_cflag & CRTSCTS) && | 1941 | if ((old_termios->c_cflag & CRTSCTS) && |
| 1942 | !(tty->termios->c_cflag & CRTSCTS)) { | 1942 | !(tty->termios.c_cflag & CRTSCTS)) { |
| 1943 | tty->hw_stopped = 0; | 1943 | tty->hw_stopped = 0; |
| 1944 | mxser_start(tty); | 1944 | mxser_start(tty); |
| 1945 | } | 1945 | } |
| 1946 | 1946 | ||
| 1947 | /* Handle sw stopped */ | 1947 | /* Handle sw stopped */ |
| 1948 | if ((old_termios->c_iflag & IXON) && | 1948 | if ((old_termios->c_iflag & IXON) && |
| 1949 | !(tty->termios->c_iflag & IXON)) { | 1949 | !(tty->termios.c_iflag & IXON)) { |
| 1950 | tty->stopped = 0; | 1950 | tty->stopped = 0; |
| 1951 | 1951 | ||
| 1952 | if (info->board->chip_flag) { | 1952 | if (info->board->chip_flag) { |
| @@ -2337,11 +2337,36 @@ static struct tty_port_operations mxser_port_ops = { | |||
| 2337 | * The MOXA Smartio/Industio serial driver boot-time initialization code! | 2337 | * The MOXA Smartio/Industio serial driver boot-time initialization code! |
| 2338 | */ | 2338 | */ |
| 2339 | 2339 | ||
| 2340 | static bool allow_overlapping_vector; | ||
| 2341 | module_param(allow_overlapping_vector, bool, S_IRUGO); | ||
| 2342 | MODULE_PARM_DESC(allow_overlapping_vector, "whether we allow ISA cards to be configured such that vector overlabs IO ports (default=no)"); | ||
| 2343 | |||
| 2344 | static bool mxser_overlapping_vector(struct mxser_board *brd) | ||
| 2345 | { | ||
| 2346 | return allow_overlapping_vector && | ||
| 2347 | brd->vector >= brd->ports[0].ioaddr && | ||
| 2348 | brd->vector < brd->ports[0].ioaddr + 8 * brd->info->nports; | ||
| 2349 | } | ||
| 2350 | |||
| 2351 | static int mxser_request_vector(struct mxser_board *brd) | ||
| 2352 | { | ||
| 2353 | if (mxser_overlapping_vector(brd)) | ||
| 2354 | return 0; | ||
| 2355 | return request_region(brd->vector, 1, "mxser(vector)") ? 0 : -EIO; | ||
| 2356 | } | ||
| 2357 | |||
| 2358 | static void mxser_release_vector(struct mxser_board *brd) | ||
| 2359 | { | ||
| 2360 | if (mxser_overlapping_vector(brd)) | ||
| 2361 | return; | ||
| 2362 | release_region(brd->vector, 1); | ||
| 2363 | } | ||
| 2364 | |||
| 2340 | static void mxser_release_ISA_res(struct mxser_board *brd) | 2365 | static void mxser_release_ISA_res(struct mxser_board *brd) |
| 2341 | { | 2366 | { |
| 2342 | free_irq(brd->irq, brd); | 2367 | free_irq(brd->irq, brd); |
| 2343 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); | 2368 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); |
| 2344 | release_region(brd->vector, 1); | 2369 | mxser_release_vector(brd); |
| 2345 | } | 2370 | } |
| 2346 | 2371 | ||
| 2347 | static int __devinit mxser_initbrd(struct mxser_board *brd, | 2372 | static int __devinit mxser_initbrd(struct mxser_board *brd, |
| @@ -2396,7 +2421,7 @@ static int __devinit mxser_initbrd(struct mxser_board *brd, | |||
| 2396 | 2421 | ||
| 2397 | static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) | 2422 | static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) |
| 2398 | { | 2423 | { |
| 2399 | int id, i, bits; | 2424 | int id, i, bits, ret; |
| 2400 | unsigned short regs[16], irq; | 2425 | unsigned short regs[16], irq; |
| 2401 | unsigned char scratch, scratch2; | 2426 | unsigned char scratch, scratch2; |
| 2402 | 2427 | ||
| @@ -2492,13 +2517,15 @@ static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) | |||
| 2492 | 8 * brd->info->nports - 1); | 2517 | 8 * brd->info->nports - 1); |
| 2493 | return -EIO; | 2518 | return -EIO; |
| 2494 | } | 2519 | } |
| 2495 | if (!request_region(brd->vector, 1, "mxser(vector)")) { | 2520 | |
| 2521 | ret = mxser_request_vector(brd); | ||
| 2522 | if (ret) { | ||
| 2496 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); | 2523 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); |
| 2497 | printk(KERN_ERR "mxser: can't request interrupt vector region: " | 2524 | printk(KERN_ERR "mxser: can't request interrupt vector region: " |
| 2498 | "0x%.8lx-0x%.8lx\n", | 2525 | "0x%.8lx-0x%.8lx\n", |
| 2499 | brd->ports[0].ioaddr, brd->ports[0].ioaddr + | 2526 | brd->ports[0].ioaddr, brd->ports[0].ioaddr + |
| 2500 | 8 * brd->info->nports - 1); | 2527 | 8 * brd->info->nports - 1); |
| 2501 | return -EIO; | 2528 | return ret; |
| 2502 | } | 2529 | } |
| 2503 | return brd->info->nports; | 2530 | return brd->info->nports; |
| 2504 | 2531 | ||
| @@ -2598,7 +2625,8 @@ static int __devinit mxser_probe(struct pci_dev *pdev, | |||
| 2598 | goto err_rel3; | 2625 | goto err_rel3; |
| 2599 | 2626 | ||
| 2600 | for (i = 0; i < brd->info->nports; i++) | 2627 | for (i = 0; i < brd->info->nports; i++) |
| 2601 | tty_register_device(mxvar_sdriver, brd->idx + i, &pdev->dev); | 2628 | tty_port_register_device(&brd->ports[i].port, mxvar_sdriver, |
| 2629 | brd->idx + i, &pdev->dev); | ||
| 2602 | 2630 | ||
| 2603 | pci_set_drvdata(pdev, brd); | 2631 | pci_set_drvdata(pdev, brd); |
| 2604 | 2632 | ||
| @@ -2695,7 +2723,8 @@ static int __init mxser_module_init(void) | |||
| 2695 | 2723 | ||
| 2696 | brd->idx = m * MXSER_PORTS_PER_BOARD; | 2724 | brd->idx = m * MXSER_PORTS_PER_BOARD; |
| 2697 | for (i = 0; i < brd->info->nports; i++) | 2725 | for (i = 0; i < brd->info->nports; i++) |
| 2698 | tty_register_device(mxvar_sdriver, brd->idx + i, NULL); | 2726 | tty_port_register_device(&brd->ports[i].port, |
| 2727 | mxvar_sdriver, brd->idx + i, NULL); | ||
| 2699 | 2728 | ||
| 2700 | m++; | 2729 | m++; |
| 2701 | } | 2730 | } |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index c43b683b6eb8..1e8e8ce55959 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
| @@ -108,7 +108,7 @@ struct gsm_mux_net { | |||
| 108 | */ | 108 | */ |
| 109 | 109 | ||
| 110 | struct gsm_msg { | 110 | struct gsm_msg { |
| 111 | struct gsm_msg *next; | 111 | struct list_head list; |
| 112 | u8 addr; /* DLCI address + flags */ | 112 | u8 addr; /* DLCI address + flags */ |
| 113 | u8 ctrl; /* Control byte + flags */ | 113 | u8 ctrl; /* Control byte + flags */ |
| 114 | unsigned int len; /* Length of data block (can be zero) */ | 114 | unsigned int len; /* Length of data block (can be zero) */ |
| @@ -245,8 +245,7 @@ struct gsm_mux { | |||
| 245 | unsigned int tx_bytes; /* TX data outstanding */ | 245 | unsigned int tx_bytes; /* TX data outstanding */ |
| 246 | #define TX_THRESH_HI 8192 | 246 | #define TX_THRESH_HI 8192 |
| 247 | #define TX_THRESH_LO 2048 | 247 | #define TX_THRESH_LO 2048 |
| 248 | struct gsm_msg *tx_head; /* Pending data packets */ | 248 | struct list_head tx_list; /* Pending data packets */ |
| 249 | struct gsm_msg *tx_tail; | ||
| 250 | 249 | ||
| 251 | /* Control messages */ | 250 | /* Control messages */ |
| 252 | struct timer_list t2_timer; /* Retransmit timer for commands */ | 251 | struct timer_list t2_timer; /* Retransmit timer for commands */ |
| @@ -489,7 +488,7 @@ static void gsm_print_packet(const char *hdr, int addr, int cr, | |||
| 489 | default: | 488 | default: |
| 490 | if (!(control & 0x01)) { | 489 | if (!(control & 0x01)) { |
| 491 | pr_cont("I N(S)%d N(R)%d", | 490 | pr_cont("I N(S)%d N(R)%d", |
| 492 | (control & 0x0E) >> 1, (control & 0xE) >> 5); | 491 | (control & 0x0E) >> 1, (control & 0xE0) >> 5); |
| 493 | } else switch (control & 0x0F) { | 492 | } else switch (control & 0x0F) { |
| 494 | case RR: | 493 | case RR: |
| 495 | pr_cont("RR(%d)", (control & 0xE0) >> 5); | 494 | pr_cont("RR(%d)", (control & 0xE0) >> 5); |
| @@ -663,7 +662,7 @@ static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len, | |||
| 663 | m->len = len; | 662 | m->len = len; |
| 664 | m->addr = addr; | 663 | m->addr = addr; |
| 665 | m->ctrl = ctrl; | 664 | m->ctrl = ctrl; |
| 666 | m->next = NULL; | 665 | INIT_LIST_HEAD(&m->list); |
| 667 | return m; | 666 | return m; |
| 668 | } | 667 | } |
| 669 | 668 | ||
| @@ -673,22 +672,21 @@ static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len, | |||
| 673 | * | 672 | * |
| 674 | * The tty device has called us to indicate that room has appeared in | 673 | * The tty device has called us to indicate that room has appeared in |
| 675 | * the transmit queue. Ram more data into the pipe if we have any | 674 | * the transmit queue. Ram more data into the pipe if we have any |
| 675 | * If we have been flow-stopped by a CMD_FCOFF, then we can only | ||
| 676 | * send messages on DLCI0 until CMD_FCON | ||
| 676 | * | 677 | * |
| 677 | * FIXME: lock against link layer control transmissions | 678 | * FIXME: lock against link layer control transmissions |
| 678 | */ | 679 | */ |
| 679 | 680 | ||
| 680 | static void gsm_data_kick(struct gsm_mux *gsm) | 681 | static void gsm_data_kick(struct gsm_mux *gsm) |
| 681 | { | 682 | { |
| 682 | struct gsm_msg *msg = gsm->tx_head; | 683 | struct gsm_msg *msg, *nmsg; |
| 683 | int len; | 684 | int len; |
| 684 | int skip_sof = 0; | 685 | int skip_sof = 0; |
| 685 | 686 | ||
| 686 | /* FIXME: We need to apply this solely to data messages */ | 687 | list_for_each_entry_safe(msg, nmsg, &gsm->tx_list, list) { |
| 687 | if (gsm->constipated) | 688 | if (gsm->constipated && msg->addr) |
| 688 | return; | 689 | continue; |
| 689 | |||
| 690 | while (gsm->tx_head != NULL) { | ||
| 691 | msg = gsm->tx_head; | ||
| 692 | if (gsm->encoding != 0) { | 690 | if (gsm->encoding != 0) { |
| 693 | gsm->txframe[0] = GSM1_SOF; | 691 | gsm->txframe[0] = GSM1_SOF; |
| 694 | len = gsm_stuff_frame(msg->data, | 692 | len = gsm_stuff_frame(msg->data, |
| @@ -711,14 +709,13 @@ static void gsm_data_kick(struct gsm_mux *gsm) | |||
| 711 | len - skip_sof) < 0) | 709 | len - skip_sof) < 0) |
| 712 | break; | 710 | break; |
| 713 | /* FIXME: Can eliminate one SOF in many more cases */ | 711 | /* FIXME: Can eliminate one SOF in many more cases */ |
| 714 | gsm->tx_head = msg->next; | ||
| 715 | if (gsm->tx_head == NULL) | ||
| 716 | gsm->tx_tail = NULL; | ||
| 717 | gsm->tx_bytes -= msg->len; | 712 | gsm->tx_bytes -= msg->len; |
| 718 | kfree(msg); | ||
| 719 | /* For a burst of frames skip the extra SOF within the | 713 | /* For a burst of frames skip the extra SOF within the |
| 720 | burst */ | 714 | burst */ |
| 721 | skip_sof = 1; | 715 | skip_sof = 1; |
| 716 | |||
| 717 | list_del(&msg->list); | ||
| 718 | kfree(msg); | ||
| 722 | } | 719 | } |
| 723 | } | 720 | } |
| 724 | 721 | ||
| @@ -768,11 +765,7 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg) | |||
| 768 | msg->data = dp; | 765 | msg->data = dp; |
| 769 | 766 | ||
| 770 | /* Add to the actual output queue */ | 767 | /* Add to the actual output queue */ |
| 771 | if (gsm->tx_tail) | 768 | list_add_tail(&msg->list, &gsm->tx_list); |
| 772 | gsm->tx_tail->next = msg; | ||
| 773 | else | ||
| 774 | gsm->tx_head = msg; | ||
| 775 | gsm->tx_tail = msg; | ||
| 776 | gsm->tx_bytes += msg->len; | 769 | gsm->tx_bytes += msg->len; |
| 777 | gsm_data_kick(gsm); | 770 | gsm_data_kick(gsm); |
| 778 | } | 771 | } |
| @@ -875,7 +868,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, | |||
| 875 | 868 | ||
| 876 | /* dlci->skb is locked by tx_lock */ | 869 | /* dlci->skb is locked by tx_lock */ |
| 877 | if (dlci->skb == NULL) { | 870 | if (dlci->skb == NULL) { |
| 878 | dlci->skb = skb_dequeue(&dlci->skb_list); | 871 | dlci->skb = skb_dequeue_tail(&dlci->skb_list); |
| 879 | if (dlci->skb == NULL) | 872 | if (dlci->skb == NULL) |
| 880 | return 0; | 873 | return 0; |
| 881 | first = 1; | 874 | first = 1; |
| @@ -886,7 +879,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, | |||
| 886 | if (len > gsm->mtu) { | 879 | if (len > gsm->mtu) { |
| 887 | if (dlci->adaption == 3) { | 880 | if (dlci->adaption == 3) { |
| 888 | /* Over long frame, bin it */ | 881 | /* Over long frame, bin it */ |
| 889 | kfree_skb(dlci->skb); | 882 | dev_kfree_skb_any(dlci->skb); |
| 890 | dlci->skb = NULL; | 883 | dlci->skb = NULL; |
| 891 | return 0; | 884 | return 0; |
| 892 | } | 885 | } |
| @@ -899,8 +892,11 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, | |||
| 899 | 892 | ||
| 900 | /* FIXME: need a timer or something to kick this so it can't | 893 | /* FIXME: need a timer or something to kick this so it can't |
| 901 | get stuck with no work outstanding and no buffer free */ | 894 | get stuck with no work outstanding and no buffer free */ |
| 902 | if (msg == NULL) | 895 | if (msg == NULL) { |
| 896 | skb_queue_tail(&dlci->skb_list, dlci->skb); | ||
| 897 | dlci->skb = NULL; | ||
| 903 | return -ENOMEM; | 898 | return -ENOMEM; |
| 899 | } | ||
| 904 | dp = msg->data; | 900 | dp = msg->data; |
| 905 | 901 | ||
| 906 | if (dlci->adaption == 4) { /* Interruptible framed (Packetised Data) */ | 902 | if (dlci->adaption == 4) { /* Interruptible framed (Packetised Data) */ |
| @@ -912,7 +908,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, | |||
| 912 | skb_pull(dlci->skb, len); | 908 | skb_pull(dlci->skb, len); |
| 913 | __gsm_data_queue(dlci, msg); | 909 | __gsm_data_queue(dlci, msg); |
| 914 | if (last) { | 910 | if (last) { |
| 915 | kfree_skb(dlci->skb); | 911 | dev_kfree_skb_any(dlci->skb); |
| 916 | dlci->skb = NULL; | 912 | dlci->skb = NULL; |
| 917 | } | 913 | } |
| 918 | return size; | 914 | return size; |
| @@ -971,16 +967,22 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm) | |||
| 971 | static void gsm_dlci_data_kick(struct gsm_dlci *dlci) | 967 | static void gsm_dlci_data_kick(struct gsm_dlci *dlci) |
| 972 | { | 968 | { |
| 973 | unsigned long flags; | 969 | unsigned long flags; |
| 970 | int sweep; | ||
| 971 | |||
| 972 | if (dlci->constipated) | ||
| 973 | return; | ||
| 974 | 974 | ||
| 975 | spin_lock_irqsave(&dlci->gsm->tx_lock, flags); | 975 | spin_lock_irqsave(&dlci->gsm->tx_lock, flags); |
| 976 | /* If we have nothing running then we need to fire up */ | 976 | /* If we have nothing running then we need to fire up */ |
| 977 | sweep = (dlci->gsm->tx_bytes < TX_THRESH_LO); | ||
| 977 | if (dlci->gsm->tx_bytes == 0) { | 978 | if (dlci->gsm->tx_bytes == 0) { |
| 978 | if (dlci->net) | 979 | if (dlci->net) |
| 979 | gsm_dlci_data_output_framed(dlci->gsm, dlci); | 980 | gsm_dlci_data_output_framed(dlci->gsm, dlci); |
| 980 | else | 981 | else |
| 981 | gsm_dlci_data_output(dlci->gsm, dlci); | 982 | gsm_dlci_data_output(dlci->gsm, dlci); |
| 982 | } else if (dlci->gsm->tx_bytes < TX_THRESH_LO) | 983 | } |
| 983 | gsm_dlci_data_sweep(dlci->gsm); | 984 | if (sweep) |
| 985 | gsm_dlci_data_sweep(dlci->gsm); | ||
| 984 | spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags); | 986 | spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags); |
| 985 | } | 987 | } |
| 986 | 988 | ||
| @@ -1027,6 +1029,7 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, | |||
| 1027 | { | 1029 | { |
| 1028 | int mlines = 0; | 1030 | int mlines = 0; |
| 1029 | u8 brk = 0; | 1031 | u8 brk = 0; |
| 1032 | int fc; | ||
| 1030 | 1033 | ||
| 1031 | /* The modem status command can either contain one octet (v.24 signals) | 1034 | /* The modem status command can either contain one octet (v.24 signals) |
| 1032 | or two octets (v.24 signals + break signals). The length field will | 1035 | or two octets (v.24 signals + break signals). The length field will |
| @@ -1038,19 +1041,21 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, | |||
| 1038 | else { | 1041 | else { |
| 1039 | brk = modem & 0x7f; | 1042 | brk = modem & 0x7f; |
| 1040 | modem = (modem >> 7) & 0x7f; | 1043 | modem = (modem >> 7) & 0x7f; |
| 1041 | }; | 1044 | } |
| 1042 | 1045 | ||
| 1043 | /* Flow control/ready to communicate */ | 1046 | /* Flow control/ready to communicate */ |
| 1044 | if (modem & MDM_FC) { | 1047 | fc = (modem & MDM_FC) || !(modem & MDM_RTR); |
| 1048 | if (fc && !dlci->constipated) { | ||
| 1045 | /* Need to throttle our output on this device */ | 1049 | /* Need to throttle our output on this device */ |
| 1046 | dlci->constipated = 1; | 1050 | dlci->constipated = 1; |
| 1047 | } | 1051 | } else if (!fc && dlci->constipated) { |
| 1048 | if (modem & MDM_RTC) { | ||
| 1049 | mlines |= TIOCM_DSR | TIOCM_DTR; | ||
| 1050 | dlci->constipated = 0; | 1052 | dlci->constipated = 0; |
| 1051 | gsm_dlci_data_kick(dlci); | 1053 | gsm_dlci_data_kick(dlci); |
| 1052 | } | 1054 | } |
| 1055 | |||
| 1053 | /* Map modem bits */ | 1056 | /* Map modem bits */ |
| 1057 | if (modem & MDM_RTC) | ||
| 1058 | mlines |= TIOCM_DSR | TIOCM_DTR; | ||
| 1054 | if (modem & MDM_RTR) | 1059 | if (modem & MDM_RTR) |
| 1055 | mlines |= TIOCM_RTS | TIOCM_CTS; | 1060 | mlines |= TIOCM_RTS | TIOCM_CTS; |
| 1056 | if (modem & MDM_IC) | 1061 | if (modem & MDM_IC) |
| @@ -1061,7 +1066,7 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, | |||
| 1061 | /* Carrier drop -> hangup */ | 1066 | /* Carrier drop -> hangup */ |
| 1062 | if (tty) { | 1067 | if (tty) { |
| 1063 | if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD)) | 1068 | if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD)) |
| 1064 | if (!(tty->termios->c_cflag & CLOCAL)) | 1069 | if (!(tty->termios.c_cflag & CLOCAL)) |
| 1065 | tty_hangup(tty); | 1070 | tty_hangup(tty); |
| 1066 | if (brk & 0x01) | 1071 | if (brk & 0x01) |
| 1067 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 1072 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
| @@ -1190,6 +1195,8 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, | |||
| 1190 | u8 *data, int clen) | 1195 | u8 *data, int clen) |
| 1191 | { | 1196 | { |
| 1192 | u8 buf[1]; | 1197 | u8 buf[1]; |
| 1198 | unsigned long flags; | ||
| 1199 | |||
| 1193 | switch (command) { | 1200 | switch (command) { |
| 1194 | case CMD_CLD: { | 1201 | case CMD_CLD: { |
| 1195 | struct gsm_dlci *dlci = gsm->dlci[0]; | 1202 | struct gsm_dlci *dlci = gsm->dlci[0]; |
| @@ -1206,16 +1213,18 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, | |||
| 1206 | gsm_control_reply(gsm, CMD_TEST, data, clen); | 1213 | gsm_control_reply(gsm, CMD_TEST, data, clen); |
| 1207 | break; | 1214 | break; |
| 1208 | case CMD_FCON: | 1215 | case CMD_FCON: |
| 1209 | /* Modem wants us to STFU */ | ||
| 1210 | gsm->constipated = 1; | ||
| 1211 | gsm_control_reply(gsm, CMD_FCON, NULL, 0); | ||
| 1212 | break; | ||
| 1213 | case CMD_FCOFF: | ||
| 1214 | /* Modem can accept data again */ | 1216 | /* Modem can accept data again */ |
| 1215 | gsm->constipated = 0; | 1217 | gsm->constipated = 0; |
| 1216 | gsm_control_reply(gsm, CMD_FCOFF, NULL, 0); | 1218 | gsm_control_reply(gsm, CMD_FCON, NULL, 0); |
| 1217 | /* Kick the link in case it is idling */ | 1219 | /* Kick the link in case it is idling */ |
| 1220 | spin_lock_irqsave(&gsm->tx_lock, flags); | ||
| 1218 | gsm_data_kick(gsm); | 1221 | gsm_data_kick(gsm); |
| 1222 | spin_unlock_irqrestore(&gsm->tx_lock, flags); | ||
| 1223 | break; | ||
| 1224 | case CMD_FCOFF: | ||
| 1225 | /* Modem wants us to STFU */ | ||
| 1226 | gsm->constipated = 1; | ||
| 1227 | gsm_control_reply(gsm, CMD_FCOFF, NULL, 0); | ||
| 1219 | break; | 1228 | break; |
| 1220 | case CMD_MSC: | 1229 | case CMD_MSC: |
| 1221 | /* Out of band modem line change indicator for a DLCI */ | 1230 | /* Out of band modem line change indicator for a DLCI */ |
| @@ -1668,7 +1677,7 @@ static void gsm_dlci_free(struct kref *ref) | |||
| 1668 | dlci->gsm->dlci[dlci->addr] = NULL; | 1677 | dlci->gsm->dlci[dlci->addr] = NULL; |
| 1669 | kfifo_free(dlci->fifo); | 1678 | kfifo_free(dlci->fifo); |
| 1670 | while ((dlci->skb = skb_dequeue(&dlci->skb_list))) | 1679 | while ((dlci->skb = skb_dequeue(&dlci->skb_list))) |
| 1671 | kfree_skb(dlci->skb); | 1680 | dev_kfree_skb(dlci->skb); |
| 1672 | kfree(dlci); | 1681 | kfree(dlci); |
| 1673 | } | 1682 | } |
| 1674 | 1683 | ||
| @@ -2007,7 +2016,7 @@ void gsm_cleanup_mux(struct gsm_mux *gsm) | |||
| 2007 | { | 2016 | { |
| 2008 | int i; | 2017 | int i; |
| 2009 | struct gsm_dlci *dlci = gsm->dlci[0]; | 2018 | struct gsm_dlci *dlci = gsm->dlci[0]; |
| 2010 | struct gsm_msg *txq; | 2019 | struct gsm_msg *txq, *ntxq; |
| 2011 | struct gsm_control *gc; | 2020 | struct gsm_control *gc; |
| 2012 | 2021 | ||
| 2013 | gsm->dead = 1; | 2022 | gsm->dead = 1; |
| @@ -2042,11 +2051,9 @@ void gsm_cleanup_mux(struct gsm_mux *gsm) | |||
| 2042 | if (gsm->dlci[i]) | 2051 | if (gsm->dlci[i]) |
| 2043 | gsm_dlci_release(gsm->dlci[i]); | 2052 | gsm_dlci_release(gsm->dlci[i]); |
| 2044 | /* Now wipe the queues */ | 2053 | /* Now wipe the queues */ |
| 2045 | for (txq = gsm->tx_head; txq != NULL; txq = gsm->tx_head) { | 2054 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list) |
| 2046 | gsm->tx_head = txq->next; | ||
| 2047 | kfree(txq); | 2055 | kfree(txq); |
| 2048 | } | 2056 | INIT_LIST_HEAD(&gsm->tx_list); |
| 2049 | gsm->tx_tail = NULL; | ||
| 2050 | } | 2057 | } |
| 2051 | EXPORT_SYMBOL_GPL(gsm_cleanup_mux); | 2058 | EXPORT_SYMBOL_GPL(gsm_cleanup_mux); |
| 2052 | 2059 | ||
| @@ -2157,6 +2164,7 @@ struct gsm_mux *gsm_alloc_mux(void) | |||
| 2157 | } | 2164 | } |
| 2158 | spin_lock_init(&gsm->lock); | 2165 | spin_lock_init(&gsm->lock); |
| 2159 | kref_init(&gsm->ref); | 2166 | kref_init(&gsm->ref); |
| 2167 | INIT_LIST_HEAD(&gsm->tx_list); | ||
| 2160 | 2168 | ||
| 2161 | gsm->t1 = T1; | 2169 | gsm->t1 = T1; |
| 2162 | gsm->t2 = T2; | 2170 | gsm->t2 = T2; |
| @@ -2273,7 +2281,7 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
| 2273 | gsm->error(gsm, *dp, flags); | 2281 | gsm->error(gsm, *dp, flags); |
| 2274 | break; | 2282 | break; |
| 2275 | default: | 2283 | default: |
| 2276 | WARN_ONCE("%s: unknown flag %d\n", | 2284 | WARN_ONCE(1, "%s: unknown flag %d\n", |
| 2277 | tty_name(tty, buf), flags); | 2285 | tty_name(tty, buf), flags); |
| 2278 | break; | 2286 | break; |
| 2279 | } | 2287 | } |
| @@ -2377,12 +2385,12 @@ static void gsmld_write_wakeup(struct tty_struct *tty) | |||
| 2377 | 2385 | ||
| 2378 | /* Queue poll */ | 2386 | /* Queue poll */ |
| 2379 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 2387 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
| 2388 | spin_lock_irqsave(&gsm->tx_lock, flags); | ||
| 2380 | gsm_data_kick(gsm); | 2389 | gsm_data_kick(gsm); |
| 2381 | if (gsm->tx_bytes < TX_THRESH_LO) { | 2390 | if (gsm->tx_bytes < TX_THRESH_LO) { |
| 2382 | spin_lock_irqsave(&gsm->tx_lock, flags); | ||
| 2383 | gsm_dlci_data_sweep(gsm); | 2391 | gsm_dlci_data_sweep(gsm); |
| 2384 | spin_unlock_irqrestore(&gsm->tx_lock, flags); | ||
| 2385 | } | 2392 | } |
| 2393 | spin_unlock_irqrestore(&gsm->tx_lock, flags); | ||
| 2386 | } | 2394 | } |
| 2387 | 2395 | ||
| 2388 | /** | 2396 | /** |
| @@ -2868,14 +2876,14 @@ static const struct tty_port_operations gsm_port_ops = { | |||
| 2868 | .dtr_rts = gsm_dtr_rts, | 2876 | .dtr_rts = gsm_dtr_rts, |
| 2869 | }; | 2877 | }; |
| 2870 | 2878 | ||
| 2871 | 2879 | static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty) | |
| 2872 | static int gsmtty_open(struct tty_struct *tty, struct file *filp) | ||
| 2873 | { | 2880 | { |
| 2874 | struct gsm_mux *gsm; | 2881 | struct gsm_mux *gsm; |
| 2875 | struct gsm_dlci *dlci; | 2882 | struct gsm_dlci *dlci; |
| 2876 | struct tty_port *port; | ||
| 2877 | unsigned int line = tty->index; | 2883 | unsigned int line = tty->index; |
| 2878 | unsigned int mux = line >> 6; | 2884 | unsigned int mux = line >> 6; |
| 2885 | bool alloc = false; | ||
| 2886 | int ret; | ||
| 2879 | 2887 | ||
| 2880 | line = line & 0x3F; | 2888 | line = line & 0x3F; |
| 2881 | 2889 | ||
| @@ -2889,14 +2897,35 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) | |||
| 2889 | gsm = gsm_mux[mux]; | 2897 | gsm = gsm_mux[mux]; |
| 2890 | if (gsm->dead) | 2898 | if (gsm->dead) |
| 2891 | return -EL2HLT; | 2899 | return -EL2HLT; |
| 2900 | /* If DLCI 0 is not yet fully open return an error. This is ok from a locking | ||
| 2901 | perspective as we don't have to worry about this if DLCI0 is lost */ | ||
| 2902 | if (gsm->dlci[0] && gsm->dlci[0]->state != DLCI_OPEN) | ||
| 2903 | return -EL2NSYNC; | ||
| 2892 | dlci = gsm->dlci[line]; | 2904 | dlci = gsm->dlci[line]; |
| 2893 | if (dlci == NULL) | 2905 | if (dlci == NULL) { |
| 2906 | alloc = true; | ||
| 2894 | dlci = gsm_dlci_alloc(gsm, line); | 2907 | dlci = gsm_dlci_alloc(gsm, line); |
| 2908 | } | ||
| 2895 | if (dlci == NULL) | 2909 | if (dlci == NULL) |
| 2896 | return -ENOMEM; | 2910 | return -ENOMEM; |
| 2897 | port = &dlci->port; | 2911 | ret = tty_port_install(&dlci->port, driver, tty); |
| 2898 | port->count++; | 2912 | if (ret) { |
| 2913 | if (alloc) | ||
| 2914 | dlci_put(dlci); | ||
| 2915 | return ret; | ||
| 2916 | } | ||
| 2917 | |||
| 2899 | tty->driver_data = dlci; | 2918 | tty->driver_data = dlci; |
| 2919 | |||
| 2920 | return 0; | ||
| 2921 | } | ||
| 2922 | |||
| 2923 | static int gsmtty_open(struct tty_struct *tty, struct file *filp) | ||
| 2924 | { | ||
| 2925 | struct gsm_dlci *dlci = tty->driver_data; | ||
| 2926 | struct tty_port *port = &dlci->port; | ||
| 2927 | |||
| 2928 | port->count++; | ||
| 2900 | dlci_get(dlci); | 2929 | dlci_get(dlci); |
| 2901 | dlci_get(dlci->gsm->dlci[0]); | 2930 | dlci_get(dlci->gsm->dlci[0]); |
| 2902 | mux_get(dlci->gsm); | 2931 | mux_get(dlci->gsm); |
| @@ -3043,13 +3072,13 @@ static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
| 3043 | the RPN control message. This however rapidly gets nasty as we | 3072 | the RPN control message. This however rapidly gets nasty as we |
| 3044 | then have to remap modem signals each way according to whether | 3073 | then have to remap modem signals each way according to whether |
| 3045 | our virtual cable is null modem etc .. */ | 3074 | our virtual cable is null modem etc .. */ |
| 3046 | tty_termios_copy_hw(tty->termios, old); | 3075 | tty_termios_copy_hw(&tty->termios, old); |
| 3047 | } | 3076 | } |
| 3048 | 3077 | ||
| 3049 | static void gsmtty_throttle(struct tty_struct *tty) | 3078 | static void gsmtty_throttle(struct tty_struct *tty) |
| 3050 | { | 3079 | { |
| 3051 | struct gsm_dlci *dlci = tty->driver_data; | 3080 | struct gsm_dlci *dlci = tty->driver_data; |
| 3052 | if (tty->termios->c_cflag & CRTSCTS) | 3081 | if (tty->termios.c_cflag & CRTSCTS) |
| 3053 | dlci->modem_tx &= ~TIOCM_DTR; | 3082 | dlci->modem_tx &= ~TIOCM_DTR; |
| 3054 | dlci->throttled = 1; | 3083 | dlci->throttled = 1; |
| 3055 | /* Send an MSC with DTR cleared */ | 3084 | /* Send an MSC with DTR cleared */ |
| @@ -3059,7 +3088,7 @@ static void gsmtty_throttle(struct tty_struct *tty) | |||
| 3059 | static void gsmtty_unthrottle(struct tty_struct *tty) | 3088 | static void gsmtty_unthrottle(struct tty_struct *tty) |
| 3060 | { | 3089 | { |
| 3061 | struct gsm_dlci *dlci = tty->driver_data; | 3090 | struct gsm_dlci *dlci = tty->driver_data; |
| 3062 | if (tty->termios->c_cflag & CRTSCTS) | 3091 | if (tty->termios.c_cflag & CRTSCTS) |
| 3063 | dlci->modem_tx |= TIOCM_DTR; | 3092 | dlci->modem_tx |= TIOCM_DTR; |
| 3064 | dlci->throttled = 0; | 3093 | dlci->throttled = 0; |
| 3065 | /* Send an MSC with DTR set */ | 3094 | /* Send an MSC with DTR set */ |
| @@ -3085,6 +3114,7 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state) | |||
| 3085 | 3114 | ||
| 3086 | /* Virtual ttys for the demux */ | 3115 | /* Virtual ttys for the demux */ |
| 3087 | static const struct tty_operations gsmtty_ops = { | 3116 | static const struct tty_operations gsmtty_ops = { |
| 3117 | .install = gsmtty_install, | ||
| 3088 | .open = gsmtty_open, | 3118 | .open = gsmtty_open, |
| 3089 | .close = gsmtty_close, | 3119 | .close = gsmtty_close, |
| 3090 | .write = gsmtty_write, | 3120 | .write = gsmtty_write, |
diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c index 5c6c31459a2f..1e6405070ce6 100644 --- a/drivers/tty/n_r3964.c +++ b/drivers/tty/n_r3964.c | |||
| @@ -1065,7 +1065,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
| 1065 | 1065 | ||
| 1066 | TRACE_L("read()"); | 1066 | TRACE_L("read()"); |
| 1067 | 1067 | ||
| 1068 | tty_lock(); | 1068 | tty_lock(tty); |
| 1069 | 1069 | ||
| 1070 | pClient = findClient(pInfo, task_pid(current)); | 1070 | pClient = findClient(pInfo, task_pid(current)); |
| 1071 | if (pClient) { | 1071 | if (pClient) { |
| @@ -1077,7 +1077,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
| 1077 | goto unlock; | 1077 | goto unlock; |
| 1078 | } | 1078 | } |
| 1079 | /* block until there is a message: */ | 1079 | /* block until there is a message: */ |
| 1080 | wait_event_interruptible_tty(pInfo->read_wait, | 1080 | wait_event_interruptible_tty(tty, pInfo->read_wait, |
| 1081 | (pMsg = remove_msg(pInfo, pClient))); | 1081 | (pMsg = remove_msg(pInfo, pClient))); |
| 1082 | } | 1082 | } |
| 1083 | 1083 | ||
| @@ -1107,7 +1107,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
| 1107 | } | 1107 | } |
| 1108 | ret = -EPERM; | 1108 | ret = -EPERM; |
| 1109 | unlock: | 1109 | unlock: |
| 1110 | tty_unlock(); | 1110 | tty_unlock(tty); |
| 1111 | return ret; | 1111 | return ret; |
| 1112 | } | 1112 | } |
| 1113 | 1113 | ||
| @@ -1156,7 +1156,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, | |||
| 1156 | pHeader->locks = 0; | 1156 | pHeader->locks = 0; |
| 1157 | pHeader->owner = NULL; | 1157 | pHeader->owner = NULL; |
| 1158 | 1158 | ||
| 1159 | tty_lock(); | 1159 | tty_lock(tty); |
| 1160 | 1160 | ||
| 1161 | pClient = findClient(pInfo, task_pid(current)); | 1161 | pClient = findClient(pInfo, task_pid(current)); |
| 1162 | if (pClient) { | 1162 | if (pClient) { |
| @@ -1175,7 +1175,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, | |||
| 1175 | add_tx_queue(pInfo, pHeader); | 1175 | add_tx_queue(pInfo, pHeader); |
| 1176 | trigger_transmit(pInfo); | 1176 | trigger_transmit(pInfo); |
| 1177 | 1177 | ||
| 1178 | tty_unlock(); | 1178 | tty_unlock(tty); |
| 1179 | 1179 | ||
| 1180 | return 0; | 1180 | return 0; |
| 1181 | } | 1181 | } |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index ee1c268f5f9d..8c0b7b42319c 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
| @@ -92,10 +92,18 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | |||
| 92 | 92 | ||
| 93 | static void n_tty_set_room(struct tty_struct *tty) | 93 | static void n_tty_set_room(struct tty_struct *tty) |
| 94 | { | 94 | { |
| 95 | /* tty->read_cnt is not read locked ? */ | 95 | int left; |
| 96 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | ||
| 97 | int old_left; | 96 | int old_left; |
| 98 | 97 | ||
| 98 | /* tty->read_cnt is not read locked ? */ | ||
| 99 | if (I_PARMRK(tty)) { | ||
| 100 | /* Multiply read_cnt by 3, since each byte might take up to | ||
| 101 | * three times as many spaces when PARMRK is set (depending on | ||
| 102 | * its flags, e.g. parity error). */ | ||
| 103 | left = N_TTY_BUF_SIZE - tty->read_cnt * 3 - 1; | ||
| 104 | } else | ||
| 105 | left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | ||
| 106 | |||
| 99 | /* | 107 | /* |
| 100 | * If we are doing input canonicalization, and there are no | 108 | * If we are doing input canonicalization, and there are no |
| 101 | * pending newlines, let characters through without limit, so | 109 | * pending newlines, let characters through without limit, so |
| @@ -1432,6 +1440,12 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
| 1432 | */ | 1440 | */ |
| 1433 | if (tty->receive_room < TTY_THRESHOLD_THROTTLE) | 1441 | if (tty->receive_room < TTY_THRESHOLD_THROTTLE) |
| 1434 | tty_throttle(tty); | 1442 | tty_throttle(tty); |
| 1443 | |||
| 1444 | /* FIXME: there is a tiny race here if the receive room check runs | ||
| 1445 | before the other work executes and empties the buffer (upping | ||
| 1446 | the receiving room and unthrottling. We then throttle and get | ||
| 1447 | stuck. This has been observed and traced down by Vincent Pillet/ | ||
| 1448 | We need to address this when we sort out out the rx path locking */ | ||
| 1435 | } | 1449 | } |
| 1436 | 1450 | ||
| 1437 | int is_ignored(int sig) | 1451 | int is_ignored(int sig) |
| @@ -1460,7 +1474,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
| 1460 | BUG_ON(!tty); | 1474 | BUG_ON(!tty); |
| 1461 | 1475 | ||
| 1462 | if (old) | 1476 | if (old) |
| 1463 | canon_change = (old->c_lflag ^ tty->termios->c_lflag) & ICANON; | 1477 | canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON; |
| 1464 | if (canon_change) { | 1478 | if (canon_change) { |
| 1465 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | 1479 | memset(&tty->read_flags, 0, sizeof tty->read_flags); |
| 1466 | tty->canon_head = tty->read_tail; | 1480 | tty->canon_head = tty->read_tail; |
| @@ -1728,7 +1742,8 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
| 1728 | 1742 | ||
| 1729 | do_it_again: | 1743 | do_it_again: |
| 1730 | 1744 | ||
| 1731 | BUG_ON(!tty->read_buf); | 1745 | if (WARN_ON(!tty->read_buf)) |
| 1746 | return -EAGAIN; | ||
| 1732 | 1747 | ||
| 1733 | c = job_control(tty, file); | 1748 | c = job_control(tty, file); |
| 1734 | if (c < 0) | 1749 | if (c < 0) |
| @@ -1832,13 +1847,13 @@ do_it_again: | |||
| 1832 | 1847 | ||
| 1833 | if (tty->icanon && !L_EXTPROC(tty)) { | 1848 | if (tty->icanon && !L_EXTPROC(tty)) { |
| 1834 | /* N.B. avoid overrun if nr == 0 */ | 1849 | /* N.B. avoid overrun if nr == 0 */ |
| 1850 | spin_lock_irqsave(&tty->read_lock, flags); | ||
| 1835 | while (nr && tty->read_cnt) { | 1851 | while (nr && tty->read_cnt) { |
| 1836 | int eol; | 1852 | int eol; |
| 1837 | 1853 | ||
| 1838 | eol = test_and_clear_bit(tty->read_tail, | 1854 | eol = test_and_clear_bit(tty->read_tail, |
| 1839 | tty->read_flags); | 1855 | tty->read_flags); |
| 1840 | c = tty->read_buf[tty->read_tail]; | 1856 | c = tty->read_buf[tty->read_tail]; |
| 1841 | spin_lock_irqsave(&tty->read_lock, flags); | ||
| 1842 | tty->read_tail = ((tty->read_tail+1) & | 1857 | tty->read_tail = ((tty->read_tail+1) & |
| 1843 | (N_TTY_BUF_SIZE-1)); | 1858 | (N_TTY_BUF_SIZE-1)); |
| 1844 | tty->read_cnt--; | 1859 | tty->read_cnt--; |
| @@ -1856,15 +1871,19 @@ do_it_again: | |||
| 1856 | if (tty_put_user(tty, c, b++)) { | 1871 | if (tty_put_user(tty, c, b++)) { |
| 1857 | retval = -EFAULT; | 1872 | retval = -EFAULT; |
| 1858 | b--; | 1873 | b--; |
| 1874 | spin_lock_irqsave(&tty->read_lock, flags); | ||
| 1859 | break; | 1875 | break; |
| 1860 | } | 1876 | } |
| 1861 | nr--; | 1877 | nr--; |
| 1862 | } | 1878 | } |
| 1863 | if (eol) { | 1879 | if (eol) { |
| 1864 | tty_audit_push(tty); | 1880 | tty_audit_push(tty); |
| 1881 | spin_lock_irqsave(&tty->read_lock, flags); | ||
| 1865 | break; | 1882 | break; |
| 1866 | } | 1883 | } |
| 1884 | spin_lock_irqsave(&tty->read_lock, flags); | ||
| 1867 | } | 1885 | } |
| 1886 | spin_unlock_irqrestore(&tty->read_lock, flags); | ||
| 1868 | if (retval) | 1887 | if (retval) |
| 1869 | break; | 1888 | break; |
| 1870 | } else { | 1889 | } else { |
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index e7592f9037da..b917c9424954 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c | |||
| @@ -1473,8 +1473,8 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
| 1473 | port->dc = dc; | 1473 | port->dc = dc; |
| 1474 | tty_port_init(&port->port); | 1474 | tty_port_init(&port->port); |
| 1475 | port->port.ops = &noz_tty_port_ops; | 1475 | port->port.ops = &noz_tty_port_ops; |
| 1476 | tty_dev = tty_register_device(ntty_driver, dc->index_start + i, | 1476 | tty_dev = tty_port_register_device(&port->port, ntty_driver, |
| 1477 | &pdev->dev); | 1477 | dc->index_start + i, &pdev->dev); |
| 1478 | 1478 | ||
| 1479 | if (IS_ERR(tty_dev)) { | 1479 | if (IS_ERR(tty_dev)) { |
| 1480 | ret = PTR_ERR(tty_dev); | 1480 | ret = PTR_ERR(tty_dev); |
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 5505ffc91da4..a82b39939a9c 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
| @@ -47,6 +47,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
| 47 | wake_up_interruptible(&tty->read_wait); | 47 | wake_up_interruptible(&tty->read_wait); |
| 48 | wake_up_interruptible(&tty->write_wait); | 48 | wake_up_interruptible(&tty->write_wait); |
| 49 | tty->packet = 0; | 49 | tty->packet = 0; |
| 50 | /* Review - krefs on tty_link ?? */ | ||
| 50 | if (!tty->link) | 51 | if (!tty->link) |
| 51 | return; | 52 | return; |
| 52 | tty->link->packet = 0; | 53 | tty->link->packet = 0; |
| @@ -62,9 +63,9 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
| 62 | mutex_unlock(&devpts_mutex); | 63 | mutex_unlock(&devpts_mutex); |
| 63 | } | 64 | } |
| 64 | #endif | 65 | #endif |
| 65 | tty_unlock(); | 66 | tty_unlock(tty); |
| 66 | tty_vhangup(tty->link); | 67 | tty_vhangup(tty->link); |
| 67 | tty_lock(); | 68 | tty_lock(tty); |
| 68 | } | 69 | } |
| 69 | } | 70 | } |
| 70 | 71 | ||
| @@ -231,8 +232,8 @@ out: | |||
| 231 | static void pty_set_termios(struct tty_struct *tty, | 232 | static void pty_set_termios(struct tty_struct *tty, |
| 232 | struct ktermios *old_termios) | 233 | struct ktermios *old_termios) |
| 233 | { | 234 | { |
| 234 | tty->termios->c_cflag &= ~(CSIZE | PARENB); | 235 | tty->termios.c_cflag &= ~(CSIZE | PARENB); |
| 235 | tty->termios->c_cflag |= (CS8 | CREAD); | 236 | tty->termios.c_cflag |= (CS8 | CREAD); |
| 236 | } | 237 | } |
| 237 | 238 | ||
| 238 | /** | 239 | /** |
| @@ -282,60 +283,110 @@ done: | |||
| 282 | return 0; | 283 | return 0; |
| 283 | } | 284 | } |
| 284 | 285 | ||
| 285 | /* Traditional BSD devices */ | 286 | /** |
| 286 | #ifdef CONFIG_LEGACY_PTYS | 287 | * pty_common_install - set up the pty pair |
| 287 | 288 | * @driver: the pty driver | |
| 288 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | 289 | * @tty: the tty being instantiated |
| 290 | * @bool: legacy, true if this is BSD style | ||
| 291 | * | ||
| 292 | * Perform the initial set up for the tty/pty pair. Called from the | ||
| 293 | * tty layer when the port is first opened. | ||
| 294 | * | ||
| 295 | * Locking: the caller must hold the tty_mutex | ||
| 296 | */ | ||
| 297 | static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, | ||
| 298 | bool legacy) | ||
| 289 | { | 299 | { |
| 290 | struct tty_struct *o_tty; | 300 | struct tty_struct *o_tty; |
| 301 | struct tty_port *ports[2]; | ||
| 291 | int idx = tty->index; | 302 | int idx = tty->index; |
| 292 | int retval; | 303 | int retval = -ENOMEM; |
| 293 | 304 | ||
| 294 | o_tty = alloc_tty_struct(); | 305 | o_tty = alloc_tty_struct(); |
| 295 | if (!o_tty) | 306 | if (!o_tty) |
| 296 | return -ENOMEM; | 307 | goto err; |
| 308 | ports[0] = kmalloc(sizeof **ports, GFP_KERNEL); | ||
| 309 | ports[1] = kmalloc(sizeof **ports, GFP_KERNEL); | ||
| 310 | if (!ports[0] || !ports[1]) | ||
| 311 | goto err_free_tty; | ||
| 297 | if (!try_module_get(driver->other->owner)) { | 312 | if (!try_module_get(driver->other->owner)) { |
| 298 | /* This cannot in fact currently happen */ | 313 | /* This cannot in fact currently happen */ |
| 299 | retval = -ENOMEM; | ||
| 300 | goto err_free_tty; | 314 | goto err_free_tty; |
| 301 | } | 315 | } |
| 302 | initialize_tty_struct(o_tty, driver->other, idx); | 316 | initialize_tty_struct(o_tty, driver->other, idx); |
| 303 | 317 | ||
| 304 | /* We always use new tty termios data so we can do this | 318 | if (legacy) { |
| 305 | the easy way .. */ | 319 | /* We always use new tty termios data so we can do this |
| 306 | retval = tty_init_termios(tty); | 320 | the easy way .. */ |
| 307 | if (retval) | 321 | retval = tty_init_termios(tty); |
| 308 | goto err_deinit_tty; | 322 | if (retval) |
| 309 | 323 | goto err_deinit_tty; | |
| 310 | retval = tty_init_termios(o_tty); | 324 | |
| 311 | if (retval) | 325 | retval = tty_init_termios(o_tty); |
| 312 | goto err_free_termios; | 326 | if (retval) |
| 327 | goto err_free_termios; | ||
| 328 | |||
| 329 | driver->other->ttys[idx] = o_tty; | ||
| 330 | driver->ttys[idx] = tty; | ||
| 331 | } else { | ||
| 332 | memset(&tty->termios_locked, 0, sizeof(tty->termios_locked)); | ||
| 333 | tty->termios = driver->init_termios; | ||
| 334 | memset(&o_tty->termios_locked, 0, sizeof(tty->termios_locked)); | ||
| 335 | o_tty->termios = driver->other->init_termios; | ||
| 336 | } | ||
| 313 | 337 | ||
| 314 | /* | 338 | /* |
| 315 | * Everything allocated ... set up the o_tty structure. | 339 | * Everything allocated ... set up the o_tty structure. |
| 316 | */ | 340 | */ |
| 317 | driver->other->ttys[idx] = o_tty; | ||
| 318 | tty_driver_kref_get(driver->other); | 341 | tty_driver_kref_get(driver->other); |
| 319 | if (driver->subtype == PTY_TYPE_MASTER) | 342 | if (driver->subtype == PTY_TYPE_MASTER) |
| 320 | o_tty->count++; | 343 | o_tty->count++; |
| 321 | /* Establish the links in both directions */ | 344 | /* Establish the links in both directions */ |
| 322 | tty->link = o_tty; | 345 | tty->link = o_tty; |
| 323 | o_tty->link = tty; | 346 | o_tty->link = tty; |
| 347 | tty_port_init(ports[0]); | ||
| 348 | tty_port_init(ports[1]); | ||
| 349 | o_tty->port = ports[0]; | ||
| 350 | tty->port = ports[1]; | ||
| 324 | 351 | ||
| 325 | tty_driver_kref_get(driver); | 352 | tty_driver_kref_get(driver); |
| 326 | tty->count++; | 353 | tty->count++; |
| 327 | driver->ttys[idx] = tty; | ||
| 328 | return 0; | 354 | return 0; |
| 329 | err_free_termios: | 355 | err_free_termios: |
| 330 | tty_free_termios(tty); | 356 | if (legacy) |
| 357 | tty_free_termios(tty); | ||
| 331 | err_deinit_tty: | 358 | err_deinit_tty: |
| 332 | deinitialize_tty_struct(o_tty); | 359 | deinitialize_tty_struct(o_tty); |
| 333 | module_put(o_tty->driver->owner); | 360 | module_put(o_tty->driver->owner); |
| 334 | err_free_tty: | 361 | err_free_tty: |
| 362 | kfree(ports[0]); | ||
| 363 | kfree(ports[1]); | ||
| 335 | free_tty_struct(o_tty); | 364 | free_tty_struct(o_tty); |
| 365 | err: | ||
| 336 | return retval; | 366 | return retval; |
| 337 | } | 367 | } |
| 338 | 368 | ||
| 369 | static void pty_cleanup(struct tty_struct *tty) | ||
| 370 | { | ||
| 371 | kfree(tty->port); | ||
| 372 | } | ||
| 373 | |||
| 374 | /* Traditional BSD devices */ | ||
| 375 | #ifdef CONFIG_LEGACY_PTYS | ||
| 376 | |||
| 377 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | ||
| 378 | { | ||
| 379 | return pty_common_install(driver, tty, true); | ||
| 380 | } | ||
| 381 | |||
| 382 | static void pty_remove(struct tty_driver *driver, struct tty_struct *tty) | ||
| 383 | { | ||
| 384 | struct tty_struct *pair = tty->link; | ||
| 385 | driver->ttys[tty->index] = NULL; | ||
| 386 | if (pair) | ||
| 387 | pair->driver->ttys[pair->index] = NULL; | ||
| 388 | } | ||
| 389 | |||
| 339 | static int pty_bsd_ioctl(struct tty_struct *tty, | 390 | static int pty_bsd_ioctl(struct tty_struct *tty, |
| 340 | unsigned int cmd, unsigned long arg) | 391 | unsigned int cmd, unsigned long arg) |
| 341 | { | 392 | { |
| @@ -366,7 +417,9 @@ static const struct tty_operations master_pty_ops_bsd = { | |||
| 366 | .unthrottle = pty_unthrottle, | 417 | .unthrottle = pty_unthrottle, |
| 367 | .set_termios = pty_set_termios, | 418 | .set_termios = pty_set_termios, |
| 368 | .ioctl = pty_bsd_ioctl, | 419 | .ioctl = pty_bsd_ioctl, |
| 369 | .resize = pty_resize | 420 | .cleanup = pty_cleanup, |
| 421 | .resize = pty_resize, | ||
| 422 | .remove = pty_remove | ||
| 370 | }; | 423 | }; |
| 371 | 424 | ||
| 372 | static const struct tty_operations slave_pty_ops_bsd = { | 425 | static const struct tty_operations slave_pty_ops_bsd = { |
| @@ -379,7 +432,9 @@ static const struct tty_operations slave_pty_ops_bsd = { | |||
| 379 | .chars_in_buffer = pty_chars_in_buffer, | 432 | .chars_in_buffer = pty_chars_in_buffer, |
| 380 | .unthrottle = pty_unthrottle, | 433 | .unthrottle = pty_unthrottle, |
| 381 | .set_termios = pty_set_termios, | 434 | .set_termios = pty_set_termios, |
| 382 | .resize = pty_resize | 435 | .cleanup = pty_cleanup, |
| 436 | .resize = pty_resize, | ||
| 437 | .remove = pty_remove | ||
| 383 | }; | 438 | }; |
| 384 | 439 | ||
| 385 | static void __init legacy_pty_init(void) | 440 | static void __init legacy_pty_init(void) |
| @@ -389,12 +444,18 @@ static void __init legacy_pty_init(void) | |||
| 389 | if (legacy_count <= 0) | 444 | if (legacy_count <= 0) |
| 390 | return; | 445 | return; |
| 391 | 446 | ||
| 392 | pty_driver = alloc_tty_driver(legacy_count); | 447 | pty_driver = tty_alloc_driver(legacy_count, |
| 393 | if (!pty_driver) | 448 | TTY_DRIVER_RESET_TERMIOS | |
| 449 | TTY_DRIVER_REAL_RAW | | ||
| 450 | TTY_DRIVER_DYNAMIC_ALLOC); | ||
| 451 | if (IS_ERR(pty_driver)) | ||
| 394 | panic("Couldn't allocate pty driver"); | 452 | panic("Couldn't allocate pty driver"); |
| 395 | 453 | ||
| 396 | pty_slave_driver = alloc_tty_driver(legacy_count); | 454 | pty_slave_driver = tty_alloc_driver(legacy_count, |
| 397 | if (!pty_slave_driver) | 455 | TTY_DRIVER_RESET_TERMIOS | |
| 456 | TTY_DRIVER_REAL_RAW | | ||
| 457 | TTY_DRIVER_DYNAMIC_ALLOC); | ||
| 458 | if (IS_ERR(pty_slave_driver)) | ||
| 398 | panic("Couldn't allocate pty slave driver"); | 459 | panic("Couldn't allocate pty slave driver"); |
| 399 | 460 | ||
| 400 | pty_driver->driver_name = "pty_master"; | 461 | pty_driver->driver_name = "pty_master"; |
| @@ -410,7 +471,6 @@ static void __init legacy_pty_init(void) | |||
| 410 | pty_driver->init_termios.c_lflag = 0; | 471 | pty_driver->init_termios.c_lflag = 0; |
| 411 | pty_driver->init_termios.c_ispeed = 38400; | 472 | pty_driver->init_termios.c_ispeed = 38400; |
| 412 | pty_driver->init_termios.c_ospeed = 38400; | 473 | pty_driver->init_termios.c_ospeed = 38400; |
| 413 | pty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW; | ||
| 414 | pty_driver->other = pty_slave_driver; | 474 | pty_driver->other = pty_slave_driver; |
| 415 | tty_set_operations(pty_driver, &master_pty_ops_bsd); | 475 | tty_set_operations(pty_driver, &master_pty_ops_bsd); |
| 416 | 476 | ||
| @@ -424,8 +484,6 @@ static void __init legacy_pty_init(void) | |||
| 424 | pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; | 484 | pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; |
| 425 | pty_slave_driver->init_termios.c_ispeed = 38400; | 485 | pty_slave_driver->init_termios.c_ispeed = 38400; |
| 426 | pty_slave_driver->init_termios.c_ospeed = 38400; | 486 | pty_slave_driver->init_termios.c_ospeed = 38400; |
| 427 | pty_slave_driver->flags = TTY_DRIVER_RESET_TERMIOS | | ||
| 428 | TTY_DRIVER_REAL_RAW; | ||
| 429 | pty_slave_driver->other = pty_driver; | 487 | pty_slave_driver->other = pty_driver; |
| 430 | tty_set_operations(pty_slave_driver, &slave_pty_ops_bsd); | 488 | tty_set_operations(pty_slave_driver, &slave_pty_ops_bsd); |
| 431 | 489 | ||
| @@ -497,78 +555,22 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, | |||
| 497 | return tty; | 555 | return tty; |
| 498 | } | 556 | } |
| 499 | 557 | ||
| 500 | static void pty_unix98_shutdown(struct tty_struct *tty) | ||
| 501 | { | ||
| 502 | tty_driver_remove_tty(tty->driver, tty); | ||
| 503 | /* We have our own method as we don't use the tty index */ | ||
| 504 | kfree(tty->termios); | ||
| 505 | } | ||
| 506 | |||
| 507 | /* We have no need to install and remove our tty objects as devpts does all | 558 | /* We have no need to install and remove our tty objects as devpts does all |
| 508 | the work for us */ | 559 | the work for us */ |
| 509 | 560 | ||
| 510 | static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) | 561 | static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) |
| 511 | { | 562 | { |
| 512 | struct tty_struct *o_tty; | 563 | return pty_common_install(driver, tty, false); |
| 513 | int idx = tty->index; | ||
| 514 | |||
| 515 | o_tty = alloc_tty_struct(); | ||
| 516 | if (!o_tty) | ||
| 517 | return -ENOMEM; | ||
| 518 | if (!try_module_get(driver->other->owner)) { | ||
| 519 | /* This cannot in fact currently happen */ | ||
| 520 | goto err_free_tty; | ||
| 521 | } | ||
| 522 | initialize_tty_struct(o_tty, driver->other, idx); | ||
| 523 | |||
| 524 | tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | ||
| 525 | if (tty->termios == NULL) | ||
| 526 | goto err_free_mem; | ||
| 527 | *tty->termios = driver->init_termios; | ||
| 528 | tty->termios_locked = tty->termios + 1; | ||
| 529 | |||
| 530 | o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | ||
| 531 | if (o_tty->termios == NULL) | ||
| 532 | goto err_free_mem; | ||
| 533 | *o_tty->termios = driver->other->init_termios; | ||
| 534 | o_tty->termios_locked = o_tty->termios + 1; | ||
| 535 | |||
| 536 | tty_driver_kref_get(driver->other); | ||
| 537 | if (driver->subtype == PTY_TYPE_MASTER) | ||
| 538 | o_tty->count++; | ||
| 539 | /* Establish the links in both directions */ | ||
| 540 | tty->link = o_tty; | ||
| 541 | o_tty->link = tty; | ||
| 542 | /* | ||
| 543 | * All structures have been allocated, so now we install them. | ||
| 544 | * Failures after this point use release_tty to clean up, so | ||
| 545 | * there's no need to null out the local pointers. | ||
| 546 | */ | ||
| 547 | tty_driver_kref_get(driver); | ||
| 548 | tty->count++; | ||
| 549 | return 0; | ||
| 550 | err_free_mem: | ||
| 551 | deinitialize_tty_struct(o_tty); | ||
| 552 | kfree(o_tty->termios); | ||
| 553 | kfree(tty->termios); | ||
| 554 | module_put(o_tty->driver->owner); | ||
| 555 | err_free_tty: | ||
| 556 | free_tty_struct(o_tty); | ||
| 557 | return -ENOMEM; | ||
| 558 | } | ||
| 559 | |||
| 560 | static void ptm_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) | ||
| 561 | { | ||
| 562 | } | 564 | } |
| 563 | 565 | ||
| 564 | static void pts_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) | 566 | static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) |
| 565 | { | 567 | { |
| 566 | } | 568 | } |
| 567 | 569 | ||
| 568 | static const struct tty_operations ptm_unix98_ops = { | 570 | static const struct tty_operations ptm_unix98_ops = { |
| 569 | .lookup = ptm_unix98_lookup, | 571 | .lookup = ptm_unix98_lookup, |
| 570 | .install = pty_unix98_install, | 572 | .install = pty_unix98_install, |
| 571 | .remove = ptm_unix98_remove, | 573 | .remove = pty_unix98_remove, |
| 572 | .open = pty_open, | 574 | .open = pty_open, |
| 573 | .close = pty_close, | 575 | .close = pty_close, |
| 574 | .write = pty_write, | 576 | .write = pty_write, |
| @@ -578,14 +580,14 @@ static const struct tty_operations ptm_unix98_ops = { | |||
| 578 | .unthrottle = pty_unthrottle, | 580 | .unthrottle = pty_unthrottle, |
| 579 | .set_termios = pty_set_termios, | 581 | .set_termios = pty_set_termios, |
| 580 | .ioctl = pty_unix98_ioctl, | 582 | .ioctl = pty_unix98_ioctl, |
| 581 | .shutdown = pty_unix98_shutdown, | 583 | .resize = pty_resize, |
| 582 | .resize = pty_resize | 584 | .cleanup = pty_cleanup |
| 583 | }; | 585 | }; |
| 584 | 586 | ||
| 585 | static const struct tty_operations pty_unix98_ops = { | 587 | static const struct tty_operations pty_unix98_ops = { |
| 586 | .lookup = pts_unix98_lookup, | 588 | .lookup = pts_unix98_lookup, |
| 587 | .install = pty_unix98_install, | 589 | .install = pty_unix98_install, |
| 588 | .remove = pts_unix98_remove, | 590 | .remove = pty_unix98_remove, |
| 589 | .open = pty_open, | 591 | .open = pty_open, |
| 590 | .close = pty_close, | 592 | .close = pty_close, |
| 591 | .write = pty_write, | 593 | .write = pty_write, |
| @@ -594,7 +596,7 @@ static const struct tty_operations pty_unix98_ops = { | |||
| 594 | .chars_in_buffer = pty_chars_in_buffer, | 596 | .chars_in_buffer = pty_chars_in_buffer, |
| 595 | .unthrottle = pty_unthrottle, | 597 | .unthrottle = pty_unthrottle, |
| 596 | .set_termios = pty_set_termios, | 598 | .set_termios = pty_set_termios, |
| 597 | .shutdown = pty_unix98_shutdown | 599 | .cleanup = pty_cleanup, |
| 598 | }; | 600 | }; |
| 599 | 601 | ||
| 600 | /** | 602 | /** |
| @@ -622,26 +624,28 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
| 622 | return retval; | 624 | return retval; |
| 623 | 625 | ||
| 624 | /* find a device that is not in use. */ | 626 | /* find a device that is not in use. */ |
| 625 | tty_lock(); | 627 | mutex_lock(&devpts_mutex); |
| 626 | index = devpts_new_index(inode); | 628 | index = devpts_new_index(inode); |
| 627 | tty_unlock(); | ||
| 628 | if (index < 0) { | 629 | if (index < 0) { |
| 629 | retval = index; | 630 | retval = index; |
| 631 | mutex_unlock(&devpts_mutex); | ||
| 630 | goto err_file; | 632 | goto err_file; |
| 631 | } | 633 | } |
| 632 | 634 | ||
| 635 | mutex_unlock(&devpts_mutex); | ||
| 636 | |||
| 633 | mutex_lock(&tty_mutex); | 637 | mutex_lock(&tty_mutex); |
| 634 | mutex_lock(&devpts_mutex); | ||
| 635 | tty = tty_init_dev(ptm_driver, index); | 638 | tty = tty_init_dev(ptm_driver, index); |
| 636 | mutex_unlock(&devpts_mutex); | ||
| 637 | tty_lock(); | ||
| 638 | mutex_unlock(&tty_mutex); | ||
| 639 | 639 | ||
| 640 | if (IS_ERR(tty)) { | 640 | if (IS_ERR(tty)) { |
| 641 | retval = PTR_ERR(tty); | 641 | retval = PTR_ERR(tty); |
| 642 | goto out; | 642 | goto out; |
| 643 | } | 643 | } |
| 644 | 644 | ||
| 645 | /* The tty returned here is locked so we can safely | ||
| 646 | drop the mutex */ | ||
| 647 | mutex_unlock(&tty_mutex); | ||
| 648 | |||
| 645 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | 649 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ |
| 646 | 650 | ||
| 647 | tty_add_file(tty, filp); | 651 | tty_add_file(tty, filp); |
| @@ -654,15 +658,15 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
| 654 | if (retval) | 658 | if (retval) |
| 655 | goto err_release; | 659 | goto err_release; |
| 656 | 660 | ||
| 657 | tty_unlock(); | 661 | tty_unlock(tty); |
| 658 | return 0; | 662 | return 0; |
| 659 | err_release: | 663 | err_release: |
| 660 | tty_unlock(); | 664 | tty_unlock(tty); |
| 661 | tty_release(inode, filp); | 665 | tty_release(inode, filp); |
| 662 | return retval; | 666 | return retval; |
| 663 | out: | 667 | out: |
| 668 | mutex_unlock(&tty_mutex); | ||
| 664 | devpts_kill_index(inode, index); | 669 | devpts_kill_index(inode, index); |
| 665 | tty_unlock(); | ||
| 666 | err_file: | 670 | err_file: |
| 667 | tty_free_file(filp); | 671 | tty_free_file(filp); |
| 668 | return retval; | 672 | return retval; |
| @@ -672,11 +676,21 @@ static struct file_operations ptmx_fops; | |||
| 672 | 676 | ||
| 673 | static void __init unix98_pty_init(void) | 677 | static void __init unix98_pty_init(void) |
| 674 | { | 678 | { |
| 675 | ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX); | 679 | ptm_driver = tty_alloc_driver(NR_UNIX98_PTY_MAX, |
| 676 | if (!ptm_driver) | 680 | TTY_DRIVER_RESET_TERMIOS | |
| 681 | TTY_DRIVER_REAL_RAW | | ||
| 682 | TTY_DRIVER_DYNAMIC_DEV | | ||
| 683 | TTY_DRIVER_DEVPTS_MEM | | ||
| 684 | TTY_DRIVER_DYNAMIC_ALLOC); | ||
| 685 | if (IS_ERR(ptm_driver)) | ||
| 677 | panic("Couldn't allocate Unix98 ptm driver"); | 686 | panic("Couldn't allocate Unix98 ptm driver"); |
| 678 | pts_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX); | 687 | pts_driver = tty_alloc_driver(NR_UNIX98_PTY_MAX, |
| 679 | if (!pts_driver) | 688 | TTY_DRIVER_RESET_TERMIOS | |
| 689 | TTY_DRIVER_REAL_RAW | | ||
| 690 | TTY_DRIVER_DYNAMIC_DEV | | ||
| 691 | TTY_DRIVER_DEVPTS_MEM | | ||
| 692 | TTY_DRIVER_DYNAMIC_ALLOC); | ||
| 693 | if (IS_ERR(pts_driver)) | ||
| 680 | panic("Couldn't allocate Unix98 pts driver"); | 694 | panic("Couldn't allocate Unix98 pts driver"); |
| 681 | 695 | ||
| 682 | ptm_driver->driver_name = "pty_master"; | 696 | ptm_driver->driver_name = "pty_master"; |
| @@ -692,8 +706,6 @@ static void __init unix98_pty_init(void) | |||
| 692 | ptm_driver->init_termios.c_lflag = 0; | 706 | ptm_driver->init_termios.c_lflag = 0; |
| 693 | ptm_driver->init_termios.c_ispeed = 38400; | 707 | ptm_driver->init_termios.c_ispeed = 38400; |
| 694 | ptm_driver->init_termios.c_ospeed = 38400; | 708 | ptm_driver->init_termios.c_ospeed = 38400; |
| 695 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | ||
| 696 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; | ||
| 697 | ptm_driver->other = pts_driver; | 709 | ptm_driver->other = pts_driver; |
| 698 | tty_set_operations(ptm_driver, &ptm_unix98_ops); | 710 | tty_set_operations(ptm_driver, &ptm_unix98_ops); |
| 699 | 711 | ||
| @@ -707,8 +719,6 @@ static void __init unix98_pty_init(void) | |||
| 707 | pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; | 719 | pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; |
| 708 | pts_driver->init_termios.c_ispeed = 38400; | 720 | pts_driver->init_termios.c_ispeed = 38400; |
| 709 | pts_driver->init_termios.c_ospeed = 38400; | 721 | pts_driver->init_termios.c_ospeed = 38400; |
| 710 | pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | ||
| 711 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; | ||
| 712 | pts_driver->other = ptm_driver; | 722 | pts_driver->other = ptm_driver; |
| 713 | tty_set_operations(pts_driver, &pty_unix98_ops); | 723 | tty_set_operations(pts_driver, &pty_unix98_ops); |
| 714 | 724 | ||
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 777d5f9cf6cc..9700d34b20a3 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c | |||
| @@ -704,8 +704,8 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | |||
| 704 | spin_lock_init(&info->slock); | 704 | spin_lock_init(&info->slock); |
| 705 | mutex_init(&info->write_mtx); | 705 | mutex_init(&info->write_mtx); |
| 706 | rp_table[line] = info; | 706 | rp_table[line] = info; |
| 707 | tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev : | 707 | tty_port_register_device(&info->port, rocket_driver, line, |
| 708 | NULL); | 708 | pci_dev ? &pci_dev->dev : NULL); |
| 709 | } | 709 | } |
| 710 | 710 | ||
| 711 | /* | 711 | /* |
| @@ -720,7 +720,7 @@ static void configure_r_port(struct tty_struct *tty, struct r_port *info, | |||
| 720 | unsigned rocketMode; | 720 | unsigned rocketMode; |
| 721 | int bits, baud, divisor; | 721 | int bits, baud, divisor; |
| 722 | CHANNEL_t *cp; | 722 | CHANNEL_t *cp; |
| 723 | struct ktermios *t = tty->termios; | 723 | struct ktermios *t = &tty->termios; |
| 724 | 724 | ||
| 725 | cp = &info->channel; | 725 | cp = &info->channel; |
| 726 | cflag = t->c_cflag; | 726 | cflag = t->c_cflag; |
| @@ -978,7 +978,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp) | |||
| 978 | tty->alt_speed = 460800; | 978 | tty->alt_speed = 460800; |
| 979 | 979 | ||
| 980 | configure_r_port(tty, info, NULL); | 980 | configure_r_port(tty, info, NULL); |
| 981 | if (tty->termios->c_cflag & CBAUD) { | 981 | if (tty->termios.c_cflag & CBAUD) { |
| 982 | sSetDTR(cp); | 982 | sSetDTR(cp); |
| 983 | sSetRTS(cp); | 983 | sSetRTS(cp); |
| 984 | } | 984 | } |
| @@ -1089,35 +1089,35 @@ static void rp_set_termios(struct tty_struct *tty, | |||
| 1089 | if (rocket_paranoia_check(info, "rp_set_termios")) | 1089 | if (rocket_paranoia_check(info, "rp_set_termios")) |
| 1090 | return; | 1090 | return; |
| 1091 | 1091 | ||
| 1092 | cflag = tty->termios->c_cflag; | 1092 | cflag = tty->termios.c_cflag; |
| 1093 | 1093 | ||
| 1094 | /* | 1094 | /* |
| 1095 | * This driver doesn't support CS5 or CS6 | 1095 | * This driver doesn't support CS5 or CS6 |
| 1096 | */ | 1096 | */ |
| 1097 | if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6)) | 1097 | if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6)) |
| 1098 | tty->termios->c_cflag = | 1098 | tty->termios.c_cflag = |
| 1099 | ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE)); | 1099 | ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE)); |
| 1100 | /* Or CMSPAR */ | 1100 | /* Or CMSPAR */ |
| 1101 | tty->termios->c_cflag &= ~CMSPAR; | 1101 | tty->termios.c_cflag &= ~CMSPAR; |
| 1102 | 1102 | ||
| 1103 | configure_r_port(tty, info, old_termios); | 1103 | configure_r_port(tty, info, old_termios); |
| 1104 | 1104 | ||
| 1105 | cp = &info->channel; | 1105 | cp = &info->channel; |
| 1106 | 1106 | ||
| 1107 | /* Handle transition to B0 status */ | 1107 | /* Handle transition to B0 status */ |
| 1108 | if ((old_termios->c_cflag & CBAUD) && !(tty->termios->c_cflag & CBAUD)) { | 1108 | if ((old_termios->c_cflag & CBAUD) && !(tty->termios.c_cflag & CBAUD)) { |
| 1109 | sClrDTR(cp); | 1109 | sClrDTR(cp); |
| 1110 | sClrRTS(cp); | 1110 | sClrRTS(cp); |
| 1111 | } | 1111 | } |
| 1112 | 1112 | ||
| 1113 | /* Handle transition away from B0 status */ | 1113 | /* Handle transition away from B0 status */ |
| 1114 | if (!(old_termios->c_cflag & CBAUD) && (tty->termios->c_cflag & CBAUD)) { | 1114 | if (!(old_termios->c_cflag & CBAUD) && (tty->termios.c_cflag & CBAUD)) { |
| 1115 | if (!tty->hw_stopped || !(tty->termios->c_cflag & CRTSCTS)) | 1115 | if (!tty->hw_stopped || !(tty->termios.c_cflag & CRTSCTS)) |
| 1116 | sSetRTS(cp); | 1116 | sSetRTS(cp); |
| 1117 | sSetDTR(cp); | 1117 | sSetDTR(cp); |
| 1118 | } | 1118 | } |
| 1119 | 1119 | ||
| 1120 | if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { | 1120 | if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios.c_cflag & CRTSCTS)) { |
| 1121 | tty->hw_stopped = 0; | 1121 | tty->hw_stopped = 0; |
| 1122 | rp_start(tty); | 1122 | rp_start(tty); |
| 1123 | } | 1123 | } |
diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index 3ed20e435e59..66c38a3f74ce 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c | |||
| @@ -515,7 +515,7 @@ static void change_speed(struct m68k_serial *info, struct tty_struct *tty) | |||
| 515 | unsigned cflag; | 515 | unsigned cflag; |
| 516 | int i; | 516 | int i; |
| 517 | 517 | ||
| 518 | cflag = tty->termios->c_cflag; | 518 | cflag = tty->termios.c_cflag; |
| 519 | if (!(port = info->port)) | 519 | if (!(port = info->port)) |
| 520 | return; | 520 | return; |
| 521 | 521 | ||
| @@ -617,7 +617,7 @@ static void rs_set_ldisc(struct tty_struct *tty) | |||
| 617 | if (serial_paranoia_check(info, tty->name, "rs_set_ldisc")) | 617 | if (serial_paranoia_check(info, tty->name, "rs_set_ldisc")) |
| 618 | return; | 618 | return; |
| 619 | 619 | ||
| 620 | info->is_cons = (tty->termios->c_line == N_TTY); | 620 | info->is_cons = (tty->termios.c_line == N_TTY); |
| 621 | 621 | ||
| 622 | printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off"); | 622 | printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off"); |
| 623 | } | 623 | } |
| @@ -985,7 +985,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 985 | change_speed(info, tty); | 985 | change_speed(info, tty); |
| 986 | 986 | ||
| 987 | if ((old_termios->c_cflag & CRTSCTS) && | 987 | if ((old_termios->c_cflag & CRTSCTS) && |
| 988 | !(tty->termios->c_cflag & CRTSCTS)) { | 988 | !(tty->termios.c_cflag & CRTSCTS)) { |
| 989 | tty->hw_stopped = 0; | 989 | tty->hw_stopped = 0; |
| 990 | rs_start(tty); | 990 | rs_start(tty); |
| 991 | } | 991 | } |
| @@ -1070,7 +1070,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
| 1070 | if (tty->ldisc.close) | 1070 | if (tty->ldisc.close) |
| 1071 | (tty->ldisc.close)(tty); | 1071 | (tty->ldisc.close)(tty); |
| 1072 | tty->ldisc = ldiscs[N_TTY]; | 1072 | tty->ldisc = ldiscs[N_TTY]; |
| 1073 | tty->termios->c_line = N_TTY; | 1073 | tty->termios.c_line = N_TTY; |
| 1074 | if (tty->ldisc.open) | 1074 | if (tty->ldisc.open) |
| 1075 | (tty->ldisc.open)(tty); | 1075 | (tty->ldisc.open)(tty); |
| 1076 | } | 1076 | } |
| @@ -1189,12 +1189,6 @@ rs68328_init(void) | |||
| 1189 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | 1189 | serial_driver->flags = TTY_DRIVER_REAL_RAW; |
| 1190 | tty_set_operations(serial_driver, &rs_ops); | 1190 | tty_set_operations(serial_driver, &rs_ops); |
| 1191 | 1191 | ||
| 1192 | if (tty_register_driver(serial_driver)) { | ||
| 1193 | put_tty_driver(serial_driver); | ||
| 1194 | printk(KERN_ERR "Couldn't register serial driver\n"); | ||
| 1195 | return -ENOMEM; | ||
| 1196 | } | ||
| 1197 | |||
| 1198 | local_irq_save(flags); | 1192 | local_irq_save(flags); |
| 1199 | 1193 | ||
| 1200 | for(i=0;i<NR_PORTS;i++) { | 1194 | for(i=0;i<NR_PORTS;i++) { |
| @@ -1224,8 +1218,17 @@ rs68328_init(void) | |||
| 1224 | 0, | 1218 | 0, |
| 1225 | "M68328_UART", info)) | 1219 | "M68328_UART", info)) |
| 1226 | panic("Unable to attach 68328 serial interrupt\n"); | 1220 | panic("Unable to attach 68328 serial interrupt\n"); |
| 1221 | |||
| 1222 | tty_port_link_device(&info->tport, serial_driver, i); | ||
| 1227 | } | 1223 | } |
| 1228 | local_irq_restore(flags); | 1224 | local_irq_restore(flags); |
| 1225 | |||
| 1226 | if (tty_register_driver(serial_driver)) { | ||
| 1227 | put_tty_driver(serial_driver); | ||
| 1228 | printk(KERN_ERR "Couldn't register serial driver\n"); | ||
| 1229 | return -ENOMEM; | ||
| 1230 | } | ||
| 1231 | |||
| 1229 | return 0; | 1232 | return 0; |
| 1230 | } | 1233 | } |
| 1231 | 1234 | ||
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 8123f784bcda..3ba4234592bc 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c | |||
| @@ -290,6 +290,9 @@ static const struct serial8250_config uart_config[] = { | |||
| 290 | UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00, | 290 | UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00, |
| 291 | .flags = UART_CAP_FIFO, | 291 | .flags = UART_CAP_FIFO, |
| 292 | }, | 292 | }, |
| 293 | [PORT_8250_CIR] = { | ||
| 294 | .name = "CIR port" | ||
| 295 | } | ||
| 293 | }; | 296 | }; |
| 294 | 297 | ||
| 295 | /* Uart divisor latch read */ | 298 | /* Uart divisor latch read */ |
| @@ -1037,6 +1040,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
| 1037 | unsigned char save_lcr, save_mcr; | 1040 | unsigned char save_lcr, save_mcr; |
| 1038 | struct uart_port *port = &up->port; | 1041 | struct uart_port *port = &up->port; |
| 1039 | unsigned long flags; | 1042 | unsigned long flags; |
| 1043 | unsigned int old_capabilities; | ||
| 1040 | 1044 | ||
| 1041 | if (!port->iobase && !port->mapbase && !port->membase) | 1045 | if (!port->iobase && !port->mapbase && !port->membase) |
| 1042 | return; | 1046 | return; |
| @@ -1087,6 +1091,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
| 1087 | /* | 1091 | /* |
| 1088 | * We failed; there's nothing here | 1092 | * We failed; there's nothing here |
| 1089 | */ | 1093 | */ |
| 1094 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 1090 | DEBUG_AUTOCONF("IER test failed (%02x, %02x) ", | 1095 | DEBUG_AUTOCONF("IER test failed (%02x, %02x) ", |
| 1091 | scratch2, scratch3); | 1096 | scratch2, scratch3); |
| 1092 | goto out; | 1097 | goto out; |
| @@ -1110,6 +1115,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
| 1110 | status1 = serial_in(up, UART_MSR) & 0xF0; | 1115 | status1 = serial_in(up, UART_MSR) & 0xF0; |
| 1111 | serial_out(up, UART_MCR, save_mcr); | 1116 | serial_out(up, UART_MCR, save_mcr); |
| 1112 | if (status1 != 0x90) { | 1117 | if (status1 != 0x90) { |
| 1118 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 1113 | DEBUG_AUTOCONF("LOOP test failed (%02x) ", | 1119 | DEBUG_AUTOCONF("LOOP test failed (%02x) ", |
| 1114 | status1); | 1120 | status1); |
| 1115 | goto out; | 1121 | goto out; |
| @@ -1132,8 +1138,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
| 1132 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); | 1138 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); |
| 1133 | scratch = serial_in(up, UART_IIR) >> 6; | 1139 | scratch = serial_in(up, UART_IIR) >> 6; |
| 1134 | 1140 | ||
| 1135 | DEBUG_AUTOCONF("iir=%d ", scratch); | ||
| 1136 | |||
| 1137 | switch (scratch) { | 1141 | switch (scratch) { |
| 1138 | case 0: | 1142 | case 0: |
| 1139 | autoconfig_8250(up); | 1143 | autoconfig_8250(up); |
| @@ -1167,19 +1171,13 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
| 1167 | 1171 | ||
| 1168 | serial_out(up, UART_LCR, save_lcr); | 1172 | serial_out(up, UART_LCR, save_lcr); |
| 1169 | 1173 | ||
| 1170 | if (up->capabilities != uart_config[port->type].flags) { | ||
| 1171 | printk(KERN_WARNING | ||
| 1172 | "ttyS%d: detected caps %08x should be %08x\n", | ||
| 1173 | serial_index(port), up->capabilities, | ||
| 1174 | uart_config[port->type].flags); | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | port->fifosize = uart_config[up->port.type].fifo_size; | 1174 | port->fifosize = uart_config[up->port.type].fifo_size; |
| 1175 | old_capabilities = up->capabilities; | ||
| 1178 | up->capabilities = uart_config[port->type].flags; | 1176 | up->capabilities = uart_config[port->type].flags; |
| 1179 | up->tx_loadsz = uart_config[port->type].tx_loadsz; | 1177 | up->tx_loadsz = uart_config[port->type].tx_loadsz; |
| 1180 | 1178 | ||
| 1181 | if (port->type == PORT_UNKNOWN) | 1179 | if (port->type == PORT_UNKNOWN) |
| 1182 | goto out; | 1180 | goto out_lock; |
| 1183 | 1181 | ||
| 1184 | /* | 1182 | /* |
| 1185 | * Reset the UART. | 1183 | * Reset the UART. |
| @@ -1196,8 +1194,16 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
| 1196 | else | 1194 | else |
| 1197 | serial_out(up, UART_IER, 0); | 1195 | serial_out(up, UART_IER, 0); |
| 1198 | 1196 | ||
| 1199 | out: | 1197 | out_lock: |
| 1200 | spin_unlock_irqrestore(&port->lock, flags); | 1198 | spin_unlock_irqrestore(&port->lock, flags); |
| 1199 | if (up->capabilities != old_capabilities) { | ||
| 1200 | printk(KERN_WARNING | ||
| 1201 | "ttyS%d: detected caps %08x should be %08x\n", | ||
| 1202 | serial_index(port), old_capabilities, | ||
| 1203 | up->capabilities); | ||
| 1204 | } | ||
| 1205 | out: | ||
| 1206 | DEBUG_AUTOCONF("iir=%d ", scratch); | ||
| 1201 | DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name); | 1207 | DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name); |
| 1202 | } | 1208 | } |
| 1203 | 1209 | ||
| @@ -1897,6 +1903,9 @@ static int serial8250_startup(struct uart_port *port) | |||
| 1897 | unsigned char lsr, iir; | 1903 | unsigned char lsr, iir; |
| 1898 | int retval; | 1904 | int retval; |
| 1899 | 1905 | ||
| 1906 | if (port->type == PORT_8250_CIR) | ||
| 1907 | return -ENODEV; | ||
| 1908 | |||
| 1900 | port->fifosize = uart_config[up->port.type].fifo_size; | 1909 | port->fifosize = uart_config[up->port.type].fifo_size; |
| 1901 | up->tx_loadsz = uart_config[up->port.type].tx_loadsz; | 1910 | up->tx_loadsz = uart_config[up->port.type].tx_loadsz; |
| 1902 | up->capabilities = uart_config[up->port.type].flags; | 1911 | up->capabilities = uart_config[up->port.type].flags; |
| @@ -2202,6 +2211,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 2202 | unsigned char cval, fcr = 0; | 2211 | unsigned char cval, fcr = 0; |
| 2203 | unsigned long flags; | 2212 | unsigned long flags; |
| 2204 | unsigned int baud, quot; | 2213 | unsigned int baud, quot; |
| 2214 | int fifo_bug = 0; | ||
| 2205 | 2215 | ||
| 2206 | switch (termios->c_cflag & CSIZE) { | 2216 | switch (termios->c_cflag & CSIZE) { |
| 2207 | case CS5: | 2217 | case CS5: |
| @@ -2221,8 +2231,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 2221 | 2231 | ||
| 2222 | if (termios->c_cflag & CSTOPB) | 2232 | if (termios->c_cflag & CSTOPB) |
| 2223 | cval |= UART_LCR_STOP; | 2233 | cval |= UART_LCR_STOP; |
| 2224 | if (termios->c_cflag & PARENB) | 2234 | if (termios->c_cflag & PARENB) { |
| 2225 | cval |= UART_LCR_PARITY; | 2235 | cval |= UART_LCR_PARITY; |
| 2236 | if (up->bugs & UART_BUG_PARITY) | ||
| 2237 | fifo_bug = 1; | ||
| 2238 | } | ||
| 2226 | if (!(termios->c_cflag & PARODD)) | 2239 | if (!(termios->c_cflag & PARODD)) |
| 2227 | cval |= UART_LCR_EPAR; | 2240 | cval |= UART_LCR_EPAR; |
| 2228 | #ifdef CMSPAR | 2241 | #ifdef CMSPAR |
| @@ -2246,7 +2259,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 2246 | 2259 | ||
| 2247 | if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { | 2260 | if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { |
| 2248 | fcr = uart_config[port->type].fcr; | 2261 | fcr = uart_config[port->type].fcr; |
| 2249 | if (baud < 2400) { | 2262 | if (baud < 2400 || fifo_bug) { |
| 2250 | fcr &= ~UART_FCR_TRIGGER_MASK; | 2263 | fcr &= ~UART_FCR_TRIGGER_MASK; |
| 2251 | fcr |= UART_FCR_TRIGGER_1; | 2264 | fcr |= UART_FCR_TRIGGER_1; |
| 2252 | } | 2265 | } |
| @@ -2336,7 +2349,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 2336 | serial_port_out(port, UART_EFR, efr); | 2349 | serial_port_out(port, UART_EFR, efr); |
| 2337 | } | 2350 | } |
| 2338 | 2351 | ||
| 2339 | #ifdef CONFIG_ARCH_OMAP | 2352 | #ifdef CONFIG_ARCH_OMAP1 |
| 2340 | /* Workaround to enable 115200 baud on OMAP1510 internal ports */ | 2353 | /* Workaround to enable 115200 baud on OMAP1510 internal ports */ |
| 2341 | if (cpu_is_omap1510() && is_omap_port(up)) { | 2354 | if (cpu_is_omap1510() && is_omap_port(up)) { |
| 2342 | if (baud == 115200) { | 2355 | if (baud == 115200) { |
| @@ -2426,7 +2439,7 @@ static unsigned int serial8250_port_size(struct uart_8250_port *pt) | |||
| 2426 | { | 2439 | { |
| 2427 | if (pt->port.iotype == UPIO_AU) | 2440 | if (pt->port.iotype == UPIO_AU) |
| 2428 | return 0x1000; | 2441 | return 0x1000; |
| 2429 | #ifdef CONFIG_ARCH_OMAP | 2442 | #ifdef CONFIG_ARCH_OMAP1 |
| 2430 | if (is_omap_port(pt)) | 2443 | if (is_omap_port(pt)) |
| 2431 | return 0x16 << pt->port.regshift; | 2444 | return 0x16 << pt->port.regshift; |
| 2432 | #endif | 2445 | #endif |
| @@ -2550,7 +2563,10 @@ static int serial8250_request_port(struct uart_port *port) | |||
| 2550 | { | 2563 | { |
| 2551 | struct uart_8250_port *up = | 2564 | struct uart_8250_port *up = |
| 2552 | container_of(port, struct uart_8250_port, port); | 2565 | container_of(port, struct uart_8250_port, port); |
| 2553 | int ret = 0; | 2566 | int ret; |
| 2567 | |||
| 2568 | if (port->type == PORT_8250_CIR) | ||
| 2569 | return -ENODEV; | ||
| 2554 | 2570 | ||
| 2555 | ret = serial8250_request_std_resource(up); | 2571 | ret = serial8250_request_std_resource(up); |
| 2556 | if (ret == 0 && port->type == PORT_RSA) { | 2572 | if (ret == 0 && port->type == PORT_RSA) { |
| @@ -2569,6 +2585,9 @@ static void serial8250_config_port(struct uart_port *port, int flags) | |||
| 2569 | int probeflags = PROBE_ANY; | 2585 | int probeflags = PROBE_ANY; |
| 2570 | int ret; | 2586 | int ret; |
| 2571 | 2587 | ||
| 2588 | if (port->type == PORT_8250_CIR) | ||
| 2589 | return; | ||
| 2590 | |||
| 2572 | /* | 2591 | /* |
| 2573 | * Find the region that we can probe for. This in turn | 2592 | * Find the region that we can probe for. This in turn |
| 2574 | * tells us whether we can probe for the type of port. | 2593 | * tells us whether we can probe for the type of port. |
| @@ -2668,6 +2687,9 @@ static void __init serial8250_isa_init_ports(void) | |||
| 2668 | return; | 2687 | return; |
| 2669 | first = 0; | 2688 | first = 0; |
| 2670 | 2689 | ||
| 2690 | if (nr_uarts > UART_NR) | ||
| 2691 | nr_uarts = UART_NR; | ||
| 2692 | |||
| 2671 | for (i = 0; i < nr_uarts; i++) { | 2693 | for (i = 0; i < nr_uarts; i++) { |
| 2672 | struct uart_8250_port *up = &serial8250_ports[i]; | 2694 | struct uart_8250_port *up = &serial8250_ports[i]; |
| 2673 | struct uart_port *port = &up->port; | 2695 | struct uart_port *port = &up->port; |
| @@ -2677,6 +2699,7 @@ static void __init serial8250_isa_init_ports(void) | |||
| 2677 | 2699 | ||
| 2678 | init_timer(&up->timer); | 2700 | init_timer(&up->timer); |
| 2679 | up->timer.function = serial8250_timeout; | 2701 | up->timer.function = serial8250_timeout; |
| 2702 | up->cur_iotype = 0xFF; | ||
| 2680 | 2703 | ||
| 2681 | /* | 2704 | /* |
| 2682 | * ALPHA_KLUDGE_MCR needs to be killed. | 2705 | * ALPHA_KLUDGE_MCR needs to be killed. |
| @@ -2728,13 +2751,9 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) | |||
| 2728 | 2751 | ||
| 2729 | for (i = 0; i < nr_uarts; i++) { | 2752 | for (i = 0; i < nr_uarts; i++) { |
| 2730 | struct uart_8250_port *up = &serial8250_ports[i]; | 2753 | struct uart_8250_port *up = &serial8250_ports[i]; |
| 2731 | up->cur_iotype = 0xFF; | ||
| 2732 | } | ||
| 2733 | |||
| 2734 | serial8250_isa_init_ports(); | ||
| 2735 | 2754 | ||
| 2736 | for (i = 0; i < nr_uarts; i++) { | 2755 | if (up->port.dev) |
| 2737 | struct uart_8250_port *up = &serial8250_ports[i]; | 2756 | continue; |
| 2738 | 2757 | ||
| 2739 | up->port.dev = dev; | 2758 | up->port.dev = dev; |
| 2740 | 2759 | ||
| @@ -2859,9 +2878,6 @@ static struct console serial8250_console = { | |||
| 2859 | 2878 | ||
| 2860 | static int __init serial8250_console_init(void) | 2879 | static int __init serial8250_console_init(void) |
| 2861 | { | 2880 | { |
| 2862 | if (nr_uarts > UART_NR) | ||
| 2863 | nr_uarts = UART_NR; | ||
| 2864 | |||
| 2865 | serial8250_isa_init_ports(); | 2881 | serial8250_isa_init_ports(); |
| 2866 | register_console(&serial8250_console); | 2882 | register_console(&serial8250_console); |
| 2867 | return 0; | 2883 | return 0; |
| @@ -2979,36 +2995,36 @@ void serial8250_resume_port(int line) | |||
| 2979 | static int __devinit serial8250_probe(struct platform_device *dev) | 2995 | static int __devinit serial8250_probe(struct platform_device *dev) |
| 2980 | { | 2996 | { |
| 2981 | struct plat_serial8250_port *p = dev->dev.platform_data; | 2997 | struct plat_serial8250_port *p = dev->dev.platform_data; |
| 2982 | struct uart_port port; | 2998 | struct uart_8250_port uart; |
| 2983 | int ret, i, irqflag = 0; | 2999 | int ret, i, irqflag = 0; |
| 2984 | 3000 | ||
| 2985 | memset(&port, 0, sizeof(struct uart_port)); | 3001 | memset(&uart, 0, sizeof(uart)); |
| 2986 | 3002 | ||
| 2987 | if (share_irqs) | 3003 | if (share_irqs) |
| 2988 | irqflag = IRQF_SHARED; | 3004 | irqflag = IRQF_SHARED; |
| 2989 | 3005 | ||
| 2990 | for (i = 0; p && p->flags != 0; p++, i++) { | 3006 | for (i = 0; p && p->flags != 0; p++, i++) { |
| 2991 | port.iobase = p->iobase; | 3007 | uart.port.iobase = p->iobase; |
| 2992 | port.membase = p->membase; | 3008 | uart.port.membase = p->membase; |
| 2993 | port.irq = p->irq; | 3009 | uart.port.irq = p->irq; |
| 2994 | port.irqflags = p->irqflags; | 3010 | uart.port.irqflags = p->irqflags; |
| 2995 | port.uartclk = p->uartclk; | 3011 | uart.port.uartclk = p->uartclk; |
| 2996 | port.regshift = p->regshift; | 3012 | uart.port.regshift = p->regshift; |
| 2997 | port.iotype = p->iotype; | 3013 | uart.port.iotype = p->iotype; |
| 2998 | port.flags = p->flags; | 3014 | uart.port.flags = p->flags; |
| 2999 | port.mapbase = p->mapbase; | 3015 | uart.port.mapbase = p->mapbase; |
| 3000 | port.hub6 = p->hub6; | 3016 | uart.port.hub6 = p->hub6; |
| 3001 | port.private_data = p->private_data; | 3017 | uart.port.private_data = p->private_data; |
| 3002 | port.type = p->type; | 3018 | uart.port.type = p->type; |
| 3003 | port.serial_in = p->serial_in; | 3019 | uart.port.serial_in = p->serial_in; |
| 3004 | port.serial_out = p->serial_out; | 3020 | uart.port.serial_out = p->serial_out; |
| 3005 | port.handle_irq = p->handle_irq; | 3021 | uart.port.handle_irq = p->handle_irq; |
| 3006 | port.handle_break = p->handle_break; | 3022 | uart.port.handle_break = p->handle_break; |
| 3007 | port.set_termios = p->set_termios; | 3023 | uart.port.set_termios = p->set_termios; |
| 3008 | port.pm = p->pm; | 3024 | uart.port.pm = p->pm; |
| 3009 | port.dev = &dev->dev; | 3025 | uart.port.dev = &dev->dev; |
| 3010 | port.irqflags |= irqflag; | 3026 | uart.port.irqflags |= irqflag; |
| 3011 | ret = serial8250_register_port(&port); | 3027 | ret = serial8250_register_8250_port(&uart); |
| 3012 | if (ret < 0) { | 3028 | if (ret < 0) { |
| 3013 | dev_err(&dev->dev, "unable to register port at index %d " | 3029 | dev_err(&dev->dev, "unable to register port at index %d " |
| 3014 | "(IO%lx MEM%llx IRQ%d): %d\n", i, | 3030 | "(IO%lx MEM%llx IRQ%d): %d\n", i, |
| @@ -3081,7 +3097,7 @@ static struct platform_driver serial8250_isa_driver = { | |||
| 3081 | static struct platform_device *serial8250_isa_devs; | 3097 | static struct platform_device *serial8250_isa_devs; |
| 3082 | 3098 | ||
| 3083 | /* | 3099 | /* |
| 3084 | * serial8250_register_port and serial8250_unregister_port allows for | 3100 | * serial8250_register_8250_port and serial8250_unregister_port allows for |
| 3085 | * 16x50 serial ports to be configured at run-time, to support PCMCIA | 3101 | * 16x50 serial ports to be configured at run-time, to support PCMCIA |
| 3086 | * modems and PCI multiport cards. | 3102 | * modems and PCI multiport cards. |
| 3087 | */ | 3103 | */ |
| @@ -3143,8 +3159,9 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
| 3143 | mutex_lock(&serial_mutex); | 3159 | mutex_lock(&serial_mutex); |
| 3144 | 3160 | ||
| 3145 | uart = serial8250_find_match_or_unused(&up->port); | 3161 | uart = serial8250_find_match_or_unused(&up->port); |
| 3146 | if (uart) { | 3162 | if (uart && uart->port.type != PORT_8250_CIR) { |
| 3147 | uart_remove_one_port(&serial8250_reg, &uart->port); | 3163 | if (uart->port.dev) |
| 3164 | uart_remove_one_port(&serial8250_reg, &uart->port); | ||
| 3148 | 3165 | ||
| 3149 | uart->port.iobase = up->port.iobase; | 3166 | uart->port.iobase = up->port.iobase; |
| 3150 | uart->port.membase = up->port.membase; | 3167 | uart->port.membase = up->port.membase; |
| @@ -3155,6 +3172,7 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
| 3155 | uart->port.regshift = up->port.regshift; | 3172 | uart->port.regshift = up->port.regshift; |
| 3156 | uart->port.iotype = up->port.iotype; | 3173 | uart->port.iotype = up->port.iotype; |
| 3157 | uart->port.flags = up->port.flags | UPF_BOOT_AUTOCONF; | 3174 | uart->port.flags = up->port.flags | UPF_BOOT_AUTOCONF; |
| 3175 | uart->bugs = up->bugs; | ||
| 3158 | uart->port.mapbase = up->port.mapbase; | 3176 | uart->port.mapbase = up->port.mapbase; |
| 3159 | uart->port.private_data = up->port.private_data; | 3177 | uart->port.private_data = up->port.private_data; |
| 3160 | if (up->port.dev) | 3178 | if (up->port.dev) |
| @@ -3198,29 +3216,6 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
| 3198 | EXPORT_SYMBOL(serial8250_register_8250_port); | 3216 | EXPORT_SYMBOL(serial8250_register_8250_port); |
| 3199 | 3217 | ||
| 3200 | /** | 3218 | /** |
| 3201 | * serial8250_register_port - register a serial port | ||
| 3202 | * @port: serial port template | ||
| 3203 | * | ||
| 3204 | * Configure the serial port specified by the request. If the | ||
| 3205 | * port exists and is in use, it is hung up and unregistered | ||
| 3206 | * first. | ||
| 3207 | * | ||
| 3208 | * The port is then probed and if necessary the IRQ is autodetected | ||
| 3209 | * If this fails an error is returned. | ||
| 3210 | * | ||
| 3211 | * On success the port is ready to use and the line number is returned. | ||
| 3212 | */ | ||
| 3213 | int serial8250_register_port(struct uart_port *port) | ||
| 3214 | { | ||
| 3215 | struct uart_8250_port up; | ||
| 3216 | |||
| 3217 | memset(&up, 0, sizeof(up)); | ||
| 3218 | memcpy(&up.port, port, sizeof(*port)); | ||
| 3219 | return serial8250_register_8250_port(&up); | ||
| 3220 | } | ||
| 3221 | EXPORT_SYMBOL(serial8250_register_port); | ||
| 3222 | |||
| 3223 | /** | ||
| 3224 | * serial8250_unregister_port - remove a 16x50 serial port at runtime | 3219 | * serial8250_unregister_port - remove a 16x50 serial port at runtime |
| 3225 | * @line: serial line number | 3220 | * @line: serial line number |
| 3226 | * | 3221 | * |
| @@ -3250,8 +3245,7 @@ static int __init serial8250_init(void) | |||
| 3250 | { | 3245 | { |
| 3251 | int ret; | 3246 | int ret; |
| 3252 | 3247 | ||
| 3253 | if (nr_uarts > UART_NR) | 3248 | serial8250_isa_init_ports(); |
| 3254 | nr_uarts = UART_NR; | ||
| 3255 | 3249 | ||
| 3256 | printk(KERN_INFO "Serial: 8250/16550 driver, " | 3250 | printk(KERN_INFO "Serial: 8250/16550 driver, " |
| 3257 | "%d ports, IRQ sharing %sabled\n", nr_uarts, | 3251 | "%d ports, IRQ sharing %sabled\n", nr_uarts, |
| @@ -3266,11 +3260,15 @@ static int __init serial8250_init(void) | |||
| 3266 | if (ret) | 3260 | if (ret) |
| 3267 | goto out; | 3261 | goto out; |
| 3268 | 3262 | ||
| 3263 | ret = serial8250_pnp_init(); | ||
| 3264 | if (ret) | ||
| 3265 | goto unreg_uart_drv; | ||
| 3266 | |||
| 3269 | serial8250_isa_devs = platform_device_alloc("serial8250", | 3267 | serial8250_isa_devs = platform_device_alloc("serial8250", |
| 3270 | PLAT8250_DEV_LEGACY); | 3268 | PLAT8250_DEV_LEGACY); |
| 3271 | if (!serial8250_isa_devs) { | 3269 | if (!serial8250_isa_devs) { |
| 3272 | ret = -ENOMEM; | 3270 | ret = -ENOMEM; |
| 3273 | goto unreg_uart_drv; | 3271 | goto unreg_pnp; |
| 3274 | } | 3272 | } |
| 3275 | 3273 | ||
| 3276 | ret = platform_device_add(serial8250_isa_devs); | 3274 | ret = platform_device_add(serial8250_isa_devs); |
| @@ -3286,6 +3284,8 @@ static int __init serial8250_init(void) | |||
| 3286 | platform_device_del(serial8250_isa_devs); | 3284 | platform_device_del(serial8250_isa_devs); |
| 3287 | put_dev: | 3285 | put_dev: |
| 3288 | platform_device_put(serial8250_isa_devs); | 3286 | platform_device_put(serial8250_isa_devs); |
| 3287 | unreg_pnp: | ||
| 3288 | serial8250_pnp_exit(); | ||
| 3289 | unreg_uart_drv: | 3289 | unreg_uart_drv: |
| 3290 | #ifdef CONFIG_SPARC | 3290 | #ifdef CONFIG_SPARC |
| 3291 | sunserial_unregister_minors(&serial8250_reg, UART_NR); | 3291 | sunserial_unregister_minors(&serial8250_reg, UART_NR); |
| @@ -3310,6 +3310,8 @@ static void __exit serial8250_exit(void) | |||
| 3310 | platform_driver_unregister(&serial8250_isa_driver); | 3310 | platform_driver_unregister(&serial8250_isa_driver); |
| 3311 | platform_device_unregister(isa_dev); | 3311 | platform_device_unregister(isa_dev); |
| 3312 | 3312 | ||
| 3313 | serial8250_pnp_exit(); | ||
| 3314 | |||
| 3313 | #ifdef CONFIG_SPARC | 3315 | #ifdef CONFIG_SPARC |
| 3314 | sunserial_unregister_minors(&serial8250_reg, UART_NR); | 3316 | sunserial_unregister_minors(&serial8250_reg, UART_NR); |
| 3315 | #else | 3317 | #else |
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index f9719d167c8d..5a76f9c8d36b 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
| @@ -13,36 +13,6 @@ | |||
| 13 | 13 | ||
| 14 | #include <linux/serial_8250.h> | 14 | #include <linux/serial_8250.h> |
| 15 | 15 | ||
| 16 | struct uart_8250_port { | ||
| 17 | struct uart_port port; | ||
| 18 | struct timer_list timer; /* "no irq" timer */ | ||
| 19 | struct list_head list; /* ports on this IRQ */ | ||
| 20 | unsigned short capabilities; /* port capabilities */ | ||
| 21 | unsigned short bugs; /* port bugs */ | ||
| 22 | unsigned int tx_loadsz; /* transmit fifo load size */ | ||
| 23 | unsigned char acr; | ||
| 24 | unsigned char ier; | ||
| 25 | unsigned char lcr; | ||
| 26 | unsigned char mcr; | ||
| 27 | unsigned char mcr_mask; /* mask of user bits */ | ||
| 28 | unsigned char mcr_force; /* mask of forced bits */ | ||
| 29 | unsigned char cur_iotype; /* Running I/O type */ | ||
| 30 | |||
| 31 | /* | ||
| 32 | * Some bits in registers are cleared on a read, so they must | ||
| 33 | * be saved whenever the register is read but the bits will not | ||
| 34 | * be immediately processed. | ||
| 35 | */ | ||
| 36 | #define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS | ||
| 37 | unsigned char lsr_saved_flags; | ||
| 38 | #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA | ||
| 39 | unsigned char msr_saved_flags; | ||
| 40 | |||
| 41 | /* 8250 specific callbacks */ | ||
| 42 | int (*dl_read)(struct uart_8250_port *); | ||
| 43 | void (*dl_write)(struct uart_8250_port *, int); | ||
| 44 | }; | ||
| 45 | |||
| 46 | struct old_serial_port { | 16 | struct old_serial_port { |
| 47 | unsigned int uart; | 17 | unsigned int uart; |
| 48 | unsigned int baud_base; | 18 | unsigned int baud_base; |
| @@ -56,9 +26,6 @@ struct old_serial_port { | |||
| 56 | unsigned long irqflags; | 26 | unsigned long irqflags; |
| 57 | }; | 27 | }; |
| 58 | 28 | ||
| 59 | /* | ||
| 60 | * This replaces serial_uart_config in include/linux/serial.h | ||
| 61 | */ | ||
| 62 | struct serial8250_config { | 29 | struct serial8250_config { |
| 63 | const char *name; | 30 | const char *name; |
| 64 | unsigned short fifo_size; | 31 | unsigned short fifo_size; |
| @@ -78,6 +45,7 @@ struct serial8250_config { | |||
| 78 | #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ | 45 | #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ |
| 79 | #define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */ | 46 | #define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */ |
| 80 | #define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */ | 47 | #define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */ |
| 48 | #define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */ | ||
| 81 | 49 | ||
| 82 | #define PROBE_RSA (1 << 0) | 50 | #define PROBE_RSA (1 << 0) |
| 83 | #define PROBE_ANY (~0) | 51 | #define PROBE_ANY (~0) |
| @@ -129,3 +97,12 @@ static inline void serial_dl_write(struct uart_8250_port *up, int value) | |||
| 129 | #else | 97 | #else |
| 130 | #define ALPHA_KLUDGE_MCR 0 | 98 | #define ALPHA_KLUDGE_MCR 0 |
| 131 | #endif | 99 | #endif |
| 100 | |||
| 101 | #ifdef CONFIG_SERIAL_8250_PNP | ||
| 102 | int serial8250_pnp_init(void); | ||
| 103 | void serial8250_pnp_exit(void); | ||
| 104 | #else | ||
| 105 | static inline int serial8250_pnp_init(void) { return 0; } | ||
| 106 | static inline void serial8250_pnp_exit(void) { } | ||
| 107 | #endif | ||
| 108 | |||
diff --git a/drivers/tty/serial/8250/8250_acorn.c b/drivers/tty/serial/8250/8250_acorn.c index b0ce8c56f1a4..857498312a9a 100644 --- a/drivers/tty/serial/8250/8250_acorn.c +++ b/drivers/tty/serial/8250/8250_acorn.c | |||
| @@ -43,7 +43,7 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
| 43 | { | 43 | { |
| 44 | struct serial_card_info *info; | 44 | struct serial_card_info *info; |
| 45 | struct serial_card_type *type = id->data; | 45 | struct serial_card_type *type = id->data; |
| 46 | struct uart_port port; | 46 | struct uart_8250_port uart; |
| 47 | unsigned long bus_addr; | 47 | unsigned long bus_addr; |
| 48 | unsigned int i; | 48 | unsigned int i; |
| 49 | 49 | ||
| @@ -62,19 +62,19 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
| 62 | 62 | ||
| 63 | ecard_set_drvdata(ec, info); | 63 | ecard_set_drvdata(ec, info); |
| 64 | 64 | ||
| 65 | memset(&port, 0, sizeof(struct uart_port)); | 65 | memset(&uart, 0, sizeof(struct uart_8250_port)); |
| 66 | port.irq = ec->irq; | 66 | uart.port.irq = ec->irq; |
| 67 | port.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; | 67 | uart.port.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; |
| 68 | port.uartclk = type->uartclk; | 68 | uart.port.uartclk = type->uartclk; |
| 69 | port.iotype = UPIO_MEM; | 69 | uart.port.iotype = UPIO_MEM; |
| 70 | port.regshift = 2; | 70 | uart.port.regshift = 2; |
| 71 | port.dev = &ec->dev; | 71 | uart.port.dev = &ec->dev; |
| 72 | 72 | ||
| 73 | for (i = 0; i < info->num_ports; i ++) { | 73 | for (i = 0; i < info->num_ports; i ++) { |
| 74 | port.membase = info->vaddr + type->offset[i]; | 74 | uart.port.membase = info->vaddr + type->offset[i]; |
| 75 | port.mapbase = bus_addr + type->offset[i]; | 75 | uart.port.mapbase = bus_addr + type->offset[i]; |
| 76 | 76 | ||
| 77 | info->ports[i] = serial8250_register_port(&port); | 77 | info->ports[i] = serial8250_register_8250_port(&uart); |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | return 0; | 80 | return 0; |
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index f574eef3075f..c3b2ec0c8c0b 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
| @@ -89,7 +89,7 @@ static int dw8250_handle_irq(struct uart_port *p) | |||
| 89 | 89 | ||
| 90 | static int __devinit dw8250_probe(struct platform_device *pdev) | 90 | static int __devinit dw8250_probe(struct platform_device *pdev) |
| 91 | { | 91 | { |
| 92 | struct uart_port port = {}; | 92 | struct uart_8250_port uart = {}; |
| 93 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 93 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 94 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 94 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
| 95 | struct device_node *np = pdev->dev.of_node; | 95 | struct device_node *np = pdev->dev.of_node; |
| @@ -104,28 +104,28 @@ static int __devinit dw8250_probe(struct platform_device *pdev) | |||
| 104 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | 104 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |
| 105 | if (!data) | 105 | if (!data) |
| 106 | return -ENOMEM; | 106 | return -ENOMEM; |
| 107 | port.private_data = data; | 107 | uart.port.private_data = data; |
| 108 | 108 | ||
| 109 | spin_lock_init(&port.lock); | 109 | spin_lock_init(&uart.port.lock); |
| 110 | port.mapbase = regs->start; | 110 | uart.port.mapbase = regs->start; |
| 111 | port.irq = irq->start; | 111 | uart.port.irq = irq->start; |
| 112 | port.handle_irq = dw8250_handle_irq; | 112 | uart.port.handle_irq = dw8250_handle_irq; |
| 113 | port.type = PORT_8250; | 113 | uart.port.type = PORT_8250; |
| 114 | port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | | 114 | uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | |
| 115 | UPF_FIXED_PORT | UPF_FIXED_TYPE; | 115 | UPF_FIXED_PORT | UPF_FIXED_TYPE; |
| 116 | port.dev = &pdev->dev; | 116 | uart.port.dev = &pdev->dev; |
| 117 | 117 | ||
| 118 | port.iotype = UPIO_MEM; | 118 | uart.port.iotype = UPIO_MEM; |
| 119 | port.serial_in = dw8250_serial_in; | 119 | uart.port.serial_in = dw8250_serial_in; |
| 120 | port.serial_out = dw8250_serial_out; | 120 | uart.port.serial_out = dw8250_serial_out; |
| 121 | if (!of_property_read_u32(np, "reg-io-width", &val)) { | 121 | if (!of_property_read_u32(np, "reg-io-width", &val)) { |
| 122 | switch (val) { | 122 | switch (val) { |
| 123 | case 1: | 123 | case 1: |
| 124 | break; | 124 | break; |
| 125 | case 4: | 125 | case 4: |
| 126 | port.iotype = UPIO_MEM32; | 126 | uart.port.iotype = UPIO_MEM32; |
| 127 | port.serial_in = dw8250_serial_in32; | 127 | uart.port.serial_in = dw8250_serial_in32; |
| 128 | port.serial_out = dw8250_serial_out32; | 128 | uart.port.serial_out = dw8250_serial_out32; |
| 129 | break; | 129 | break; |
| 130 | default: | 130 | default: |
| 131 | dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n", | 131 | dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n", |
| @@ -135,15 +135,15 @@ static int __devinit dw8250_probe(struct platform_device *pdev) | |||
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | if (!of_property_read_u32(np, "reg-shift", &val)) | 137 | if (!of_property_read_u32(np, "reg-shift", &val)) |
| 138 | port.regshift = val; | 138 | uart.port.regshift = val; |
| 139 | 139 | ||
| 140 | if (of_property_read_u32(np, "clock-frequency", &val)) { | 140 | if (of_property_read_u32(np, "clock-frequency", &val)) { |
| 141 | dev_err(&pdev->dev, "no clock-frequency property set\n"); | 141 | dev_err(&pdev->dev, "no clock-frequency property set\n"); |
| 142 | return -EINVAL; | 142 | return -EINVAL; |
| 143 | } | 143 | } |
| 144 | port.uartclk = val; | 144 | uart.port.uartclk = val; |
| 145 | 145 | ||
| 146 | data->line = serial8250_register_port(&port); | 146 | data->line = serial8250_register_8250_port(&uart); |
| 147 | if (data->line < 0) | 147 | if (data->line < 0) |
| 148 | return data->line; | 148 | return data->line; |
| 149 | 149 | ||
diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c index d8c0ffbfa6e3..097dff9c08ad 100644 --- a/drivers/tty/serial/8250/8250_gsc.c +++ b/drivers/tty/serial/8250/8250_gsc.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | static int __init serial_init_chip(struct parisc_device *dev) | 27 | static int __init serial_init_chip(struct parisc_device *dev) |
| 28 | { | 28 | { |
| 29 | struct uart_port port; | 29 | struct uart_8250_port uart; |
| 30 | unsigned long address; | 30 | unsigned long address; |
| 31 | int err; | 31 | int err; |
| 32 | 32 | ||
| @@ -48,21 +48,21 @@ static int __init serial_init_chip(struct parisc_device *dev) | |||
| 48 | if (dev->id.sversion != 0x8d) | 48 | if (dev->id.sversion != 0x8d) |
| 49 | address += 0x800; | 49 | address += 0x800; |
| 50 | 50 | ||
| 51 | memset(&port, 0, sizeof(port)); | 51 | memset(&uart, 0, sizeof(uart)); |
| 52 | port.iotype = UPIO_MEM; | 52 | uart.port.iotype = UPIO_MEM; |
| 53 | /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */ | 53 | /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */ |
| 54 | port.uartclk = 7272727; | 54 | uart.port.uartclk = 7272727; |
| 55 | port.mapbase = address; | 55 | uart.port.mapbase = address; |
| 56 | port.membase = ioremap_nocache(address, 16); | 56 | uart.port.membase = ioremap_nocache(address, 16); |
| 57 | port.irq = dev->irq; | 57 | uart.port.irq = dev->irq; |
| 58 | port.flags = UPF_BOOT_AUTOCONF; | 58 | uart.port.flags = UPF_BOOT_AUTOCONF; |
| 59 | port.dev = &dev->dev; | 59 | uart.port.dev = &dev->dev; |
| 60 | 60 | ||
| 61 | err = serial8250_register_port(&port); | 61 | err = serial8250_register_8250_port(&uart); |
| 62 | if (err < 0) { | 62 | if (err < 0) { |
| 63 | printk(KERN_WARNING | 63 | printk(KERN_WARNING |
| 64 | "serial8250_register_port returned error %d\n", err); | 64 | "serial8250_register_8250_port returned error %d\n", err); |
| 65 | iounmap(port.membase); | 65 | iounmap(uart.port.membase); |
| 66 | return err; | 66 | return err; |
| 67 | } | 67 | } |
| 68 | 68 | ||
diff --git a/drivers/tty/serial/8250/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c index c13438c93012..8f1dd2cc00a8 100644 --- a/drivers/tty/serial/8250/8250_hp300.c +++ b/drivers/tty/serial/8250/8250_hp300.c | |||
| @@ -171,7 +171,7 @@ static int __devinit hpdca_init_one(struct dio_dev *d, | |||
| 171 | return 0; | 171 | return 0; |
| 172 | } | 172 | } |
| 173 | #endif | 173 | #endif |
| 174 | memset(&port, 0, sizeof(struct uart_port)); | 174 | memset(&uart, 0, sizeof(uart)); |
| 175 | 175 | ||
| 176 | /* Memory mapped I/O */ | 176 | /* Memory mapped I/O */ |
| 177 | port.iotype = UPIO_MEM; | 177 | port.iotype = UPIO_MEM; |
| @@ -182,7 +182,7 @@ static int __devinit hpdca_init_one(struct dio_dev *d, | |||
| 182 | port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE); | 182 | port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE); |
| 183 | port.regshift = 1; | 183 | port.regshift = 1; |
| 184 | port.dev = &d->dev; | 184 | port.dev = &d->dev; |
| 185 | line = serial8250_register_port(&port); | 185 | line = serial8250_register_8250_port(&uart); |
| 186 | 186 | ||
| 187 | if (line < 0) { | 187 | if (line < 0) { |
| 188 | printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d" | 188 | printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d" |
| @@ -210,7 +210,7 @@ static int __init hp300_8250_init(void) | |||
| 210 | #ifdef CONFIG_HPAPCI | 210 | #ifdef CONFIG_HPAPCI |
| 211 | int line; | 211 | int line; |
| 212 | unsigned long base; | 212 | unsigned long base; |
| 213 | struct uart_port uport; | 213 | struct uart_8250_port uart; |
| 214 | struct hp300_port *port; | 214 | struct hp300_port *port; |
| 215 | int i; | 215 | int i; |
| 216 | #endif | 216 | #endif |
| @@ -248,26 +248,26 @@ static int __init hp300_8250_init(void) | |||
| 248 | if (!port) | 248 | if (!port) |
| 249 | return -ENOMEM; | 249 | return -ENOMEM; |
| 250 | 250 | ||
| 251 | memset(&uport, 0, sizeof(struct uart_port)); | 251 | memset(&uart, 0, sizeof(uart)); |
| 252 | 252 | ||
| 253 | base = (FRODO_BASE + FRODO_APCI_OFFSET(i)); | 253 | base = (FRODO_BASE + FRODO_APCI_OFFSET(i)); |
| 254 | 254 | ||
| 255 | /* Memory mapped I/O */ | 255 | /* Memory mapped I/O */ |
| 256 | uport.iotype = UPIO_MEM; | 256 | uart.port.iotype = UPIO_MEM; |
| 257 | uport.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ \ | 257 | uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ \ |
| 258 | | UPF_BOOT_AUTOCONF; | 258 | | UPF_BOOT_AUTOCONF; |
| 259 | /* XXX - no interrupt support yet */ | 259 | /* XXX - no interrupt support yet */ |
| 260 | uport.irq = 0; | 260 | uart.port.irq = 0; |
| 261 | uport.uartclk = HPAPCI_BAUD_BASE * 16; | 261 | uart.port.uartclk = HPAPCI_BAUD_BASE * 16; |
| 262 | uport.mapbase = base; | 262 | uart.port.mapbase = base; |
| 263 | uport.membase = (char *)(base + DIO_VIRADDRBASE); | 263 | uart.port.membase = (char *)(base + DIO_VIRADDRBASE); |
| 264 | uport.regshift = 2; | 264 | uart.port.regshift = 2; |
| 265 | 265 | ||
| 266 | line = serial8250_register_port(&uport); | 266 | line = serial8250_register_8250_port(&uart); |
| 267 | 267 | ||
| 268 | if (line < 0) { | 268 | if (line < 0) { |
| 269 | printk(KERN_NOTICE "8250_hp300: register_serial() APCI" | 269 | printk(KERN_NOTICE "8250_hp300: register_serial() APCI" |
| 270 | " %d irq %d failed\n", i, uport.irq); | 270 | " %d irq %d failed\n", i, uart.port.irq); |
| 271 | kfree(port); | 271 | kfree(port); |
| 272 | continue; | 272 | continue; |
| 273 | } | 273 | } |
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 452278efef29..17b7d26abf41 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
| @@ -44,7 +44,7 @@ struct pci_serial_quirk { | |||
| 44 | int (*init)(struct pci_dev *dev); | 44 | int (*init)(struct pci_dev *dev); |
| 45 | int (*setup)(struct serial_private *, | 45 | int (*setup)(struct serial_private *, |
| 46 | const struct pciserial_board *, | 46 | const struct pciserial_board *, |
| 47 | struct uart_port *, int); | 47 | struct uart_8250_port *, int); |
| 48 | void (*exit)(struct pci_dev *dev); | 48 | void (*exit)(struct pci_dev *dev); |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| @@ -59,7 +59,7 @@ struct serial_private { | |||
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | static int pci_default_setup(struct serial_private*, | 61 | static int pci_default_setup(struct serial_private*, |
| 62 | const struct pciserial_board*, struct uart_port*, int); | 62 | const struct pciserial_board*, struct uart_8250_port *, int); |
| 63 | 63 | ||
| 64 | static void moan_device(const char *str, struct pci_dev *dev) | 64 | static void moan_device(const char *str, struct pci_dev *dev) |
| 65 | { | 65 | { |
| @@ -74,7 +74,7 @@ static void moan_device(const char *str, struct pci_dev *dev) | |||
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | static int | 76 | static int |
| 77 | setup_port(struct serial_private *priv, struct uart_port *port, | 77 | setup_port(struct serial_private *priv, struct uart_8250_port *port, |
| 78 | int bar, int offset, int regshift) | 78 | int bar, int offset, int regshift) |
| 79 | { | 79 | { |
| 80 | struct pci_dev *dev = priv->dev; | 80 | struct pci_dev *dev = priv->dev; |
| @@ -93,17 +93,17 @@ setup_port(struct serial_private *priv, struct uart_port *port, | |||
| 93 | if (!priv->remapped_bar[bar]) | 93 | if (!priv->remapped_bar[bar]) |
| 94 | return -ENOMEM; | 94 | return -ENOMEM; |
| 95 | 95 | ||
| 96 | port->iotype = UPIO_MEM; | 96 | port->port.iotype = UPIO_MEM; |
| 97 | port->iobase = 0; | 97 | port->port.iobase = 0; |
| 98 | port->mapbase = base + offset; | 98 | port->port.mapbase = base + offset; |
| 99 | port->membase = priv->remapped_bar[bar] + offset; | 99 | port->port.membase = priv->remapped_bar[bar] + offset; |
| 100 | port->regshift = regshift; | 100 | port->port.regshift = regshift; |
| 101 | } else { | 101 | } else { |
| 102 | port->iotype = UPIO_PORT; | 102 | port->port.iotype = UPIO_PORT; |
| 103 | port->iobase = base + offset; | 103 | port->port.iobase = base + offset; |
| 104 | port->mapbase = 0; | 104 | port->port.mapbase = 0; |
| 105 | port->membase = NULL; | 105 | port->port.membase = NULL; |
| 106 | port->regshift = 0; | 106 | port->port.regshift = 0; |
| 107 | } | 107 | } |
| 108 | return 0; | 108 | return 0; |
| 109 | } | 109 | } |
| @@ -113,7 +113,7 @@ setup_port(struct serial_private *priv, struct uart_port *port, | |||
| 113 | */ | 113 | */ |
| 114 | static int addidata_apci7800_setup(struct serial_private *priv, | 114 | static int addidata_apci7800_setup(struct serial_private *priv, |
| 115 | const struct pciserial_board *board, | 115 | const struct pciserial_board *board, |
| 116 | struct uart_port *port, int idx) | 116 | struct uart_8250_port *port, int idx) |
| 117 | { | 117 | { |
| 118 | unsigned int bar = 0, offset = board->first_offset; | 118 | unsigned int bar = 0, offset = board->first_offset; |
| 119 | bar = FL_GET_BASE(board->flags); | 119 | bar = FL_GET_BASE(board->flags); |
| @@ -140,7 +140,7 @@ static int addidata_apci7800_setup(struct serial_private *priv, | |||
| 140 | */ | 140 | */ |
| 141 | static int | 141 | static int |
| 142 | afavlab_setup(struct serial_private *priv, const struct pciserial_board *board, | 142 | afavlab_setup(struct serial_private *priv, const struct pciserial_board *board, |
| 143 | struct uart_port *port, int idx) | 143 | struct uart_8250_port *port, int idx) |
| 144 | { | 144 | { |
| 145 | unsigned int bar, offset = board->first_offset; | 145 | unsigned int bar, offset = board->first_offset; |
| 146 | 146 | ||
| @@ -195,7 +195,7 @@ static int pci_hp_diva_init(struct pci_dev *dev) | |||
| 195 | static int | 195 | static int |
| 196 | pci_hp_diva_setup(struct serial_private *priv, | 196 | pci_hp_diva_setup(struct serial_private *priv, |
| 197 | const struct pciserial_board *board, | 197 | const struct pciserial_board *board, |
| 198 | struct uart_port *port, int idx) | 198 | struct uart_8250_port *port, int idx) |
| 199 | { | 199 | { |
| 200 | unsigned int offset = board->first_offset; | 200 | unsigned int offset = board->first_offset; |
| 201 | unsigned int bar = FL_GET_BASE(board->flags); | 201 | unsigned int bar = FL_GET_BASE(board->flags); |
| @@ -370,7 +370,7 @@ static void __devexit pci_ni8430_exit(struct pci_dev *dev) | |||
| 370 | /* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */ | 370 | /* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */ |
| 371 | static int | 371 | static int |
| 372 | sbs_setup(struct serial_private *priv, const struct pciserial_board *board, | 372 | sbs_setup(struct serial_private *priv, const struct pciserial_board *board, |
| 373 | struct uart_port *port, int idx) | 373 | struct uart_8250_port *port, int idx) |
| 374 | { | 374 | { |
| 375 | unsigned int bar, offset = board->first_offset; | 375 | unsigned int bar, offset = board->first_offset; |
| 376 | 376 | ||
| @@ -525,7 +525,7 @@ static int pci_siig_init(struct pci_dev *dev) | |||
| 525 | 525 | ||
| 526 | static int pci_siig_setup(struct serial_private *priv, | 526 | static int pci_siig_setup(struct serial_private *priv, |
| 527 | const struct pciserial_board *board, | 527 | const struct pciserial_board *board, |
| 528 | struct uart_port *port, int idx) | 528 | struct uart_8250_port *port, int idx) |
| 529 | { | 529 | { |
| 530 | unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0; | 530 | unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0; |
| 531 | 531 | ||
| @@ -619,7 +619,7 @@ static int pci_timedia_init(struct pci_dev *dev) | |||
| 619 | static int | 619 | static int |
| 620 | pci_timedia_setup(struct serial_private *priv, | 620 | pci_timedia_setup(struct serial_private *priv, |
| 621 | const struct pciserial_board *board, | 621 | const struct pciserial_board *board, |
| 622 | struct uart_port *port, int idx) | 622 | struct uart_8250_port *port, int idx) |
| 623 | { | 623 | { |
| 624 | unsigned int bar = 0, offset = board->first_offset; | 624 | unsigned int bar = 0, offset = board->first_offset; |
| 625 | 625 | ||
| @@ -653,7 +653,7 @@ pci_timedia_setup(struct serial_private *priv, | |||
| 653 | static int | 653 | static int |
| 654 | titan_400l_800l_setup(struct serial_private *priv, | 654 | titan_400l_800l_setup(struct serial_private *priv, |
| 655 | const struct pciserial_board *board, | 655 | const struct pciserial_board *board, |
| 656 | struct uart_port *port, int idx) | 656 | struct uart_8250_port *port, int idx) |
| 657 | { | 657 | { |
| 658 | unsigned int bar, offset = board->first_offset; | 658 | unsigned int bar, offset = board->first_offset; |
| 659 | 659 | ||
| @@ -754,7 +754,7 @@ static int pci_ni8430_init(struct pci_dev *dev) | |||
| 754 | static int | 754 | static int |
| 755 | pci_ni8430_setup(struct serial_private *priv, | 755 | pci_ni8430_setup(struct serial_private *priv, |
| 756 | const struct pciserial_board *board, | 756 | const struct pciserial_board *board, |
| 757 | struct uart_port *port, int idx) | 757 | struct uart_8250_port *port, int idx) |
| 758 | { | 758 | { |
| 759 | void __iomem *p; | 759 | void __iomem *p; |
| 760 | unsigned long base, len; | 760 | unsigned long base, len; |
| @@ -781,7 +781,7 @@ pci_ni8430_setup(struct serial_private *priv, | |||
| 781 | 781 | ||
| 782 | static int pci_netmos_9900_setup(struct serial_private *priv, | 782 | static int pci_netmos_9900_setup(struct serial_private *priv, |
| 783 | const struct pciserial_board *board, | 783 | const struct pciserial_board *board, |
| 784 | struct uart_port *port, int idx) | 784 | struct uart_8250_port *port, int idx) |
| 785 | { | 785 | { |
| 786 | unsigned int bar; | 786 | unsigned int bar; |
| 787 | 787 | ||
| @@ -1032,10 +1032,17 @@ static int pci_oxsemi_tornado_init(struct pci_dev *dev) | |||
| 1032 | return number_uarts; | 1032 | return number_uarts; |
| 1033 | } | 1033 | } |
| 1034 | 1034 | ||
| 1035 | static int | 1035 | static int pci_asix_setup(struct serial_private *priv, |
| 1036 | pci_default_setup(struct serial_private *priv, | 1036 | const struct pciserial_board *board, |
| 1037 | struct uart_8250_port *port, int idx) | ||
| 1038 | { | ||
| 1039 | port->bugs |= UART_BUG_PARITY; | ||
| 1040 | return pci_default_setup(priv, board, port, idx); | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | static int pci_default_setup(struct serial_private *priv, | ||
| 1037 | const struct pciserial_board *board, | 1044 | const struct pciserial_board *board, |
| 1038 | struct uart_port *port, int idx) | 1045 | struct uart_8250_port *port, int idx) |
| 1039 | { | 1046 | { |
| 1040 | unsigned int bar, offset = board->first_offset, maxnr; | 1047 | unsigned int bar, offset = board->first_offset, maxnr; |
| 1041 | 1048 | ||
| @@ -1057,15 +1064,15 @@ pci_default_setup(struct serial_private *priv, | |||
| 1057 | static int | 1064 | static int |
| 1058 | ce4100_serial_setup(struct serial_private *priv, | 1065 | ce4100_serial_setup(struct serial_private *priv, |
| 1059 | const struct pciserial_board *board, | 1066 | const struct pciserial_board *board, |
| 1060 | struct uart_port *port, int idx) | 1067 | struct uart_8250_port *port, int idx) |
| 1061 | { | 1068 | { |
| 1062 | int ret; | 1069 | int ret; |
| 1063 | 1070 | ||
| 1064 | ret = setup_port(priv, port, 0, 0, board->reg_shift); | 1071 | ret = setup_port(priv, port, 0, 0, board->reg_shift); |
| 1065 | port->iotype = UPIO_MEM32; | 1072 | port->port.iotype = UPIO_MEM32; |
| 1066 | port->type = PORT_XSCALE; | 1073 | port->port.type = PORT_XSCALE; |
| 1067 | port->flags = (port->flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); | 1074 | port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); |
| 1068 | port->regshift = 2; | 1075 | port->port.regshift = 2; |
| 1069 | 1076 | ||
| 1070 | return ret; | 1077 | return ret; |
| 1071 | } | 1078 | } |
| @@ -1073,16 +1080,16 @@ ce4100_serial_setup(struct serial_private *priv, | |||
| 1073 | static int | 1080 | static int |
| 1074 | pci_omegapci_setup(struct serial_private *priv, | 1081 | pci_omegapci_setup(struct serial_private *priv, |
| 1075 | const struct pciserial_board *board, | 1082 | const struct pciserial_board *board, |
| 1076 | struct uart_port *port, int idx) | 1083 | struct uart_8250_port *port, int idx) |
| 1077 | { | 1084 | { |
| 1078 | return setup_port(priv, port, 2, idx * 8, 0); | 1085 | return setup_port(priv, port, 2, idx * 8, 0); |
| 1079 | } | 1086 | } |
| 1080 | 1087 | ||
| 1081 | static int skip_tx_en_setup(struct serial_private *priv, | 1088 | static int skip_tx_en_setup(struct serial_private *priv, |
| 1082 | const struct pciserial_board *board, | 1089 | const struct pciserial_board *board, |
| 1083 | struct uart_port *port, int idx) | 1090 | struct uart_8250_port *port, int idx) |
| 1084 | { | 1091 | { |
| 1085 | port->flags |= UPF_NO_TXEN_TEST; | 1092 | port->port.flags |= UPF_NO_TXEN_TEST; |
| 1086 | printk(KERN_DEBUG "serial8250: skipping TxEn test for device " | 1093 | printk(KERN_DEBUG "serial8250: skipping TxEn test for device " |
| 1087 | "[%04x:%04x] subsystem [%04x:%04x]\n", | 1094 | "[%04x:%04x] subsystem [%04x:%04x]\n", |
| 1088 | priv->dev->vendor, | 1095 | priv->dev->vendor, |
| @@ -1131,11 +1138,11 @@ static unsigned int kt_serial_in(struct uart_port *p, int offset) | |||
| 1131 | 1138 | ||
| 1132 | static int kt_serial_setup(struct serial_private *priv, | 1139 | static int kt_serial_setup(struct serial_private *priv, |
| 1133 | const struct pciserial_board *board, | 1140 | const struct pciserial_board *board, |
| 1134 | struct uart_port *port, int idx) | 1141 | struct uart_8250_port *port, int idx) |
| 1135 | { | 1142 | { |
| 1136 | port->flags |= UPF_BUG_THRE; | 1143 | port->port.flags |= UPF_BUG_THRE; |
| 1137 | port->serial_in = kt_serial_in; | 1144 | port->port.serial_in = kt_serial_in; |
| 1138 | port->handle_break = kt_handle_break; | 1145 | port->port.handle_break = kt_handle_break; |
| 1139 | return skip_tx_en_setup(priv, board, port, idx); | 1146 | return skip_tx_en_setup(priv, board, port, idx); |
| 1140 | } | 1147 | } |
| 1141 | 1148 | ||
| @@ -1151,9 +1158,19 @@ static int pci_eg20t_init(struct pci_dev *dev) | |||
| 1151 | static int | 1158 | static int |
| 1152 | pci_xr17c154_setup(struct serial_private *priv, | 1159 | pci_xr17c154_setup(struct serial_private *priv, |
| 1153 | const struct pciserial_board *board, | 1160 | const struct pciserial_board *board, |
| 1154 | struct uart_port *port, int idx) | 1161 | struct uart_8250_port *port, int idx) |
| 1155 | { | 1162 | { |
| 1156 | port->flags |= UPF_EXAR_EFR; | 1163 | port->port.flags |= UPF_EXAR_EFR; |
| 1164 | return pci_default_setup(priv, board, port, idx); | ||
| 1165 | } | ||
| 1166 | |||
| 1167 | static int | ||
| 1168 | pci_wch_ch353_setup(struct serial_private *priv, | ||
| 1169 | const struct pciserial_board *board, | ||
| 1170 | struct uart_8250_port *port, int idx) | ||
| 1171 | { | ||
| 1172 | port->port.flags |= UPF_FIXED_TYPE; | ||
| 1173 | port->port.type = PORT_16550A; | ||
| 1157 | return pci_default_setup(priv, board, port, idx); | 1174 | return pci_default_setup(priv, board, port, idx); |
| 1158 | } | 1175 | } |
| 1159 | 1176 | ||
| @@ -1164,6 +1181,8 @@ pci_xr17c154_setup(struct serial_private *priv, | |||
| 1164 | #define PCI_SUBDEVICE_ID_OCTPRO422 0x0208 | 1181 | #define PCI_SUBDEVICE_ID_OCTPRO422 0x0208 |
| 1165 | #define PCI_SUBDEVICE_ID_POCTAL232 0x0308 | 1182 | #define PCI_SUBDEVICE_ID_POCTAL232 0x0308 |
| 1166 | #define PCI_SUBDEVICE_ID_POCTAL422 0x0408 | 1183 | #define PCI_SUBDEVICE_ID_POCTAL422 0x0408 |
| 1184 | #define PCI_SUBDEVICE_ID_SIIG_DUAL_00 0x2500 | ||
| 1185 | #define PCI_SUBDEVICE_ID_SIIG_DUAL_30 0x2530 | ||
| 1167 | #define PCI_VENDOR_ID_ADVANTECH 0x13fe | 1186 | #define PCI_VENDOR_ID_ADVANTECH 0x13fe |
| 1168 | #define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66 | 1187 | #define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66 |
| 1169 | #define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 | 1188 | #define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 |
| @@ -1187,6 +1206,13 @@ pci_xr17c154_setup(struct serial_private *priv, | |||
| 1187 | #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 | 1206 | #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 |
| 1188 | #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 | 1207 | #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 |
| 1189 | #define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d | 1208 | #define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d |
| 1209 | #define PCI_VENDOR_ID_WCH 0x4348 | ||
| 1210 | #define PCI_DEVICE_ID_WCH_CH353_4S 0x3453 | ||
| 1211 | #define PCI_DEVICE_ID_WCH_CH353_2S1PF 0x5046 | ||
| 1212 | #define PCI_DEVICE_ID_WCH_CH353_2S1P 0x7053 | ||
| 1213 | #define PCI_VENDOR_ID_AGESTAR 0x5372 | ||
| 1214 | #define PCI_DEVICE_ID_AGESTAR_9375 0x6872 | ||
| 1215 | #define PCI_VENDOR_ID_ASIX 0x9710 | ||
| 1190 | 1216 | ||
| 1191 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ | 1217 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
| 1192 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 | 1218 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
| @@ -1726,7 +1752,41 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
| 1726 | .subvendor = PCI_ANY_ID, | 1752 | .subvendor = PCI_ANY_ID, |
| 1727 | .subdevice = PCI_ANY_ID, | 1753 | .subdevice = PCI_ANY_ID, |
| 1728 | .setup = pci_omegapci_setup, | 1754 | .setup = pci_omegapci_setup, |
| 1729 | }, | 1755 | }, |
| 1756 | /* WCH CH353 2S1P card (16550 clone) */ | ||
| 1757 | { | ||
| 1758 | .vendor = PCI_VENDOR_ID_WCH, | ||
| 1759 | .device = PCI_DEVICE_ID_WCH_CH353_2S1P, | ||
| 1760 | .subvendor = PCI_ANY_ID, | ||
| 1761 | .subdevice = PCI_ANY_ID, | ||
| 1762 | .setup = pci_wch_ch353_setup, | ||
| 1763 | }, | ||
| 1764 | /* WCH CH353 4S card (16550 clone) */ | ||
| 1765 | { | ||
| 1766 | .vendor = PCI_VENDOR_ID_WCH, | ||
| 1767 | .device = PCI_DEVICE_ID_WCH_CH353_4S, | ||
| 1768 | .subvendor = PCI_ANY_ID, | ||
| 1769 | .subdevice = PCI_ANY_ID, | ||
| 1770 | .setup = pci_wch_ch353_setup, | ||
| 1771 | }, | ||
| 1772 | /* WCH CH353 2S1PF card (16550 clone) */ | ||
| 1773 | { | ||
| 1774 | .vendor = PCI_VENDOR_ID_WCH, | ||
| 1775 | .device = PCI_DEVICE_ID_WCH_CH353_2S1PF, | ||
| 1776 | .subvendor = PCI_ANY_ID, | ||
| 1777 | .subdevice = PCI_ANY_ID, | ||
| 1778 | .setup = pci_wch_ch353_setup, | ||
| 1779 | }, | ||
| 1780 | /* | ||
| 1781 | * ASIX devices with FIFO bug | ||
| 1782 | */ | ||
| 1783 | { | ||
| 1784 | .vendor = PCI_VENDOR_ID_ASIX, | ||
| 1785 | .device = PCI_ANY_ID, | ||
| 1786 | .subvendor = PCI_ANY_ID, | ||
| 1787 | .subdevice = PCI_ANY_ID, | ||
| 1788 | .setup = pci_asix_setup, | ||
| 1789 | }, | ||
| 1730 | /* | 1790 | /* |
| 1731 | * Default "match everything" terminator entry | 1791 | * Default "match everything" terminator entry |
| 1732 | */ | 1792 | */ |
| @@ -1887,7 +1947,6 @@ enum pci_board_num_t { | |||
| 1887 | pbn_panacom, | 1947 | pbn_panacom, |
| 1888 | pbn_panacom2, | 1948 | pbn_panacom2, |
| 1889 | pbn_panacom4, | 1949 | pbn_panacom4, |
| 1890 | pbn_exsys_4055, | ||
| 1891 | pbn_plx_romulus, | 1950 | pbn_plx_romulus, |
| 1892 | pbn_oxsemi, | 1951 | pbn_oxsemi, |
| 1893 | pbn_oxsemi_1_4000000, | 1952 | pbn_oxsemi_1_4000000, |
| @@ -2393,13 +2452,6 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
| 2393 | .reg_shift = 7, | 2452 | .reg_shift = 7, |
| 2394 | }, | 2453 | }, |
| 2395 | 2454 | ||
| 2396 | [pbn_exsys_4055] = { | ||
| 2397 | .flags = FL_BASE2, | ||
| 2398 | .num_ports = 4, | ||
| 2399 | .base_baud = 115200, | ||
| 2400 | .uart_offset = 8, | ||
| 2401 | }, | ||
| 2402 | |||
| 2403 | /* I think this entry is broken - the first_offset looks wrong --rmk */ | 2455 | /* I think this entry is broken - the first_offset looks wrong --rmk */ |
| 2404 | [pbn_plx_romulus] = { | 2456 | [pbn_plx_romulus] = { |
| 2405 | .flags = FL_BASE2, | 2457 | .flags = FL_BASE2, |
| @@ -2624,10 +2676,14 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
| 2624 | }, | 2676 | }, |
| 2625 | }; | 2677 | }; |
| 2626 | 2678 | ||
| 2627 | static const struct pci_device_id softmodem_blacklist[] = { | 2679 | static const struct pci_device_id blacklist[] = { |
| 2680 | /* softmodems */ | ||
| 2628 | { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */ | 2681 | { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */ |
| 2629 | { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */ | 2682 | { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */ |
| 2630 | { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */ | 2683 | { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */ |
| 2684 | |||
| 2685 | /* multi-io cards handled by parport_serial */ | ||
| 2686 | { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ | ||
| 2631 | }; | 2687 | }; |
| 2632 | 2688 | ||
| 2633 | /* | 2689 | /* |
| @@ -2638,7 +2694,7 @@ static const struct pci_device_id softmodem_blacklist[] = { | |||
| 2638 | static int __devinit | 2694 | static int __devinit |
| 2639 | serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) | 2695 | serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) |
| 2640 | { | 2696 | { |
| 2641 | const struct pci_device_id *blacklist; | 2697 | const struct pci_device_id *bldev; |
| 2642 | int num_iomem, num_port, first_port = -1, i; | 2698 | int num_iomem, num_port, first_port = -1, i; |
| 2643 | 2699 | ||
| 2644 | /* | 2700 | /* |
| @@ -2655,13 +2711,13 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) | |||
| 2655 | 2711 | ||
| 2656 | /* | 2712 | /* |
| 2657 | * Do not access blacklisted devices that are known not to | 2713 | * Do not access blacklisted devices that are known not to |
| 2658 | * feature serial ports. | 2714 | * feature serial ports or are handled by other modules. |
| 2659 | */ | 2715 | */ |
| 2660 | for (blacklist = softmodem_blacklist; | 2716 | for (bldev = blacklist; |
| 2661 | blacklist < softmodem_blacklist + ARRAY_SIZE(softmodem_blacklist); | 2717 | bldev < blacklist + ARRAY_SIZE(blacklist); |
| 2662 | blacklist++) { | 2718 | bldev++) { |
| 2663 | if (dev->vendor == blacklist->vendor && | 2719 | if (dev->vendor == bldev->vendor && |
| 2664 | dev->device == blacklist->device) | 2720 | dev->device == bldev->device) |
| 2665 | return -ENODEV; | 2721 | return -ENODEV; |
| 2666 | } | 2722 | } |
| 2667 | 2723 | ||
| @@ -2728,7 +2784,7 @@ serial_pci_matches(const struct pciserial_board *board, | |||
| 2728 | struct serial_private * | 2784 | struct serial_private * |
| 2729 | pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) | 2785 | pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) |
| 2730 | { | 2786 | { |
| 2731 | struct uart_port serial_port; | 2787 | struct uart_8250_port uart; |
| 2732 | struct serial_private *priv; | 2788 | struct serial_private *priv; |
| 2733 | struct pci_serial_quirk *quirk; | 2789 | struct pci_serial_quirk *quirk; |
| 2734 | int rc, nr_ports, i; | 2790 | int rc, nr_ports, i; |
| @@ -2768,22 +2824,22 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) | |||
| 2768 | priv->dev = dev; | 2824 | priv->dev = dev; |
| 2769 | priv->quirk = quirk; | 2825 | priv->quirk = quirk; |
| 2770 | 2826 | ||
| 2771 | memset(&serial_port, 0, sizeof(struct uart_port)); | 2827 | memset(&uart, 0, sizeof(uart)); |
| 2772 | serial_port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; | 2828 | uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; |
| 2773 | serial_port.uartclk = board->base_baud * 16; | 2829 | uart.port.uartclk = board->base_baud * 16; |
| 2774 | serial_port.irq = get_pci_irq(dev, board); | 2830 | uart.port.irq = get_pci_irq(dev, board); |
| 2775 | serial_port.dev = &dev->dev; | 2831 | uart.port.dev = &dev->dev; |
| 2776 | 2832 | ||
| 2777 | for (i = 0; i < nr_ports; i++) { | 2833 | for (i = 0; i < nr_ports; i++) { |
| 2778 | if (quirk->setup(priv, board, &serial_port, i)) | 2834 | if (quirk->setup(priv, board, &uart, i)) |
| 2779 | break; | 2835 | break; |
| 2780 | 2836 | ||
| 2781 | #ifdef SERIAL_DEBUG_PCI | 2837 | #ifdef SERIAL_DEBUG_PCI |
| 2782 | printk(KERN_DEBUG "Setup PCI port: port %lx, irq %d, type %d\n", | 2838 | printk(KERN_DEBUG "Setup PCI port: port %lx, irq %d, type %d\n", |
| 2783 | serial_port.iobase, serial_port.irq, serial_port.iotype); | 2839 | uart.port.iobase, uart.port.irq, uart.port.iotype); |
| 2784 | #endif | 2840 | #endif |
| 2785 | 2841 | ||
| 2786 | priv->line[i] = serial8250_register_port(&serial_port); | 2842 | priv->line[i] = serial8250_register_8250_port(&uart); |
| 2787 | if (priv->line[i] < 0) { | 2843 | if (priv->line[i] < 0) { |
| 2788 | printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]); | 2844 | printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]); |
| 2789 | break; | 2845 | break; |
| @@ -3193,7 +3249,7 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
| 3193 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, | 3249 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, |
| 3194 | PCI_SUBVENDOR_ID_EXSYS, | 3250 | PCI_SUBVENDOR_ID_EXSYS, |
| 3195 | PCI_SUBDEVICE_ID_EXSYS_4055, 0, 0, | 3251 | PCI_SUBDEVICE_ID_EXSYS_4055, 0, 0, |
| 3196 | pbn_exsys_4055 }, | 3252 | pbn_b2_4_115200 }, |
| 3197 | /* | 3253 | /* |
| 3198 | * Megawolf Romulus PCI Serial Card, from Mike Hudson | 3254 | * Megawolf Romulus PCI Serial Card, from Mike Hudson |
| 3199 | * (Exoray@isys.ca) | 3255 | * (Exoray@isys.ca) |
| @@ -3232,8 +3288,11 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
| 3232 | * For now just used the hex ID 0x950a. | 3288 | * For now just used the hex ID 0x950a. |
| 3233 | */ | 3289 | */ |
| 3234 | { PCI_VENDOR_ID_OXSEMI, 0x950a, | 3290 | { PCI_VENDOR_ID_OXSEMI, 0x950a, |
| 3235 | PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_SERIAL, 0, 0, | 3291 | PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_00, |
| 3236 | pbn_b0_2_115200 }, | 3292 | 0, 0, pbn_b0_2_115200 }, |
| 3293 | { PCI_VENDOR_ID_OXSEMI, 0x950a, | ||
| 3294 | PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_30, | ||
| 3295 | 0, 0, pbn_b0_2_115200 }, | ||
| 3237 | { PCI_VENDOR_ID_OXSEMI, 0x950a, | 3296 | { PCI_VENDOR_ID_OXSEMI, 0x950a, |
| 3238 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3297 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
| 3239 | pbn_b0_2_1130000 }, | 3298 | pbn_b0_2_1130000 }, |
| @@ -4179,6 +4238,25 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
| 4179 | pbn_omegapci }, | 4238 | pbn_omegapci }, |
| 4180 | 4239 | ||
| 4181 | /* | 4240 | /* |
| 4241 | * AgeStar as-prs2-009 | ||
| 4242 | */ | ||
| 4243 | { PCI_VENDOR_ID_AGESTAR, PCI_DEVICE_ID_AGESTAR_9375, | ||
| 4244 | PCI_ANY_ID, PCI_ANY_ID, | ||
| 4245 | 0, 0, pbn_b0_bt_2_115200 }, | ||
| 4246 | |||
| 4247 | /* | ||
| 4248 | * WCH CH353 series devices: The 2S1P is handled by parport_serial | ||
| 4249 | * so not listed here. | ||
| 4250 | */ | ||
| 4251 | { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH353_4S, | ||
| 4252 | PCI_ANY_ID, PCI_ANY_ID, | ||
| 4253 | 0, 0, pbn_b0_bt_4_115200 }, | ||
| 4254 | |||
| 4255 | { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH353_2S1PF, | ||
| 4256 | PCI_ANY_ID, PCI_ANY_ID, | ||
| 4257 | 0, 0, pbn_b0_bt_2_115200 }, | ||
| 4258 | |||
| 4259 | /* | ||
| 4182 | * These entries match devices with class COMMUNICATION_SERIAL, | 4260 | * These entries match devices with class COMMUNICATION_SERIAL, |
| 4183 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL | 4261 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL |
| 4184 | */ | 4262 | */ |
diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c index a2f236510ff1..f8ee25001dd0 100644 --- a/drivers/tty/serial/8250/8250_pnp.c +++ b/drivers/tty/serial/8250/8250_pnp.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Probe module for 8250/16550-type ISAPNP serial ports. | 2 | * Probe for 8250/16550-type ISAPNP serial ports. |
| 3 | * | 3 | * |
| 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 4 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. |
| 5 | * | 5 | * |
| @@ -25,7 +25,7 @@ | |||
| 25 | #include "8250.h" | 25 | #include "8250.h" |
| 26 | 26 | ||
| 27 | #define UNKNOWN_DEV 0x3000 | 27 | #define UNKNOWN_DEV 0x3000 |
| 28 | 28 | #define CIR_PORT 0x0800 | |
| 29 | 29 | ||
| 30 | static const struct pnp_device_id pnp_dev_table[] = { | 30 | static const struct pnp_device_id pnp_dev_table[] = { |
| 31 | /* Archtek America Corp. */ | 31 | /* Archtek America Corp. */ |
| @@ -362,6 +362,9 @@ static const struct pnp_device_id pnp_dev_table[] = { | |||
| 362 | { "PNPCXXX", UNKNOWN_DEV }, | 362 | { "PNPCXXX", UNKNOWN_DEV }, |
| 363 | /* More unknown PnP modems */ | 363 | /* More unknown PnP modems */ |
| 364 | { "PNPDXXX", UNKNOWN_DEV }, | 364 | { "PNPDXXX", UNKNOWN_DEV }, |
| 365 | /* Winbond CIR port, should not be probed. We should keep track | ||
| 366 | of it to prevent the legacy serial driver from probing it */ | ||
| 367 | { "WEC1022", CIR_PORT }, | ||
| 365 | { "", 0 } | 368 | { "", 0 } |
| 366 | }; | 369 | }; |
| 367 | 370 | ||
| @@ -409,7 +412,7 @@ static int __devinit check_resources(struct pnp_dev *dev) | |||
| 409 | * PnP modems, alternatively we must hardcode all modems in pnp_devices[] | 412 | * PnP modems, alternatively we must hardcode all modems in pnp_devices[] |
| 410 | * table. | 413 | * table. |
| 411 | */ | 414 | */ |
| 412 | static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags) | 415 | static int __devinit serial_pnp_guess_board(struct pnp_dev *dev) |
| 413 | { | 416 | { |
| 414 | if (!(check_name(pnp_dev_name(dev)) || | 417 | if (!(check_name(pnp_dev_name(dev)) || |
| 415 | (dev->card && check_name(dev->card->name)))) | 418 | (dev->card && check_name(dev->card->name)))) |
| @@ -424,42 +427,49 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags) | |||
| 424 | static int __devinit | 427 | static int __devinit |
| 425 | serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | 428 | serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) |
| 426 | { | 429 | { |
| 427 | struct uart_port port; | 430 | struct uart_8250_port uart; |
| 428 | int ret, line, flags = dev_id->driver_data; | 431 | int ret, line, flags = dev_id->driver_data; |
| 429 | 432 | ||
| 430 | if (flags & UNKNOWN_DEV) { | 433 | if (flags & UNKNOWN_DEV) { |
| 431 | ret = serial_pnp_guess_board(dev, &flags); | 434 | ret = serial_pnp_guess_board(dev); |
| 432 | if (ret < 0) | 435 | if (ret < 0) |
| 433 | return ret; | 436 | return ret; |
| 434 | } | 437 | } |
| 435 | 438 | ||
| 436 | memset(&port, 0, sizeof(struct uart_port)); | 439 | memset(&uart, 0, sizeof(uart)); |
| 437 | if (pnp_irq_valid(dev, 0)) | 440 | if (pnp_irq_valid(dev, 0)) |
| 438 | port.irq = pnp_irq(dev, 0); | 441 | uart.port.irq = pnp_irq(dev, 0); |
| 439 | if (pnp_port_valid(dev, 0)) { | 442 | if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) { |
| 440 | port.iobase = pnp_port_start(dev, 0); | 443 | uart.port.iobase = pnp_port_start(dev, 2); |
| 441 | port.iotype = UPIO_PORT; | 444 | uart.port.iotype = UPIO_PORT; |
| 445 | } else if (pnp_port_valid(dev, 0)) { | ||
| 446 | uart.port.iobase = pnp_port_start(dev, 0); | ||
| 447 | uart.port.iotype = UPIO_PORT; | ||
| 442 | } else if (pnp_mem_valid(dev, 0)) { | 448 | } else if (pnp_mem_valid(dev, 0)) { |
| 443 | port.mapbase = pnp_mem_start(dev, 0); | 449 | uart.port.mapbase = pnp_mem_start(dev, 0); |
| 444 | port.iotype = UPIO_MEM; | 450 | uart.port.iotype = UPIO_MEM; |
| 445 | port.flags = UPF_IOREMAP; | 451 | uart.port.flags = UPF_IOREMAP; |
| 446 | } else | 452 | } else |
| 447 | return -ENODEV; | 453 | return -ENODEV; |
| 448 | 454 | ||
| 449 | #ifdef SERIAL_DEBUG_PNP | 455 | #ifdef SERIAL_DEBUG_PNP |
| 450 | printk(KERN_DEBUG | 456 | printk(KERN_DEBUG |
| 451 | "Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n", | 457 | "Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n", |
| 452 | port.iobase, port.mapbase, port.irq, port.iotype); | 458 | uart.port.iobase, uart.port.mapbase, uart.port.irq, uart.port.iotype); |
| 453 | #endif | 459 | #endif |
| 460 | if (flags & CIR_PORT) { | ||
| 461 | uart.port.flags |= UPF_FIXED_PORT | UPF_FIXED_TYPE; | ||
| 462 | uart.port.type = PORT_8250_CIR; | ||
| 463 | } | ||
| 454 | 464 | ||
| 455 | port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; | 465 | uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; |
| 456 | if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) | 466 | if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) |
| 457 | port.flags |= UPF_SHARE_IRQ; | 467 | uart.port.flags |= UPF_SHARE_IRQ; |
| 458 | port.uartclk = 1843200; | 468 | uart.port.uartclk = 1843200; |
| 459 | port.dev = &dev->dev; | 469 | uart.port.dev = &dev->dev; |
| 460 | 470 | ||
| 461 | line = serial8250_register_port(&port); | 471 | line = serial8250_register_8250_port(&uart); |
| 462 | if (line < 0) | 472 | if (line < 0 || (flags & CIR_PORT)) |
| 463 | return -ENODEV; | 473 | return -ENODEV; |
| 464 | 474 | ||
| 465 | pnp_set_drvdata(dev, (void *)((long)line + 1)); | 475 | pnp_set_drvdata(dev, (void *)((long)line + 1)); |
| @@ -507,18 +517,13 @@ static struct pnp_driver serial_pnp_driver = { | |||
| 507 | .id_table = pnp_dev_table, | 517 | .id_table = pnp_dev_table, |
| 508 | }; | 518 | }; |
| 509 | 519 | ||
| 510 | static int __init serial8250_pnp_init(void) | 520 | int serial8250_pnp_init(void) |
| 511 | { | 521 | { |
| 512 | return pnp_register_driver(&serial_pnp_driver); | 522 | return pnp_register_driver(&serial_pnp_driver); |
| 513 | } | 523 | } |
| 514 | 524 | ||
| 515 | static void __exit serial8250_pnp_exit(void) | 525 | void serial8250_pnp_exit(void) |
| 516 | { | 526 | { |
| 517 | pnp_unregister_driver(&serial_pnp_driver); | 527 | pnp_unregister_driver(&serial_pnp_driver); |
| 518 | } | 528 | } |
| 519 | 529 | ||
| 520 | module_init(serial8250_pnp_init); | ||
| 521 | module_exit(serial8250_pnp_exit); | ||
| 522 | |||
| 523 | MODULE_LICENSE("GPL"); | ||
| 524 | MODULE_DESCRIPTION("Generic 8250/16x50 PnP serial driver"); | ||
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index a27dd0569bd7..f3d283f2e3aa 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig | |||
| @@ -33,6 +33,14 @@ config SERIAL_8250 | |||
| 33 | Most people will say Y or M here, so that they can use serial mice, | 33 | Most people will say Y or M here, so that they can use serial mice, |
| 34 | modems and similar devices connecting to the standard serial ports. | 34 | modems and similar devices connecting to the standard serial ports. |
| 35 | 35 | ||
| 36 | config SERIAL_8250_PNP | ||
| 37 | bool "8250/16550 PNP device support" if EXPERT | ||
| 38 | depends on SERIAL_8250 && PNP | ||
| 39 | default y | ||
| 40 | ---help--- | ||
| 41 | This builds standard PNP serial support. You may be able to | ||
| 42 | disable this feature if you only need legacy serial support. | ||
| 43 | |||
| 36 | config SERIAL_8250_CONSOLE | 44 | config SERIAL_8250_CONSOLE |
| 37 | bool "Console on 8250/16550 and compatible serial port" | 45 | bool "Console on 8250/16550 and compatible serial port" |
| 38 | depends on SERIAL_8250=y | 46 | depends on SERIAL_8250=y |
| @@ -85,14 +93,6 @@ config SERIAL_8250_PCI | |||
| 85 | disable this feature if you only need legacy serial support. | 93 | disable this feature if you only need legacy serial support. |
| 86 | Saves about 9K. | 94 | Saves about 9K. |
| 87 | 95 | ||
| 88 | config SERIAL_8250_PNP | ||
| 89 | tristate "8250/16550 PNP device support" if EXPERT | ||
| 90 | depends on SERIAL_8250 && PNP | ||
| 91 | default SERIAL_8250 | ||
| 92 | help | ||
| 93 | This builds standard PNP serial support. You may be able to | ||
| 94 | disable this feature if you only need legacy serial support. | ||
| 95 | |||
| 96 | config SERIAL_8250_HP300 | 96 | config SERIAL_8250_HP300 |
| 97 | tristate | 97 | tristate |
| 98 | depends on SERIAL_8250 && HP300 | 98 | depends on SERIAL_8250 && HP300 |
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index d7533c7d2c1a..108fe7fe13e2 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile | |||
| @@ -2,8 +2,9 @@ | |||
| 2 | # Makefile for the 8250 serial device drivers. | 2 | # Makefile for the 8250 serial device drivers. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-$(CONFIG_SERIAL_8250) += 8250.o | 5 | obj-$(CONFIG_SERIAL_8250) += 8250_core.o |
| 6 | obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o | 6 | 8250_core-y := 8250.o |
| 7 | 8250_core-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o | ||
| 7 | obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o | 8 | obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o |
| 8 | obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o | 9 | obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o |
| 9 | obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o | 10 | obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o |
diff --git a/drivers/tty/serial/8250/serial_cs.c b/drivers/tty/serial/8250/serial_cs.c index 29b695d041ec..b7d48b346393 100644 --- a/drivers/tty/serial/8250/serial_cs.c +++ b/drivers/tty/serial/8250/serial_cs.c | |||
| @@ -73,7 +73,7 @@ struct serial_quirk { | |||
| 73 | unsigned int prodid; | 73 | unsigned int prodid; |
| 74 | int multi; /* 1 = multifunction, > 1 = # ports */ | 74 | int multi; /* 1 = multifunction, > 1 = # ports */ |
| 75 | void (*config)(struct pcmcia_device *); | 75 | void (*config)(struct pcmcia_device *); |
| 76 | void (*setup)(struct pcmcia_device *, struct uart_port *); | 76 | void (*setup)(struct pcmcia_device *, struct uart_8250_port *); |
| 77 | void (*wakeup)(struct pcmcia_device *); | 77 | void (*wakeup)(struct pcmcia_device *); |
| 78 | int (*post)(struct pcmcia_device *); | 78 | int (*post)(struct pcmcia_device *); |
| 79 | }; | 79 | }; |
| @@ -105,9 +105,9 @@ struct serial_cfg_mem { | |||
| 105 | * Elan VPU16551 UART with 14.7456MHz oscillator | 105 | * Elan VPU16551 UART with 14.7456MHz oscillator |
| 106 | * manfid 0x015D, 0x4C45 | 106 | * manfid 0x015D, 0x4C45 |
| 107 | */ | 107 | */ |
| 108 | static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port) | 108 | static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_8250_port *uart) |
| 109 | { | 109 | { |
| 110 | port->uartclk = 14745600; | 110 | uart->port.uartclk = 14745600; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | static int quirk_post_ibm(struct pcmcia_device *link) | 113 | static int quirk_post_ibm(struct pcmcia_device *link) |
| @@ -343,25 +343,25 @@ static void serial_detach(struct pcmcia_device *link) | |||
| 343 | static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, | 343 | static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, |
| 344 | unsigned int iobase, int irq) | 344 | unsigned int iobase, int irq) |
| 345 | { | 345 | { |
| 346 | struct uart_port port; | 346 | struct uart_8250_port uart; |
| 347 | int line; | 347 | int line; |
| 348 | 348 | ||
| 349 | memset(&port, 0, sizeof (struct uart_port)); | 349 | memset(&uart, 0, sizeof(uart)); |
| 350 | port.iobase = iobase; | 350 | uart.port.iobase = iobase; |
| 351 | port.irq = irq; | 351 | uart.port.irq = irq; |
| 352 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; | 352 | uart.port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; |
| 353 | port.uartclk = 1843200; | 353 | uart.port.uartclk = 1843200; |
| 354 | port.dev = &handle->dev; | 354 | uart.port.dev = &handle->dev; |
| 355 | if (buggy_uart) | 355 | if (buggy_uart) |
| 356 | port.flags |= UPF_BUGGY_UART; | 356 | uart.port.flags |= UPF_BUGGY_UART; |
| 357 | 357 | ||
| 358 | if (info->quirk && info->quirk->setup) | 358 | if (info->quirk && info->quirk->setup) |
| 359 | info->quirk->setup(handle, &port); | 359 | info->quirk->setup(handle, &uart); |
| 360 | 360 | ||
| 361 | line = serial8250_register_port(&port); | 361 | line = serial8250_register_8250_port(&uart); |
| 362 | if (line < 0) { | 362 | if (line < 0) { |
| 363 | printk(KERN_NOTICE "serial_cs: serial8250_register_port() at " | 363 | pr_err("serial_cs: serial8250_register_8250_port() at 0x%04lx, irq %d failed\n", |
| 364 | "0x%04lx, irq %d failed\n", (u_long)iobase, irq); | 364 | (unsigned long)iobase, irq); |
| 365 | return -EINVAL; | 365 | return -EINVAL; |
| 366 | } | 366 | } |
| 367 | 367 | ||
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 4720b4ba096a..233fbaaf2559 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
| @@ -141,6 +141,25 @@ config SERIAL_ATMEL_TTYAT | |||
| 141 | 141 | ||
| 142 | Say Y if you have an external 8250/16C550 UART. If unsure, say N. | 142 | Say Y if you have an external 8250/16C550 UART. If unsure, say N. |
| 143 | 143 | ||
| 144 | config SERIAL_KGDB_NMI | ||
| 145 | bool "Serial console over KGDB NMI debugger port" | ||
| 146 | depends on KGDB_SERIAL_CONSOLE | ||
| 147 | help | ||
| 148 | This special driver allows you to temporary use NMI debugger port | ||
| 149 | as a normal console (assuming that the port is attached to KGDB). | ||
| 150 | |||
| 151 | Unlike KDB's disable_nmi command, with this driver you are always | ||
| 152 | able to go back to the debugger using KGDB escape sequence ($3#33). | ||
| 153 | This is because this console driver processes the input in NMI | ||
| 154 | context, and thus is able to intercept the magic sequence. | ||
| 155 | |||
| 156 | Note that since the console interprets input and uses polling | ||
| 157 | communication methods, for things like PPP you still must fully | ||
| 158 | detach debugger port from the KGDB NMI (i.e. disable_nmi), and | ||
| 159 | use raw console. | ||
| 160 | |||
| 161 | If unsure, say N. | ||
| 162 | |||
| 144 | config SERIAL_KS8695 | 163 | config SERIAL_KS8695 |
| 145 | bool "Micrel KS8695 (Centaur) serial port support" | 164 | bool "Micrel KS8695 (Centaur) serial port support" |
| 146 | depends on ARCH_KS8695 | 165 | depends on ARCH_KS8695 |
| @@ -257,12 +276,19 @@ config SERIAL_MAX3100 | |||
| 257 | help | 276 | help |
| 258 | MAX3100 chip support | 277 | MAX3100 chip support |
| 259 | 278 | ||
| 260 | config SERIAL_MAX3107 | 279 | config SERIAL_MAX310X |
| 261 | tristate "MAX3107 support" | 280 | bool "MAX310X support" |
| 262 | depends on SPI | 281 | depends on SPI |
| 263 | select SERIAL_CORE | 282 | select SERIAL_CORE |
| 283 | select REGMAP_SPI if SPI | ||
| 284 | default n | ||
| 264 | help | 285 | help |
| 265 | MAX3107 chip support | 286 | This selects support for an advanced UART from Maxim (Dallas). |
| 287 | Supported ICs are MAX3107, MAX3108. | ||
| 288 | Each IC contains 128 words each of receive and transmit FIFO | ||
| 289 | that can be controlled through I2C or high-speed SPI. | ||
| 290 | |||
| 291 | Say Y here if you want to support this ICs. | ||
| 266 | 292 | ||
| 267 | config SERIAL_DZ | 293 | config SERIAL_DZ |
| 268 | bool "DECstation DZ serial driver" | 294 | bool "DECstation DZ serial driver" |
| @@ -686,7 +712,7 @@ config SERIAL_SH_SCI_CONSOLE | |||
| 686 | 712 | ||
| 687 | config SERIAL_SH_SCI_DMA | 713 | config SERIAL_SH_SCI_DMA |
| 688 | bool "DMA support" | 714 | bool "DMA support" |
| 689 | depends on SERIAL_SH_SCI && SH_DMAE && EXPERIMENTAL | 715 | depends on SERIAL_SH_SCI && SH_DMAE |
| 690 | 716 | ||
| 691 | config SERIAL_PNX8XXX | 717 | config SERIAL_PNX8XXX |
| 692 | bool "Enable PNX8XXX SoCs' UART Support" | 718 | bool "Enable PNX8XXX SoCs' UART Support" |
| @@ -704,6 +730,25 @@ config SERIAL_PNX8XXX_CONSOLE | |||
| 704 | If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330 | 730 | If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330 |
| 705 | and you want to use serial console, say Y. Otherwise, say N. | 731 | and you want to use serial console, say Y. Otherwise, say N. |
| 706 | 732 | ||
| 733 | config SERIAL_HS_LPC32XX | ||
| 734 | tristate "LPC32XX high speed serial port support" | ||
| 735 | depends on ARCH_LPC32XX && OF | ||
| 736 | select SERIAL_CORE | ||
| 737 | help | ||
| 738 | Support for the LPC32XX high speed serial ports (up to 900kbps). | ||
| 739 | Those are UARTs completely different from the Standard UARTs on the | ||
| 740 | LPC32XX SoC. | ||
| 741 | Choose M or Y here to build this driver. | ||
| 742 | |||
| 743 | config SERIAL_HS_LPC32XX_CONSOLE | ||
| 744 | bool "Enable LPC32XX high speed UART serial console" | ||
| 745 | depends on SERIAL_HS_LPC32XX | ||
| 746 | select SERIAL_CORE_CONSOLE | ||
| 747 | help | ||
| 748 | If you would like to be able to use one of the high speed serial | ||
| 749 | ports on the LPC32XX as the console, you can do so by answering | ||
| 750 | Y to this option. | ||
| 751 | |||
| 707 | config SERIAL_CORE | 752 | config SERIAL_CORE |
| 708 | tristate | 753 | tristate |
| 709 | 754 | ||
| @@ -1104,6 +1149,24 @@ config SERIAL_SC26XX_CONSOLE | |||
| 1104 | help | 1149 | help |
| 1105 | Support for Console on SC2681/SC2692 serial ports. | 1150 | Support for Console on SC2681/SC2692 serial ports. |
| 1106 | 1151 | ||
| 1152 | config SERIAL_SCCNXP | ||
| 1153 | bool "SCCNXP serial port support" | ||
| 1154 | depends on !SERIAL_SC26XX | ||
| 1155 | select SERIAL_CORE | ||
| 1156 | default n | ||
| 1157 | help | ||
| 1158 | This selects support for an advanced UART from NXP (Philips). | ||
| 1159 | Supported ICs are SCC2681, SCC2691, SCC2692, SC28L91, SC28L92, | ||
| 1160 | SC28L202, SCC68681 and SCC68692. | ||
| 1161 | Positioned as a replacement for the driver SC26XX. | ||
| 1162 | |||
| 1163 | config SERIAL_SCCNXP_CONSOLE | ||
| 1164 | bool "Console on SCCNXP serial port" | ||
| 1165 | depends on SERIAL_SCCNXP | ||
| 1166 | select SERIAL_CORE_CONSOLE | ||
| 1167 | help | ||
| 1168 | Support for console on SCCNXP serial ports. | ||
| 1169 | |||
| 1107 | config SERIAL_BFIN_SPORT | 1170 | config SERIAL_BFIN_SPORT |
| 1108 | tristate "Blackfin SPORT emulate UART" | 1171 | tristate "Blackfin SPORT emulate UART" |
| 1109 | depends on BLACKFIN | 1172 | depends on BLACKFIN |
| @@ -1260,7 +1323,7 @@ config SERIAL_ALTERA_UART_CONSOLE | |||
| 1260 | 1323 | ||
| 1261 | config SERIAL_IFX6X60 | 1324 | config SERIAL_IFX6X60 |
| 1262 | tristate "SPI protocol driver for Infineon 6x60 modem (EXPERIMENTAL)" | 1325 | tristate "SPI protocol driver for Infineon 6x60 modem (EXPERIMENTAL)" |
| 1263 | depends on GPIOLIB && SPI && EXPERIMENTAL | 1326 | depends on GPIOLIB && SPI |
| 1264 | help | 1327 | help |
| 1265 | Support for the IFX6x60 modem devices on Intel MID platforms. | 1328 | Support for the IFX6x60 modem devices on Intel MID platforms. |
| 1266 | 1329 | ||
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 7257c5d898ae..4f694dafa719 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
| @@ -28,12 +28,13 @@ obj-$(CONFIG_SERIAL_BFIN) += bfin_uart.o | |||
| 28 | obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o | 28 | obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o |
| 29 | obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o | 29 | obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o |
| 30 | obj-$(CONFIG_SERIAL_MAX3100) += max3100.o | 30 | obj-$(CONFIG_SERIAL_MAX3100) += max3100.o |
| 31 | obj-$(CONFIG_SERIAL_MAX3107) += max3107.o | 31 | obj-$(CONFIG_SERIAL_MAX310X) += max310x.o |
| 32 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o | 32 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o |
| 33 | obj-$(CONFIG_SERIAL_MUX) += mux.o | 33 | obj-$(CONFIG_SERIAL_MUX) += mux.o |
| 34 | obj-$(CONFIG_SERIAL_68328) += 68328serial.o | 34 | obj-$(CONFIG_SERIAL_68328) += 68328serial.o |
| 35 | obj-$(CONFIG_SERIAL_MCF) += mcf.o | 35 | obj-$(CONFIG_SERIAL_MCF) += mcf.o |
| 36 | obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o | 36 | obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o |
| 37 | obj-$(CONFIG_SERIAL_HS_LPC32XX) += lpc32xx_hs.o | ||
| 37 | obj-$(CONFIG_SERIAL_DZ) += dz.o | 38 | obj-$(CONFIG_SERIAL_DZ) += dz.o |
| 38 | obj-$(CONFIG_SERIAL_ZS) += zs.o | 39 | obj-$(CONFIG_SERIAL_ZS) += zs.o |
| 39 | obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o | 40 | obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o |
| @@ -47,6 +48,7 @@ obj-$(CONFIG_SERIAL_MPSC) += mpsc.o | |||
| 47 | obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o | 48 | obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o |
| 48 | obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o | 49 | obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o |
| 49 | obj-$(CONFIG_SERIAL_SC26XX) += sc26xx.o | 50 | obj-$(CONFIG_SERIAL_SC26XX) += sc26xx.o |
| 51 | obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o | ||
| 50 | obj-$(CONFIG_SERIAL_JSM) += jsm/ | 52 | obj-$(CONFIG_SERIAL_JSM) += jsm/ |
| 51 | obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o | 53 | obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o |
| 52 | obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o | 54 | obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o |
| @@ -59,6 +61,7 @@ obj-$(CONFIG_SERIAL_MSM_HS) += msm_serial_hs.o | |||
| 59 | obj-$(CONFIG_SERIAL_NETX) += netx-serial.o | 61 | obj-$(CONFIG_SERIAL_NETX) += netx-serial.o |
| 60 | obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o | 62 | obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o |
| 61 | obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o | 63 | obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o |
| 64 | obj-$(CONFIG_SERIAL_KGDB_NMI) += kgdb_nmi.o | ||
| 62 | obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o | 65 | obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o |
| 63 | obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o | 66 | obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o |
| 64 | obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o | 67 | obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o |
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 1f0330915d5a..15d80b9fb303 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c | |||
| @@ -591,7 +591,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) | |||
| 591 | port->ops = &altera_uart_ops; | 591 | port->ops = &altera_uart_ops; |
| 592 | port->flags = UPF_BOOT_AUTOCONF; | 592 | port->flags = UPF_BOOT_AUTOCONF; |
| 593 | 593 | ||
| 594 | dev_set_drvdata(&pdev->dev, port); | 594 | platform_set_drvdata(pdev, port); |
| 595 | 595 | ||
| 596 | uart_add_one_port(&altera_uart_driver, port); | 596 | uart_add_one_port(&altera_uart_driver, port); |
| 597 | 597 | ||
| @@ -600,11 +600,11 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) | |||
| 600 | 600 | ||
| 601 | static int __devexit altera_uart_remove(struct platform_device *pdev) | 601 | static int __devexit altera_uart_remove(struct platform_device *pdev) |
| 602 | { | 602 | { |
| 603 | struct uart_port *port = dev_get_drvdata(&pdev->dev); | 603 | struct uart_port *port = platform_get_drvdata(pdev); |
| 604 | 604 | ||
| 605 | if (port) { | 605 | if (port) { |
| 606 | uart_remove_one_port(&altera_uart_driver, port); | 606 | uart_remove_one_port(&altera_uart_driver, port); |
| 607 | dev_set_drvdata(&pdev->dev, NULL); | 607 | platform_set_drvdata(pdev, NULL); |
| 608 | port->mapbase = 0; | 608 | port->mapbase = 0; |
| 609 | } | 609 | } |
| 610 | 610 | ||
diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index 0d91a540bf11..22317dd16474 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c | |||
| @@ -312,16 +312,12 @@ static int pl010_startup(struct uart_port *port) | |||
| 312 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 312 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
| 313 | int retval; | 313 | int retval; |
| 314 | 314 | ||
| 315 | retval = clk_prepare(uap->clk); | ||
| 316 | if (retval) | ||
| 317 | goto out; | ||
| 318 | |||
| 319 | /* | 315 | /* |
| 320 | * Try to enable the clock producer. | 316 | * Try to enable the clock producer. |
| 321 | */ | 317 | */ |
| 322 | retval = clk_enable(uap->clk); | 318 | retval = clk_prepare_enable(uap->clk); |
| 323 | if (retval) | 319 | if (retval) |
| 324 | goto clk_unprep; | 320 | goto out; |
| 325 | 321 | ||
| 326 | uap->port.uartclk = clk_get_rate(uap->clk); | 322 | uap->port.uartclk = clk_get_rate(uap->clk); |
| 327 | 323 | ||
| @@ -346,9 +342,7 @@ static int pl010_startup(struct uart_port *port) | |||
| 346 | return 0; | 342 | return 0; |
| 347 | 343 | ||
| 348 | clk_dis: | 344 | clk_dis: |
| 349 | clk_disable(uap->clk); | 345 | clk_disable_unprepare(uap->clk); |
| 350 | clk_unprep: | ||
| 351 | clk_unprepare(uap->clk); | ||
| 352 | out: | 346 | out: |
| 353 | return retval; | 347 | return retval; |
| 354 | } | 348 | } |
| @@ -375,8 +369,7 @@ static void pl010_shutdown(struct uart_port *port) | |||
| 375 | /* | 369 | /* |
| 376 | * Shut down the clock producer | 370 | * Shut down the clock producer |
| 377 | */ | 371 | */ |
| 378 | clk_disable(uap->clk); | 372 | clk_disable_unprepare(uap->clk); |
| 379 | clk_unprepare(uap->clk); | ||
| 380 | } | 373 | } |
| 381 | 374 | ||
| 382 | static void | 375 | static void |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d3553b5d3fca..d7e1edec50b5 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
| @@ -52,6 +52,8 @@ | |||
| 52 | #include <linux/scatterlist.h> | 52 | #include <linux/scatterlist.h> |
| 53 | #include <linux/delay.h> | 53 | #include <linux/delay.h> |
| 54 | #include <linux/types.h> | 54 | #include <linux/types.h> |
| 55 | #include <linux/of.h> | ||
| 56 | #include <linux/of_device.h> | ||
| 55 | #include <linux/pinctrl/consumer.h> | 57 | #include <linux/pinctrl/consumer.h> |
| 56 | #include <linux/sizes.h> | 58 | #include <linux/sizes.h> |
| 57 | 59 | ||
| @@ -75,7 +77,6 @@ struct vendor_data { | |||
| 75 | unsigned int lcrh_tx; | 77 | unsigned int lcrh_tx; |
| 76 | unsigned int lcrh_rx; | 78 | unsigned int lcrh_rx; |
| 77 | bool oversampling; | 79 | bool oversampling; |
| 78 | bool interrupt_may_hang; /* vendor-specific */ | ||
| 79 | bool dma_threshold; | 80 | bool dma_threshold; |
| 80 | bool cts_event_workaround; | 81 | bool cts_event_workaround; |
| 81 | }; | 82 | }; |
| @@ -96,7 +97,6 @@ static struct vendor_data vendor_st = { | |||
| 96 | .lcrh_tx = ST_UART011_LCRH_TX, | 97 | .lcrh_tx = ST_UART011_LCRH_TX, |
| 97 | .lcrh_rx = ST_UART011_LCRH_RX, | 98 | .lcrh_rx = ST_UART011_LCRH_RX, |
| 98 | .oversampling = true, | 99 | .oversampling = true, |
| 99 | .interrupt_may_hang = true, | ||
| 100 | .dma_threshold = true, | 100 | .dma_threshold = true, |
| 101 | .cts_event_workaround = true, | 101 | .cts_event_workaround = true, |
| 102 | }; | 102 | }; |
| @@ -147,7 +147,6 @@ struct uart_amba_port { | |||
| 147 | unsigned int old_cr; /* state during shutdown */ | 147 | unsigned int old_cr; /* state during shutdown */ |
| 148 | bool autorts; | 148 | bool autorts; |
| 149 | char type[12]; | 149 | char type[12]; |
| 150 | bool interrupt_may_hang; /* vendor-specific */ | ||
| 151 | #ifdef CONFIG_DMA_ENGINE | 150 | #ifdef CONFIG_DMA_ENGINE |
| 152 | /* DMA stuff */ | 151 | /* DMA stuff */ |
| 153 | bool using_tx_dma; | 152 | bool using_tx_dma; |
| @@ -1215,14 +1214,14 @@ static irqreturn_t pl011_int(int irq, void *dev_id) | |||
| 1215 | return IRQ_RETVAL(handled); | 1214 | return IRQ_RETVAL(handled); |
| 1216 | } | 1215 | } |
| 1217 | 1216 | ||
| 1218 | static unsigned int pl01x_tx_empty(struct uart_port *port) | 1217 | static unsigned int pl011_tx_empty(struct uart_port *port) |
| 1219 | { | 1218 | { |
| 1220 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1219 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
| 1221 | unsigned int status = readw(uap->port.membase + UART01x_FR); | 1220 | unsigned int status = readw(uap->port.membase + UART01x_FR); |
| 1222 | return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT; | 1221 | return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT; |
| 1223 | } | 1222 | } |
| 1224 | 1223 | ||
| 1225 | static unsigned int pl01x_get_mctrl(struct uart_port *port) | 1224 | static unsigned int pl011_get_mctrl(struct uart_port *port) |
| 1226 | { | 1225 | { |
| 1227 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1226 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
| 1228 | unsigned int result = 0; | 1227 | unsigned int result = 0; |
| @@ -1285,11 +1284,40 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) | |||
| 1285 | } | 1284 | } |
| 1286 | 1285 | ||
| 1287 | #ifdef CONFIG_CONSOLE_POLL | 1286 | #ifdef CONFIG_CONSOLE_POLL |
| 1288 | static int pl010_get_poll_char(struct uart_port *port) | 1287 | |
| 1288 | static void pl011_quiesce_irqs(struct uart_port *port) | ||
| 1289 | { | ||
| 1290 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
| 1291 | unsigned char __iomem *regs = uap->port.membase; | ||
| 1292 | |||
| 1293 | writew(readw(regs + UART011_MIS), regs + UART011_ICR); | ||
| 1294 | /* | ||
| 1295 | * There is no way to clear TXIM as this is "ready to transmit IRQ", so | ||
| 1296 | * we simply mask it. start_tx() will unmask it. | ||
| 1297 | * | ||
| 1298 | * Note we can race with start_tx(), and if the race happens, the | ||
| 1299 | * polling user might get another interrupt just after we clear it. | ||
| 1300 | * But it should be OK and can happen even w/o the race, e.g. | ||
| 1301 | * controller immediately got some new data and raised the IRQ. | ||
| 1302 | * | ||
| 1303 | * And whoever uses polling routines assumes that it manages the device | ||
| 1304 | * (including tx queue), so we're also fine with start_tx()'s caller | ||
| 1305 | * side. | ||
| 1306 | */ | ||
| 1307 | writew(readw(regs + UART011_IMSC) & ~UART011_TXIM, regs + UART011_IMSC); | ||
| 1308 | } | ||
| 1309 | |||
| 1310 | static int pl011_get_poll_char(struct uart_port *port) | ||
| 1289 | { | 1311 | { |
| 1290 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1312 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
| 1291 | unsigned int status; | 1313 | unsigned int status; |
| 1292 | 1314 | ||
| 1315 | /* | ||
| 1316 | * The caller might need IRQs lowered, e.g. if used with KDB NMI | ||
| 1317 | * debugger. | ||
| 1318 | */ | ||
| 1319 | pl011_quiesce_irqs(port); | ||
| 1320 | |||
| 1293 | status = readw(uap->port.membase + UART01x_FR); | 1321 | status = readw(uap->port.membase + UART01x_FR); |
| 1294 | if (status & UART01x_FR_RXFE) | 1322 | if (status & UART01x_FR_RXFE) |
| 1295 | return NO_POLL_CHAR; | 1323 | return NO_POLL_CHAR; |
| @@ -1297,7 +1325,7 @@ static int pl010_get_poll_char(struct uart_port *port) | |||
| 1297 | return readw(uap->port.membase + UART01x_DR); | 1325 | return readw(uap->port.membase + UART01x_DR); |
| 1298 | } | 1326 | } |
| 1299 | 1327 | ||
| 1300 | static void pl010_put_poll_char(struct uart_port *port, | 1328 | static void pl011_put_poll_char(struct uart_port *port, |
| 1301 | unsigned char ch) | 1329 | unsigned char ch) |
| 1302 | { | 1330 | { |
| 1303 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1331 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
| @@ -1310,10 +1338,9 @@ static void pl010_put_poll_char(struct uart_port *port, | |||
| 1310 | 1338 | ||
| 1311 | #endif /* CONFIG_CONSOLE_POLL */ | 1339 | #endif /* CONFIG_CONSOLE_POLL */ |
| 1312 | 1340 | ||
| 1313 | static int pl011_startup(struct uart_port *port) | 1341 | static int pl011_hwinit(struct uart_port *port) |
| 1314 | { | 1342 | { |
| 1315 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1343 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
| 1316 | unsigned int cr; | ||
| 1317 | int retval; | 1344 | int retval; |
| 1318 | 1345 | ||
| 1319 | /* Optionaly enable pins to be muxed in and configured */ | 1346 | /* Optionaly enable pins to be muxed in and configured */ |
| @@ -1324,16 +1351,12 @@ static int pl011_startup(struct uart_port *port) | |||
| 1324 | "could not set default pins\n"); | 1351 | "could not set default pins\n"); |
| 1325 | } | 1352 | } |
| 1326 | 1353 | ||
| 1327 | retval = clk_prepare(uap->clk); | ||
| 1328 | if (retval) | ||
| 1329 | goto out; | ||
| 1330 | |||
| 1331 | /* | 1354 | /* |
| 1332 | * Try to enable the clock producer. | 1355 | * Try to enable the clock producer. |
| 1333 | */ | 1356 | */ |
| 1334 | retval = clk_enable(uap->clk); | 1357 | retval = clk_prepare_enable(uap->clk); |
| 1335 | if (retval) | 1358 | if (retval) |
| 1336 | goto clk_unprep; | 1359 | goto out; |
| 1337 | 1360 | ||
| 1338 | uap->port.uartclk = clk_get_rate(uap->clk); | 1361 | uap->port.uartclk = clk_get_rate(uap->clk); |
| 1339 | 1362 | ||
| @@ -1342,6 +1365,37 @@ static int pl011_startup(struct uart_port *port) | |||
| 1342 | UART011_RTIS | UART011_RXIS, uap->port.membase + UART011_ICR); | 1365 | UART011_RTIS | UART011_RXIS, uap->port.membase + UART011_ICR); |
| 1343 | 1366 | ||
| 1344 | /* | 1367 | /* |
| 1368 | * Save interrupts enable mask, and enable RX interrupts in case if | ||
| 1369 | * the interrupt is used for NMI entry. | ||
| 1370 | */ | ||
| 1371 | uap->im = readw(uap->port.membase + UART011_IMSC); | ||
| 1372 | writew(UART011_RTIM | UART011_RXIM, uap->port.membase + UART011_IMSC); | ||
| 1373 | |||
| 1374 | if (uap->port.dev->platform_data) { | ||
| 1375 | struct amba_pl011_data *plat; | ||
| 1376 | |||
| 1377 | plat = uap->port.dev->platform_data; | ||
| 1378 | if (plat->init) | ||
| 1379 | plat->init(); | ||
| 1380 | } | ||
| 1381 | return 0; | ||
| 1382 | out: | ||
| 1383 | return retval; | ||
| 1384 | } | ||
| 1385 | |||
| 1386 | static int pl011_startup(struct uart_port *port) | ||
| 1387 | { | ||
| 1388 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | ||
| 1389 | unsigned int cr; | ||
| 1390 | int retval; | ||
| 1391 | |||
| 1392 | retval = pl011_hwinit(port); | ||
| 1393 | if (retval) | ||
| 1394 | goto clk_dis; | ||
| 1395 | |||
| 1396 | writew(uap->im, uap->port.membase + UART011_IMSC); | ||
| 1397 | |||
| 1398 | /* | ||
| 1345 | * Allocate the IRQ | 1399 | * Allocate the IRQ |
| 1346 | */ | 1400 | */ |
| 1347 | retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap); | 1401 | retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap); |
| @@ -1400,21 +1454,10 @@ static int pl011_startup(struct uart_port *port) | |||
| 1400 | writew(uap->im, uap->port.membase + UART011_IMSC); | 1454 | writew(uap->im, uap->port.membase + UART011_IMSC); |
| 1401 | spin_unlock_irq(&uap->port.lock); | 1455 | spin_unlock_irq(&uap->port.lock); |
| 1402 | 1456 | ||
| 1403 | if (uap->port.dev->platform_data) { | ||
| 1404 | struct amba_pl011_data *plat; | ||
| 1405 | |||
| 1406 | plat = uap->port.dev->platform_data; | ||
| 1407 | if (plat->init) | ||
| 1408 | plat->init(); | ||
| 1409 | } | ||
| 1410 | |||
| 1411 | return 0; | 1457 | return 0; |
| 1412 | 1458 | ||
| 1413 | clk_dis: | 1459 | clk_dis: |
| 1414 | clk_disable(uap->clk); | 1460 | clk_disable_unprepare(uap->clk); |
| 1415 | clk_unprep: | ||
| 1416 | clk_unprepare(uap->clk); | ||
| 1417 | out: | ||
| 1418 | return retval; | 1461 | return retval; |
| 1419 | } | 1462 | } |
| 1420 | 1463 | ||
| @@ -1473,8 +1516,7 @@ static void pl011_shutdown(struct uart_port *port) | |||
| 1473 | /* | 1516 | /* |
| 1474 | * Shut down the clock producer | 1517 | * Shut down the clock producer |
| 1475 | */ | 1518 | */ |
| 1476 | clk_disable(uap->clk); | 1519 | clk_disable_unprepare(uap->clk); |
| 1477 | clk_unprepare(uap->clk); | ||
| 1478 | /* Optionally let pins go into sleep states */ | 1520 | /* Optionally let pins go into sleep states */ |
| 1479 | if (!IS_ERR(uap->pins_sleep)) { | 1521 | if (!IS_ERR(uap->pins_sleep)) { |
| 1480 | retval = pinctrl_select_state(uap->pinctrl, uap->pins_sleep); | 1522 | retval = pinctrl_select_state(uap->pinctrl, uap->pins_sleep); |
| @@ -1603,13 +1645,26 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 1603 | old_cr &= ~ST_UART011_CR_OVSFACT; | 1645 | old_cr &= ~ST_UART011_CR_OVSFACT; |
| 1604 | } | 1646 | } |
| 1605 | 1647 | ||
| 1648 | /* | ||
| 1649 | * Workaround for the ST Micro oversampling variants to | ||
| 1650 | * increase the bitrate slightly, by lowering the divisor, | ||
| 1651 | * to avoid delayed sampling of start bit at high speeds, | ||
| 1652 | * else we see data corruption. | ||
| 1653 | */ | ||
| 1654 | if (uap->vendor->oversampling) { | ||
| 1655 | if ((baud >= 3000000) && (baud < 3250000) && (quot > 1)) | ||
| 1656 | quot -= 1; | ||
| 1657 | else if ((baud > 3250000) && (quot > 2)) | ||
| 1658 | quot -= 2; | ||
| 1659 | } | ||
| 1606 | /* Set baud rate */ | 1660 | /* Set baud rate */ |
| 1607 | writew(quot & 0x3f, port->membase + UART011_FBRD); | 1661 | writew(quot & 0x3f, port->membase + UART011_FBRD); |
| 1608 | writew(quot >> 6, port->membase + UART011_IBRD); | 1662 | writew(quot >> 6, port->membase + UART011_IBRD); |
| 1609 | 1663 | ||
| 1610 | /* | 1664 | /* |
| 1611 | * ----------v----------v----------v----------v----- | 1665 | * ----------v----------v----------v----------v----- |
| 1612 | * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L | 1666 | * NOTE: lcrh_tx and lcrh_rx MUST BE WRITTEN AFTER |
| 1667 | * UART011_FBRD & UART011_IBRD. | ||
| 1613 | * ----------^----------^----------^----------^----- | 1668 | * ----------^----------^----------^----------^----- |
| 1614 | */ | 1669 | */ |
| 1615 | writew(lcr_h, port->membase + uap->lcrh_rx); | 1670 | writew(lcr_h, port->membase + uap->lcrh_rx); |
| @@ -1637,7 +1692,7 @@ static const char *pl011_type(struct uart_port *port) | |||
| 1637 | /* | 1692 | /* |
| 1638 | * Release the memory region(s) being used by 'port' | 1693 | * Release the memory region(s) being used by 'port' |
| 1639 | */ | 1694 | */ |
| 1640 | static void pl010_release_port(struct uart_port *port) | 1695 | static void pl011_release_port(struct uart_port *port) |
| 1641 | { | 1696 | { |
| 1642 | release_mem_region(port->mapbase, SZ_4K); | 1697 | release_mem_region(port->mapbase, SZ_4K); |
| 1643 | } | 1698 | } |
| @@ -1645,7 +1700,7 @@ static void pl010_release_port(struct uart_port *port) | |||
| 1645 | /* | 1700 | /* |
| 1646 | * Request the memory region(s) being used by 'port' | 1701 | * Request the memory region(s) being used by 'port' |
| 1647 | */ | 1702 | */ |
| 1648 | static int pl010_request_port(struct uart_port *port) | 1703 | static int pl011_request_port(struct uart_port *port) |
| 1649 | { | 1704 | { |
| 1650 | return request_mem_region(port->mapbase, SZ_4K, "uart-pl011") | 1705 | return request_mem_region(port->mapbase, SZ_4K, "uart-pl011") |
| 1651 | != NULL ? 0 : -EBUSY; | 1706 | != NULL ? 0 : -EBUSY; |
| @@ -1654,18 +1709,18 @@ static int pl010_request_port(struct uart_port *port) | |||
| 1654 | /* | 1709 | /* |
| 1655 | * Configure/autoconfigure the port. | 1710 | * Configure/autoconfigure the port. |
| 1656 | */ | 1711 | */ |
| 1657 | static void pl010_config_port(struct uart_port *port, int flags) | 1712 | static void pl011_config_port(struct uart_port *port, int flags) |
| 1658 | { | 1713 | { |
| 1659 | if (flags & UART_CONFIG_TYPE) { | 1714 | if (flags & UART_CONFIG_TYPE) { |
| 1660 | port->type = PORT_AMBA; | 1715 | port->type = PORT_AMBA; |
| 1661 | pl010_request_port(port); | 1716 | pl011_request_port(port); |
| 1662 | } | 1717 | } |
| 1663 | } | 1718 | } |
| 1664 | 1719 | ||
| 1665 | /* | 1720 | /* |
| 1666 | * verify the new serial_struct (for TIOCSSERIAL). | 1721 | * verify the new serial_struct (for TIOCSSERIAL). |
| 1667 | */ | 1722 | */ |
| 1668 | static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser) | 1723 | static int pl011_verify_port(struct uart_port *port, struct serial_struct *ser) |
| 1669 | { | 1724 | { |
| 1670 | int ret = 0; | 1725 | int ret = 0; |
| 1671 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA) | 1726 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA) |
| @@ -1678,9 +1733,9 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
| 1678 | } | 1733 | } |
| 1679 | 1734 | ||
| 1680 | static struct uart_ops amba_pl011_pops = { | 1735 | static struct uart_ops amba_pl011_pops = { |
| 1681 | .tx_empty = pl01x_tx_empty, | 1736 | .tx_empty = pl011_tx_empty, |
| 1682 | .set_mctrl = pl011_set_mctrl, | 1737 | .set_mctrl = pl011_set_mctrl, |
| 1683 | .get_mctrl = pl01x_get_mctrl, | 1738 | .get_mctrl = pl011_get_mctrl, |
| 1684 | .stop_tx = pl011_stop_tx, | 1739 | .stop_tx = pl011_stop_tx, |
| 1685 | .start_tx = pl011_start_tx, | 1740 | .start_tx = pl011_start_tx, |
| 1686 | .stop_rx = pl011_stop_rx, | 1741 | .stop_rx = pl011_stop_rx, |
| @@ -1691,13 +1746,14 @@ static struct uart_ops amba_pl011_pops = { | |||
| 1691 | .flush_buffer = pl011_dma_flush_buffer, | 1746 | .flush_buffer = pl011_dma_flush_buffer, |
| 1692 | .set_termios = pl011_set_termios, | 1747 | .set_termios = pl011_set_termios, |
| 1693 | .type = pl011_type, | 1748 | .type = pl011_type, |
| 1694 | .release_port = pl010_release_port, | 1749 | .release_port = pl011_release_port, |
| 1695 | .request_port = pl010_request_port, | 1750 | .request_port = pl011_request_port, |
| 1696 | .config_port = pl010_config_port, | 1751 | .config_port = pl011_config_port, |
| 1697 | .verify_port = pl010_verify_port, | 1752 | .verify_port = pl011_verify_port, |
| 1698 | #ifdef CONFIG_CONSOLE_POLL | 1753 | #ifdef CONFIG_CONSOLE_POLL |
| 1699 | .poll_get_char = pl010_get_poll_char, | 1754 | .poll_init = pl011_hwinit, |
| 1700 | .poll_put_char = pl010_put_poll_char, | 1755 | .poll_get_char = pl011_get_poll_char, |
| 1756 | .poll_put_char = pl011_put_poll_char, | ||
| 1701 | #endif | 1757 | #endif |
| 1702 | }; | 1758 | }; |
| 1703 | 1759 | ||
| @@ -1869,6 +1925,38 @@ static struct uart_driver amba_reg = { | |||
| 1869 | .cons = AMBA_CONSOLE, | 1925 | .cons = AMBA_CONSOLE, |
| 1870 | }; | 1926 | }; |
| 1871 | 1927 | ||
| 1928 | static int pl011_probe_dt_alias(int index, struct device *dev) | ||
| 1929 | { | ||
| 1930 | struct device_node *np; | ||
| 1931 | static bool seen_dev_with_alias = false; | ||
| 1932 | static bool seen_dev_without_alias = false; | ||
| 1933 | int ret = index; | ||
| 1934 | |||
| 1935 | if (!IS_ENABLED(CONFIG_OF)) | ||
| 1936 | return ret; | ||
| 1937 | |||
| 1938 | np = dev->of_node; | ||
| 1939 | if (!np) | ||
| 1940 | return ret; | ||
| 1941 | |||
| 1942 | ret = of_alias_get_id(np, "serial"); | ||
| 1943 | if (IS_ERR_VALUE(ret)) { | ||
| 1944 | seen_dev_without_alias = true; | ||
| 1945 | ret = index; | ||
| 1946 | } else { | ||
| 1947 | seen_dev_with_alias = true; | ||
| 1948 | if (ret >= ARRAY_SIZE(amba_ports) || amba_ports[ret] != NULL) { | ||
| 1949 | dev_warn(dev, "requested serial port %d not available.\n", ret); | ||
| 1950 | ret = index; | ||
| 1951 | } | ||
| 1952 | } | ||
| 1953 | |||
| 1954 | if (seen_dev_with_alias && seen_dev_without_alias) | ||
| 1955 | dev_warn(dev, "aliased and non-aliased serial devices found in device tree. Serial port enumeration may be unpredictable.\n"); | ||
| 1956 | |||
| 1957 | return ret; | ||
| 1958 | } | ||
| 1959 | |||
| 1872 | static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | 1960 | static int pl011_probe(struct amba_device *dev, const struct amba_id *id) |
| 1873 | { | 1961 | { |
| 1874 | struct uart_amba_port *uap; | 1962 | struct uart_amba_port *uap; |
| @@ -1891,6 +1979,8 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | |||
| 1891 | goto out; | 1979 | goto out; |
| 1892 | } | 1980 | } |
| 1893 | 1981 | ||
| 1982 | i = pl011_probe_dt_alias(i, &dev->dev); | ||
| 1983 | |||
| 1894 | base = ioremap(dev->res.start, resource_size(&dev->res)); | 1984 | base = ioremap(dev->res.start, resource_size(&dev->res)); |
| 1895 | if (!base) { | 1985 | if (!base) { |
| 1896 | ret = -ENOMEM; | 1986 | ret = -ENOMEM; |
| @@ -1923,7 +2013,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | |||
| 1923 | uap->lcrh_tx = vendor->lcrh_tx; | 2013 | uap->lcrh_tx = vendor->lcrh_tx; |
| 1924 | uap->old_cr = 0; | 2014 | uap->old_cr = 0; |
| 1925 | uap->fifosize = vendor->fifosize; | 2015 | uap->fifosize = vendor->fifosize; |
| 1926 | uap->interrupt_may_hang = vendor->interrupt_may_hang; | ||
| 1927 | uap->port.dev = &dev->dev; | 2016 | uap->port.dev = &dev->dev; |
| 1928 | uap->port.mapbase = dev->res.start; | 2017 | uap->port.mapbase = dev->res.start; |
| 1929 | uap->port.membase = base; | 2018 | uap->port.membase = base; |
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index bd97db23985b..9242d56ba267 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c | |||
| @@ -182,7 +182,7 @@ static void bfin_serial_start_tx(struct uart_port *port) | |||
| 182 | * To avoid losting RX interrupt, we reset IR function | 182 | * To avoid losting RX interrupt, we reset IR function |
| 183 | * before sending data. | 183 | * before sending data. |
| 184 | */ | 184 | */ |
| 185 | if (tty->termios->c_line == N_IRDA) | 185 | if (tty->termios.c_line == N_IRDA) |
| 186 | bfin_serial_reset_irda(port); | 186 | bfin_serial_reset_irda(port); |
| 187 | 187 | ||
| 188 | #ifdef CONFIG_SERIAL_BFIN_DMA | 188 | #ifdef CONFIG_SERIAL_BFIN_DMA |
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index b418947b7107..d0dd9194cecc 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c | |||
| @@ -71,7 +71,7 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo); | |||
| 71 | 71 | ||
| 72 | /**************************************************************/ | 72 | /**************************************************************/ |
| 73 | 73 | ||
| 74 | #define HW_BUF_SPD_THRESHOLD 9600 | 74 | #define HW_BUF_SPD_THRESHOLD 2400 |
| 75 | 75 | ||
| 76 | /* | 76 | /* |
| 77 | * Check, if transmit buffers are processed | 77 | * Check, if transmit buffers are processed |
| @@ -417,6 +417,7 @@ static int cpm_uart_startup(struct uart_port *port) | |||
| 417 | clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR); | 417 | clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR); |
| 418 | clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); | 418 | clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); |
| 419 | } | 419 | } |
| 420 | cpm_uart_initbd(pinfo); | ||
| 420 | cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); | 421 | cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); |
| 421 | } | 422 | } |
| 422 | /* Install interrupt handler. */ | 423 | /* Install interrupt handler. */ |
| @@ -500,16 +501,28 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
| 500 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 501 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
| 501 | smc_t __iomem *smcp = pinfo->smcp; | 502 | smc_t __iomem *smcp = pinfo->smcp; |
| 502 | scc_t __iomem *sccp = pinfo->sccp; | 503 | scc_t __iomem *sccp = pinfo->sccp; |
| 504 | int maxidl; | ||
| 503 | 505 | ||
| 504 | pr_debug("CPM uart[%d]:set_termios\n", port->line); | 506 | pr_debug("CPM uart[%d]:set_termios\n", port->line); |
| 505 | 507 | ||
| 506 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); | 508 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); |
| 507 | if (baud <= HW_BUF_SPD_THRESHOLD || | 509 | if (baud < HW_BUF_SPD_THRESHOLD || |
| 508 | (pinfo->port.state && pinfo->port.state->port.tty->low_latency)) | 510 | (pinfo->port.state && pinfo->port.state->port.tty->low_latency)) |
| 509 | pinfo->rx_fifosize = 1; | 511 | pinfo->rx_fifosize = 1; |
| 510 | else | 512 | else |
| 511 | pinfo->rx_fifosize = RX_BUF_SIZE; | 513 | pinfo->rx_fifosize = RX_BUF_SIZE; |
| 512 | 514 | ||
| 515 | /* MAXIDL is the timeout after which a receive buffer is closed | ||
| 516 | * when not full if no more characters are received. | ||
| 517 | * We calculate it from the baudrate so that the duration is | ||
| 518 | * always the same at standard rates: about 4ms. | ||
| 519 | */ | ||
| 520 | maxidl = baud / 2400; | ||
| 521 | if (maxidl < 1) | ||
| 522 | maxidl = 1; | ||
| 523 | if (maxidl > 0x10) | ||
| 524 | maxidl = 0x10; | ||
| 525 | |||
| 513 | /* Character length programmed into the mode register is the | 526 | /* Character length programmed into the mode register is the |
| 514 | * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, | 527 | * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, |
| 515 | * 1 or 2 stop bits, minus 1. | 528 | * 1 or 2 stop bits, minus 1. |
| @@ -610,6 +623,7 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
| 610 | * SMC/SCC receiver is disabled. | 623 | * SMC/SCC receiver is disabled. |
| 611 | */ | 624 | */ |
| 612 | out_be16(&pinfo->smcup->smc_mrblr, pinfo->rx_fifosize); | 625 | out_be16(&pinfo->smcup->smc_mrblr, pinfo->rx_fifosize); |
| 626 | out_be16(&pinfo->smcup->smc_maxidl, maxidl); | ||
| 613 | 627 | ||
| 614 | /* Set the mode register. We want to keep a copy of the | 628 | /* Set the mode register. We want to keep a copy of the |
| 615 | * enables, because we want to put them back if they were | 629 | * enables, because we want to put them back if they were |
| @@ -622,6 +636,7 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
| 622 | SMCMR_SM_UART | prev_mode); | 636 | SMCMR_SM_UART | prev_mode); |
| 623 | } else { | 637 | } else { |
| 624 | out_be16(&pinfo->sccup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); | 638 | out_be16(&pinfo->sccup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); |
| 639 | out_be16(&pinfo->sccup->scc_maxidl, maxidl); | ||
| 625 | out_be16(&sccp->scc_psmr, (sbits << 12) | scval); | 640 | out_be16(&sccp->scc_psmr, (sbits << 12) | scval); |
| 626 | } | 641 | } |
| 627 | 642 | ||
| @@ -798,7 +813,7 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) | |||
| 798 | cpm_set_scc_fcr(sup); | 813 | cpm_set_scc_fcr(sup); |
| 799 | 814 | ||
| 800 | out_be16(&sup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); | 815 | out_be16(&sup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); |
| 801 | out_be16(&sup->scc_maxidl, pinfo->rx_fifosize); | 816 | out_be16(&sup->scc_maxidl, 0x10); |
| 802 | out_be16(&sup->scc_brkcr, 1); | 817 | out_be16(&sup->scc_brkcr, 1); |
| 803 | out_be16(&sup->scc_parec, 0); | 818 | out_be16(&sup->scc_parec, 0); |
| 804 | out_be16(&sup->scc_frmec, 0); | 819 | out_be16(&sup->scc_frmec, 0); |
| @@ -872,7 +887,7 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) | |||
| 872 | 887 | ||
| 873 | /* Using idle character time requires some additional tuning. */ | 888 | /* Using idle character time requires some additional tuning. */ |
| 874 | out_be16(&up->smc_mrblr, pinfo->rx_fifosize); | 889 | out_be16(&up->smc_mrblr, pinfo->rx_fifosize); |
| 875 | out_be16(&up->smc_maxidl, pinfo->rx_fifosize); | 890 | out_be16(&up->smc_maxidl, 0x10); |
| 876 | out_be16(&up->smc_brklen, 0); | 891 | out_be16(&up->smc_brklen, 0); |
| 877 | out_be16(&up->smc_brkec, 0); | 892 | out_be16(&up->smc_brkec, 0); |
| 878 | out_be16(&up->smc_brkcr, 1); | 893 | out_be16(&up->smc_brkcr, 1); |
diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 80b6b1b1f725..35ee6a2c6877 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c | |||
| @@ -955,7 +955,7 @@ static const struct control_pins e100_modem_pins[NR_PORTS] = | |||
| 955 | /* Calculate the chartime depending on baudrate, numbor of bits etc. */ | 955 | /* Calculate the chartime depending on baudrate, numbor of bits etc. */ |
| 956 | static void update_char_time(struct e100_serial * info) | 956 | static void update_char_time(struct e100_serial * info) |
| 957 | { | 957 | { |
| 958 | tcflag_t cflags = info->port.tty->termios->c_cflag; | 958 | tcflag_t cflags = info->port.tty->termios.c_cflag; |
| 959 | int bits; | 959 | int bits; |
| 960 | 960 | ||
| 961 | /* calc. number of bits / data byte */ | 961 | /* calc. number of bits / data byte */ |
| @@ -1473,7 +1473,7 @@ rs_stop(struct tty_struct *tty) | |||
| 1473 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, | 1473 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, |
| 1474 | STOP_CHAR(info->port.tty)); | 1474 | STOP_CHAR(info->port.tty)); |
| 1475 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop); | 1475 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop); |
| 1476 | if (tty->termios->c_iflag & IXON ) { | 1476 | if (tty->termios.c_iflag & IXON ) { |
| 1477 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); | 1477 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); |
| 1478 | } | 1478 | } |
| 1479 | 1479 | ||
| @@ -1496,7 +1496,7 @@ rs_start(struct tty_struct *tty) | |||
| 1496 | info->xmit.tail,SERIAL_XMIT_SIZE))); | 1496 | info->xmit.tail,SERIAL_XMIT_SIZE))); |
| 1497 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(tty)); | 1497 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(tty)); |
| 1498 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); | 1498 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); |
| 1499 | if (tty->termios->c_iflag & IXON ) { | 1499 | if (tty->termios.c_iflag & IXON ) { |
| 1500 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); | 1500 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); |
| 1501 | } | 1501 | } |
| 1502 | 1502 | ||
| @@ -2929,7 +2929,7 @@ shutdown(struct e100_serial * info) | |||
| 2929 | descr[i].buf = 0; | 2929 | descr[i].buf = 0; |
| 2930 | } | 2930 | } |
| 2931 | 2931 | ||
| 2932 | if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) { | 2932 | if (!info->port.tty || (info->port.tty->termios.c_cflag & HUPCL)) { |
| 2933 | /* hang up DTR and RTS if HUPCL is enabled */ | 2933 | /* hang up DTR and RTS if HUPCL is enabled */ |
| 2934 | e100_dtr(info, 0); | 2934 | e100_dtr(info, 0); |
| 2935 | e100_rts(info, 0); /* could check CRTSCTS before doing this */ | 2935 | e100_rts(info, 0); /* could check CRTSCTS before doing this */ |
| @@ -2953,12 +2953,12 @@ change_speed(struct e100_serial *info) | |||
| 2953 | unsigned long flags; | 2953 | unsigned long flags; |
| 2954 | /* first some safety checks */ | 2954 | /* first some safety checks */ |
| 2955 | 2955 | ||
| 2956 | if (!info->port.tty || !info->port.tty->termios) | 2956 | if (!info->port.tty) |
| 2957 | return; | 2957 | return; |
| 2958 | if (!info->ioport) | 2958 | if (!info->ioport) |
| 2959 | return; | 2959 | return; |
| 2960 | 2960 | ||
| 2961 | cflag = info->port.tty->termios->c_cflag; | 2961 | cflag = info->port.tty->termios.c_cflag; |
| 2962 | 2962 | ||
| 2963 | /* possibly, the tx/rx should be disabled first to do this safely */ | 2963 | /* possibly, the tx/rx should be disabled first to do this safely */ |
| 2964 | 2964 | ||
| @@ -3088,7 +3088,7 @@ change_speed(struct e100_serial *info) | |||
| 3088 | info->ioport[REG_REC_CTRL] = info->rx_ctrl; | 3088 | info->ioport[REG_REC_CTRL] = info->rx_ctrl; |
| 3089 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->port.tty)); | 3089 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->port.tty)); |
| 3090 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); | 3090 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); |
| 3091 | if (info->port.tty->termios->c_iflag & IXON ) { | 3091 | if (info->port.tty->termios.c_iflag & IXON ) { |
| 3092 | DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n", | 3092 | DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n", |
| 3093 | STOP_CHAR(info->port.tty))); | 3093 | STOP_CHAR(info->port.tty))); |
| 3094 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); | 3094 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); |
| @@ -3355,7 +3355,7 @@ rs_throttle(struct tty_struct * tty) | |||
| 3355 | DFLOW(DEBUG_LOG(info->line,"rs_throttle %lu\n", tty->ldisc.chars_in_buffer(tty))); | 3355 | DFLOW(DEBUG_LOG(info->line,"rs_throttle %lu\n", tty->ldisc.chars_in_buffer(tty))); |
| 3356 | 3356 | ||
| 3357 | /* Do RTS before XOFF since XOFF might take some time */ | 3357 | /* Do RTS before XOFF since XOFF might take some time */ |
| 3358 | if (tty->termios->c_cflag & CRTSCTS) { | 3358 | if (tty->termios.c_cflag & CRTSCTS) { |
| 3359 | /* Turn off RTS line */ | 3359 | /* Turn off RTS line */ |
| 3360 | e100_rts(info, 0); | 3360 | e100_rts(info, 0); |
| 3361 | } | 3361 | } |
| @@ -3377,7 +3377,7 @@ rs_unthrottle(struct tty_struct * tty) | |||
| 3377 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc %d\n", tty->ldisc.chars_in_buffer(tty))); | 3377 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc %d\n", tty->ldisc.chars_in_buffer(tty))); |
| 3378 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle flip.count: %i\n", tty->flip.count)); | 3378 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle flip.count: %i\n", tty->flip.count)); |
| 3379 | /* Do RTS before XOFF since XOFF might take some time */ | 3379 | /* Do RTS before XOFF since XOFF might take some time */ |
| 3380 | if (tty->termios->c_cflag & CRTSCTS) { | 3380 | if (tty->termios.c_cflag & CRTSCTS) { |
| 3381 | /* Assert RTS line */ | 3381 | /* Assert RTS line */ |
| 3382 | e100_rts(info, 1); | 3382 | e100_rts(info, 1); |
| 3383 | } | 3383 | } |
| @@ -3748,7 +3748,7 @@ rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 3748 | 3748 | ||
| 3749 | /* Handle turning off CRTSCTS */ | 3749 | /* Handle turning off CRTSCTS */ |
| 3750 | if ((old_termios->c_cflag & CRTSCTS) && | 3750 | if ((old_termios->c_cflag & CRTSCTS) && |
| 3751 | !(tty->termios->c_cflag & CRTSCTS)) { | 3751 | !(tty->termios.c_cflag & CRTSCTS)) { |
| 3752 | tty->hw_stopped = 0; | 3752 | tty->hw_stopped = 0; |
| 3753 | rs_start(tty); | 3753 | rs_start(tty); |
| 3754 | } | 3754 | } |
| @@ -3815,7 +3815,7 @@ rs_close(struct tty_struct *tty, struct file * filp) | |||
| 3815 | * separate termios for callout and dialin. | 3815 | * separate termios for callout and dialin. |
| 3816 | */ | 3816 | */ |
| 3817 | if (info->flags & ASYNC_NORMAL_ACTIVE) | 3817 | if (info->flags & ASYNC_NORMAL_ACTIVE) |
| 3818 | info->normal_termios = *tty->termios; | 3818 | info->normal_termios = tty->termios; |
| 3819 | /* | 3819 | /* |
| 3820 | * Now we wait for the transmit buffer to clear; and we notify | 3820 | * Now we wait for the transmit buffer to clear; and we notify |
| 3821 | * the line discipline to only process XON/XOFF characters. | 3821 | * the line discipline to only process XON/XOFF characters. |
| @@ -3976,7 +3976,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
| 3976 | */ | 3976 | */ |
| 3977 | if (tty_hung_up_p(filp) || | 3977 | if (tty_hung_up_p(filp) || |
| 3978 | (info->flags & ASYNC_CLOSING)) { | 3978 | (info->flags & ASYNC_CLOSING)) { |
| 3979 | wait_event_interruptible_tty(info->close_wait, | 3979 | wait_event_interruptible_tty(tty, info->close_wait, |
| 3980 | !(info->flags & ASYNC_CLOSING)); | 3980 | !(info->flags & ASYNC_CLOSING)); |
| 3981 | #ifdef SERIAL_DO_RESTART | 3981 | #ifdef SERIAL_DO_RESTART |
| 3982 | if (info->flags & ASYNC_HUP_NOTIFY) | 3982 | if (info->flags & ASYNC_HUP_NOTIFY) |
| @@ -3998,7 +3998,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
| 3998 | return 0; | 3998 | return 0; |
| 3999 | } | 3999 | } |
| 4000 | 4000 | ||
| 4001 | if (tty->termios->c_cflag & CLOCAL) { | 4001 | if (tty->termios.c_cflag & CLOCAL) { |
| 4002 | do_clocal = 1; | 4002 | do_clocal = 1; |
| 4003 | } | 4003 | } |
| 4004 | 4004 | ||
| @@ -4052,9 +4052,9 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
| 4052 | printk("block_til_ready blocking: ttyS%d, count = %d\n", | 4052 | printk("block_til_ready blocking: ttyS%d, count = %d\n", |
| 4053 | info->line, info->count); | 4053 | info->line, info->count); |
| 4054 | #endif | 4054 | #endif |
| 4055 | tty_unlock(); | 4055 | tty_unlock(tty); |
| 4056 | schedule(); | 4056 | schedule(); |
| 4057 | tty_lock(); | 4057 | tty_lock(tty); |
| 4058 | } | 4058 | } |
| 4059 | set_current_state(TASK_RUNNING); | 4059 | set_current_state(TASK_RUNNING); |
| 4060 | remove_wait_queue(&info->open_wait, &wait); | 4060 | remove_wait_queue(&info->open_wait, &wait); |
| @@ -4115,7 +4115,7 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
| 4115 | */ | 4115 | */ |
| 4116 | if (tty_hung_up_p(filp) || | 4116 | if (tty_hung_up_p(filp) || |
| 4117 | (info->flags & ASYNC_CLOSING)) { | 4117 | (info->flags & ASYNC_CLOSING)) { |
| 4118 | wait_event_interruptible_tty(info->close_wait, | 4118 | wait_event_interruptible_tty(tty, info->close_wait, |
| 4119 | !(info->flags & ASYNC_CLOSING)); | 4119 | !(info->flags & ASYNC_CLOSING)); |
| 4120 | #ifdef SERIAL_DO_RESTART | 4120 | #ifdef SERIAL_DO_RESTART |
| 4121 | return ((info->flags & ASYNC_HUP_NOTIFY) ? | 4121 | return ((info->flags & ASYNC_HUP_NOTIFY) ? |
| @@ -4219,7 +4219,7 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
| 4219 | } | 4219 | } |
| 4220 | 4220 | ||
| 4221 | if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { | 4221 | if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { |
| 4222 | *tty->termios = info->normal_termios; | 4222 | tty->termios = info->normal_termios; |
| 4223 | change_speed(info); | 4223 | change_speed(info); |
| 4224 | } | 4224 | } |
| 4225 | 4225 | ||
| @@ -4443,14 +4443,12 @@ static int __init rs_init(void) | |||
| 4443 | B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */ | 4443 | B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */ |
| 4444 | driver->init_termios.c_ispeed = 115200; | 4444 | driver->init_termios.c_ispeed = 115200; |
| 4445 | driver->init_termios.c_ospeed = 115200; | 4445 | driver->init_termios.c_ospeed = 115200; |
| 4446 | driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 4446 | driver->flags = TTY_DRIVER_REAL_RAW; |
| 4447 | 4447 | ||
| 4448 | tty_set_operations(driver, &rs_ops); | 4448 | tty_set_operations(driver, &rs_ops); |
| 4449 | serial_driver = driver; | 4449 | serial_driver = driver; |
| 4450 | if (tty_register_driver(driver)) | ||
| 4451 | panic("Couldn't register serial driver\n"); | ||
| 4452 | /* do some initializing for the separate ports */ | ||
| 4453 | 4450 | ||
| 4451 | /* do some initializing for the separate ports */ | ||
| 4454 | for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) { | 4452 | for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) { |
| 4455 | if (info->enabled) { | 4453 | if (info->enabled) { |
| 4456 | if (cris_request_io_interface(info->io_if, | 4454 | if (cris_request_io_interface(info->io_if, |
| @@ -4502,7 +4500,12 @@ static int __init rs_init(void) | |||
| 4502 | printk(KERN_INFO "%s%d at %p is a builtin UART with DMA\n", | 4500 | printk(KERN_INFO "%s%d at %p is a builtin UART with DMA\n", |
| 4503 | serial_driver->name, info->line, info->ioport); | 4501 | serial_driver->name, info->line, info->ioport); |
| 4504 | } | 4502 | } |
| 4503 | tty_port_link_device(&info->port, driver, i); | ||
| 4505 | } | 4504 | } |
| 4505 | |||
| 4506 | if (tty_register_driver(driver)) | ||
| 4507 | panic("Couldn't register serial driver\n"); | ||
| 4508 | |||
| 4506 | #ifdef CONFIG_ETRAX_FAST_TIMER | 4509 | #ifdef CONFIG_ETRAX_FAST_TIMER |
| 4507 | #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER | 4510 | #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER |
| 4508 | memset(fast_timers, 0, sizeof(fast_timers)); | 4511 | memset(fast_timers, 0, sizeof(fast_timers)); |
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 3ad079ffd049..5b9bc19ed134 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
| @@ -800,8 +800,8 @@ static int ifx_spi_create_port(struct ifx_spi_device *ifx_dev) | |||
| 800 | tty_port_init(pport); | 800 | tty_port_init(pport); |
| 801 | pport->ops = &ifx_tty_port_ops; | 801 | pport->ops = &ifx_tty_port_ops; |
| 802 | ifx_dev->minor = IFX_SPI_TTY_ID; | 802 | ifx_dev->minor = IFX_SPI_TTY_ID; |
| 803 | ifx_dev->tty_dev = tty_register_device(tty_drv, ifx_dev->minor, | 803 | ifx_dev->tty_dev = tty_port_register_device(pport, tty_drv, |
| 804 | &ifx_dev->spi_dev->dev); | 804 | ifx_dev->minor, &ifx_dev->spi_dev->dev); |
| 805 | if (IS_ERR(ifx_dev->tty_dev)) { | 805 | if (IS_ERR(ifx_dev->tty_dev)) { |
| 806 | dev_dbg(&ifx_dev->spi_dev->dev, | 806 | dev_dbg(&ifx_dev->spi_dev->dev, |
| 807 | "%s: registering tty device failed", __func__); | 807 | "%s: registering tty device failed", __func__); |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index e309e8b0aaba..efeb8becfa43 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
| @@ -207,7 +207,7 @@ struct imx_port { | |||
| 207 | unsigned short trcv_delay; /* transceiver delay */ | 207 | unsigned short trcv_delay; /* transceiver delay */ |
| 208 | struct clk *clk_ipg; | 208 | struct clk *clk_ipg; |
| 209 | struct clk *clk_per; | 209 | struct clk *clk_per; |
| 210 | struct imx_uart_data *devdata; | 210 | const struct imx_uart_data *devdata; |
| 211 | }; | 211 | }; |
| 212 | 212 | ||
| 213 | struct imx_port_ucrs { | 213 | struct imx_port_ucrs { |
| @@ -1373,8 +1373,7 @@ static int serial_imx_suspend(struct platform_device *dev, pm_message_t state) | |||
| 1373 | val |= UCR3_AWAKEN; | 1373 | val |= UCR3_AWAKEN; |
| 1374 | writel(val, sport->port.membase + UCR3); | 1374 | writel(val, sport->port.membase + UCR3); |
| 1375 | 1375 | ||
| 1376 | if (sport) | 1376 | uart_suspend_port(&imx_reg, &sport->port); |
| 1377 | uart_suspend_port(&imx_reg, &sport->port); | ||
| 1378 | 1377 | ||
| 1379 | return 0; | 1378 | return 0; |
| 1380 | } | 1379 | } |
| @@ -1389,8 +1388,7 @@ static int serial_imx_resume(struct platform_device *dev) | |||
| 1389 | val &= ~UCR3_AWAKEN; | 1388 | val &= ~UCR3_AWAKEN; |
| 1390 | writel(val, sport->port.membase + UCR3); | 1389 | writel(val, sport->port.membase + UCR3); |
| 1391 | 1390 | ||
| 1392 | if (sport) | 1391 | uart_resume_port(&imx_reg, &sport->port); |
| 1393 | uart_resume_port(&imx_reg, &sport->port); | ||
| 1394 | 1392 | ||
| 1395 | return 0; | 1393 | return 0; |
| 1396 | } | 1394 | } |
| @@ -1505,18 +1503,21 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
| 1505 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); | 1503 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); |
| 1506 | if (IS_ERR(pinctrl)) { | 1504 | if (IS_ERR(pinctrl)) { |
| 1507 | ret = PTR_ERR(pinctrl); | 1505 | ret = PTR_ERR(pinctrl); |
| 1506 | dev_err(&pdev->dev, "failed to get default pinctrl: %d\n", ret); | ||
| 1508 | goto unmap; | 1507 | goto unmap; |
| 1509 | } | 1508 | } |
| 1510 | 1509 | ||
| 1511 | sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); | 1510 | sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
| 1512 | if (IS_ERR(sport->clk_ipg)) { | 1511 | if (IS_ERR(sport->clk_ipg)) { |
| 1513 | ret = PTR_ERR(sport->clk_ipg); | 1512 | ret = PTR_ERR(sport->clk_ipg); |
| 1513 | dev_err(&pdev->dev, "failed to get ipg clk: %d\n", ret); | ||
| 1514 | goto unmap; | 1514 | goto unmap; |
| 1515 | } | 1515 | } |
| 1516 | 1516 | ||
| 1517 | sport->clk_per = devm_clk_get(&pdev->dev, "per"); | 1517 | sport->clk_per = devm_clk_get(&pdev->dev, "per"); |
| 1518 | if (IS_ERR(sport->clk_per)) { | 1518 | if (IS_ERR(sport->clk_per)) { |
| 1519 | ret = PTR_ERR(sport->clk_per); | 1519 | ret = PTR_ERR(sport->clk_per); |
| 1520 | dev_err(&pdev->dev, "failed to get per clk: %d\n", ret); | ||
| 1520 | goto unmap; | 1521 | goto unmap; |
| 1521 | } | 1522 | } |
| 1522 | 1523 | ||
| @@ -1537,7 +1538,7 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
| 1537 | ret = uart_add_one_port(&imx_reg, &sport->port); | 1538 | ret = uart_add_one_port(&imx_reg, &sport->port); |
| 1538 | if (ret) | 1539 | if (ret) |
| 1539 | goto deinit; | 1540 | goto deinit; |
| 1540 | platform_set_drvdata(pdev, &sport->port); | 1541 | platform_set_drvdata(pdev, sport); |
| 1541 | 1542 | ||
| 1542 | return 0; | 1543 | return 0; |
| 1543 | deinit: | 1544 | deinit: |
diff --git a/drivers/tty/serial/ioc3_serial.c b/drivers/tty/serial/ioc3_serial.c index 758ff310f7f8..5ac52898a0bb 100644 --- a/drivers/tty/serial/ioc3_serial.c +++ b/drivers/tty/serial/ioc3_serial.c | |||
| @@ -1120,13 +1120,14 @@ static inline int do_read(struct uart_port *the_port, char *buf, int len) | |||
| 1120 | struct ioc3_port *port = get_ioc3_port(the_port); | 1120 | struct ioc3_port *port = get_ioc3_port(the_port); |
| 1121 | struct ring *inring; | 1121 | struct ring *inring; |
| 1122 | struct ring_entry *entry; | 1122 | struct ring_entry *entry; |
| 1123 | struct port_hooks *hooks = port->ip_hooks; | 1123 | struct port_hooks *hooks; |
| 1124 | int byte_num; | 1124 | int byte_num; |
| 1125 | char *sc; | 1125 | char *sc; |
| 1126 | int loop_counter; | 1126 | int loop_counter; |
| 1127 | 1127 | ||
| 1128 | BUG_ON(!(len >= 0)); | 1128 | BUG_ON(!(len >= 0)); |
| 1129 | BUG_ON(!port); | 1129 | BUG_ON(!port); |
| 1130 | hooks = port->ip_hooks; | ||
| 1130 | 1131 | ||
| 1131 | /* There is a nasty timing issue in the IOC3. When the rx_timer | 1132 | /* There is a nasty timing issue in the IOC3. When the rx_timer |
| 1132 | * expires or the rx_high condition arises, we take an interrupt. | 1133 | * expires or the rx_high condition arises, we take an interrupt. |
diff --git a/drivers/tty/serial/ioc4_serial.c b/drivers/tty/serial/ioc4_serial.c index e16894fb2ca3..3e7da10cebba 100644 --- a/drivers/tty/serial/ioc4_serial.c +++ b/drivers/tty/serial/ioc4_serial.c | |||
| @@ -1803,7 +1803,7 @@ static inline int ic4_startup_local(struct uart_port *the_port) | |||
| 1803 | ioc4_set_proto(port, the_port->mapbase); | 1803 | ioc4_set_proto(port, the_port->mapbase); |
| 1804 | 1804 | ||
| 1805 | /* set the speed of the serial port */ | 1805 | /* set the speed of the serial port */ |
| 1806 | ioc4_change_speed(the_port, state->port.tty->termios, | 1806 | ioc4_change_speed(the_port, &state->port.tty->termios, |
| 1807 | (struct ktermios *)0); | 1807 | (struct ktermios *)0); |
| 1808 | 1808 | ||
| 1809 | return 0; | 1809 | return 0; |
| @@ -2069,13 +2069,14 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf, | |||
| 2069 | struct ioc4_port *port = get_ioc4_port(the_port, 0); | 2069 | struct ioc4_port *port = get_ioc4_port(the_port, 0); |
| 2070 | struct ring *inring; | 2070 | struct ring *inring; |
| 2071 | struct ring_entry *entry; | 2071 | struct ring_entry *entry; |
| 2072 | struct hooks *hooks = port->ip_hooks; | 2072 | struct hooks *hooks; |
| 2073 | int byte_num; | 2073 | int byte_num; |
| 2074 | char *sc; | 2074 | char *sc; |
| 2075 | int loop_counter; | 2075 | int loop_counter; |
| 2076 | 2076 | ||
| 2077 | BUG_ON(!(len >= 0)); | 2077 | BUG_ON(!(len >= 0)); |
| 2078 | BUG_ON(!port); | 2078 | BUG_ON(!port); |
| 2079 | hooks = port->ip_hooks; | ||
| 2079 | 2080 | ||
| 2080 | /* There is a nasty timing issue in the IOC4. When the rx_timer | 2081 | /* There is a nasty timing issue in the IOC4. When the rx_timer |
| 2081 | * expires or the rx_high condition arises, we take an interrupt. | 2082 | * expires or the rx_high condition arises, we take an interrupt. |
diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 434bd881fcae..71397961773c 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c | |||
| @@ -161,7 +161,7 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch) | |||
| 161 | struct ktermios *termios; | 161 | struct ktermios *termios; |
| 162 | 162 | ||
| 163 | spin_lock_irqsave(&port->lock, lock_flags); | 163 | spin_lock_irqsave(&port->lock, lock_flags); |
| 164 | termios = port->state->port.tty->termios; | 164 | termios = &port->state->port.tty->termios; |
| 165 | if (ch == termios->c_cc[VSTART]) | 165 | if (ch == termios->c_cc[VSTART]) |
| 166 | channel->ch_bd->bd_ops->send_start_character(channel); | 166 | channel->ch_bd->bd_ops->send_start_character(channel); |
| 167 | 167 | ||
| @@ -250,7 +250,7 @@ static int jsm_tty_open(struct uart_port *port) | |||
| 250 | channel->ch_cached_lsr = 0; | 250 | channel->ch_cached_lsr = 0; |
| 251 | channel->ch_stops_sent = 0; | 251 | channel->ch_stops_sent = 0; |
| 252 | 252 | ||
| 253 | termios = port->state->port.tty->termios; | 253 | termios = &port->state->port.tty->termios; |
| 254 | channel->ch_c_cflag = termios->c_cflag; | 254 | channel->ch_c_cflag = termios->c_cflag; |
| 255 | channel->ch_c_iflag = termios->c_iflag; | 255 | channel->ch_c_iflag = termios->c_iflag; |
| 256 | channel->ch_c_oflag = termios->c_oflag; | 256 | channel->ch_c_oflag = termios->c_oflag; |
| @@ -283,7 +283,7 @@ static void jsm_tty_close(struct uart_port *port) | |||
| 283 | jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n"); | 283 | jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n"); |
| 284 | 284 | ||
| 285 | bd = channel->ch_bd; | 285 | bd = channel->ch_bd; |
| 286 | ts = port->state->port.tty->termios; | 286 | ts = &port->state->port.tty->termios; |
| 287 | 287 | ||
| 288 | channel->ch_flags &= ~(CH_STOPI); | 288 | channel->ch_flags &= ~(CH_STOPI); |
| 289 | 289 | ||
| @@ -567,7 +567,7 @@ void jsm_input(struct jsm_channel *ch) | |||
| 567 | *input data and return immediately. | 567 | *input data and return immediately. |
| 568 | */ | 568 | */ |
| 569 | if (!tp || | 569 | if (!tp || |
| 570 | !(tp->termios->c_cflag & CREAD) ) { | 570 | !(tp->termios.c_cflag & CREAD) ) { |
| 571 | 571 | ||
| 572 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | 572 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, |
| 573 | "input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum); | 573 | "input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum); |
diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c new file mode 100644 index 000000000000..d185247ba1aa --- /dev/null +++ b/drivers/tty/serial/kgdb_nmi.c | |||
| @@ -0,0 +1,402 @@ | |||
| 1 | /* | ||
| 2 | * KGDB NMI serial console | ||
| 3 | * | ||
| 4 | * Copyright 2010 Google, Inc. | ||
| 5 | * Arve Hjønnevåg <arve@android.com> | ||
| 6 | * Colin Cross <ccross@android.com> | ||
| 7 | * Copyright 2012 Linaro Ltd. | ||
| 8 | * Anton Vorontsov <anton.vorontsov@linaro.org> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU General Public License version 2 as published | ||
| 12 | * by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/compiler.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/slab.h> | ||
| 20 | #include <linux/errno.h> | ||
| 21 | #include <linux/atomic.h> | ||
| 22 | #include <linux/console.h> | ||
| 23 | #include <linux/tty.h> | ||
| 24 | #include <linux/tty_driver.h> | ||
| 25 | #include <linux/tty_flip.h> | ||
| 26 | #include <linux/interrupt.h> | ||
| 27 | #include <linux/hrtimer.h> | ||
| 28 | #include <linux/tick.h> | ||
| 29 | #include <linux/kfifo.h> | ||
| 30 | #include <linux/kgdb.h> | ||
| 31 | #include <linux/kdb.h> | ||
| 32 | |||
| 33 | static int kgdb_nmi_knock = 1; | ||
| 34 | module_param_named(knock, kgdb_nmi_knock, int, 0600); | ||
| 35 | MODULE_PARM_DESC(knock, "if set to 1 (default), the special '$3#33' command " \ | ||
| 36 | "must be used to enter the debugger; when set to 0, " \ | ||
| 37 | "hitting return key is enough to enter the debugger; " \ | ||
| 38 | "when set to -1, the debugger is entered immediately " \ | ||
| 39 | "upon NMI"); | ||
| 40 | |||
| 41 | static char *kgdb_nmi_magic = "$3#33"; | ||
| 42 | module_param_named(magic, kgdb_nmi_magic, charp, 0600); | ||
| 43 | MODULE_PARM_DESC(magic, "magic sequence to enter NMI debugger (default $3#33)"); | ||
| 44 | |||
| 45 | static bool kgdb_nmi_tty_enabled; | ||
| 46 | |||
| 47 | static void kgdb_nmi_console_write(struct console *co, const char *s, uint c) | ||
| 48 | { | ||
| 49 | int i; | ||
| 50 | |||
| 51 | if (!kgdb_nmi_tty_enabled || atomic_read(&kgdb_active) >= 0) | ||
| 52 | return; | ||
| 53 | |||
| 54 | for (i = 0; i < c; i++) | ||
| 55 | dbg_io_ops->write_char(s[i]); | ||
| 56 | } | ||
| 57 | |||
| 58 | static struct tty_driver *kgdb_nmi_tty_driver; | ||
| 59 | |||
| 60 | static struct tty_driver *kgdb_nmi_console_device(struct console *co, int *idx) | ||
| 61 | { | ||
| 62 | *idx = co->index; | ||
| 63 | return kgdb_nmi_tty_driver; | ||
| 64 | } | ||
| 65 | |||
| 66 | static struct console kgdb_nmi_console = { | ||
| 67 | .name = "ttyNMI", | ||
| 68 | .write = kgdb_nmi_console_write, | ||
| 69 | .device = kgdb_nmi_console_device, | ||
| 70 | .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_ENABLED, | ||
| 71 | .index = -1, | ||
| 72 | }; | ||
| 73 | |||
| 74 | /* | ||
| 75 | * This is usually the maximum rate on debug ports. We make fifo large enough | ||
| 76 | * to make copy-pasting to the terminal usable. | ||
| 77 | */ | ||
| 78 | #define KGDB_NMI_BAUD 115200 | ||
| 79 | #define KGDB_NMI_FIFO_SIZE roundup_pow_of_two(KGDB_NMI_BAUD / 8 / HZ) | ||
| 80 | |||
| 81 | struct kgdb_nmi_tty_priv { | ||
| 82 | struct tty_port port; | ||
| 83 | struct tasklet_struct tlet; | ||
| 84 | STRUCT_KFIFO(char, KGDB_NMI_FIFO_SIZE) fifo; | ||
| 85 | }; | ||
| 86 | |||
| 87 | static struct kgdb_nmi_tty_priv *kgdb_nmi_port_to_priv(struct tty_port *port) | ||
| 88 | { | ||
| 89 | return container_of(port, struct kgdb_nmi_tty_priv, port); | ||
| 90 | } | ||
| 91 | |||
| 92 | /* | ||
| 93 | * Our debugging console is polled in a tasklet, so we'll check for input | ||
| 94 | * every tick. In HZ-less mode, we should program the next tick. We have | ||
| 95 | * to use the lowlevel stuff as no locks should be grabbed. | ||
| 96 | */ | ||
| 97 | #ifdef CONFIG_HIGH_RES_TIMERS | ||
| 98 | static void kgdb_tty_poke(void) | ||
| 99 | { | ||
| 100 | tick_program_event(ktime_get(), 0); | ||
| 101 | } | ||
| 102 | #else | ||
| 103 | static inline void kgdb_tty_poke(void) {} | ||
| 104 | #endif | ||
| 105 | |||
| 106 | static struct tty_port *kgdb_nmi_port; | ||
| 107 | |||
| 108 | static void kgdb_tty_recv(int ch) | ||
| 109 | { | ||
| 110 | struct kgdb_nmi_tty_priv *priv; | ||
| 111 | char c = ch; | ||
| 112 | |||
| 113 | if (!kgdb_nmi_port || ch < 0) | ||
| 114 | return; | ||
| 115 | /* | ||
| 116 | * Can't use port->tty->driver_data as tty might be not there. Tasklet | ||
| 117 | * will check for tty and will get the ref, but here we don't have to | ||
| 118 | * do that, and actually, we can't: we're in NMI context, no locks are | ||
| 119 | * possible. | ||
| 120 | */ | ||
| 121 | priv = kgdb_nmi_port_to_priv(kgdb_nmi_port); | ||
| 122 | kfifo_in(&priv->fifo, &c, 1); | ||
| 123 | kgdb_tty_poke(); | ||
| 124 | } | ||
| 125 | |||
| 126 | static int kgdb_nmi_poll_one_knock(void) | ||
| 127 | { | ||
| 128 | static int n; | ||
| 129 | int c = -1; | ||
| 130 | const char *magic = kgdb_nmi_magic; | ||
| 131 | size_t m = strlen(magic); | ||
| 132 | bool printch = 0; | ||
| 133 | |||
| 134 | c = dbg_io_ops->read_char(); | ||
| 135 | if (c == NO_POLL_CHAR) | ||
| 136 | return c; | ||
| 137 | |||
| 138 | if (!kgdb_nmi_knock && (c == '\r' || c == '\n')) { | ||
| 139 | return 1; | ||
| 140 | } else if (c == magic[n]) { | ||
| 141 | n = (n + 1) % m; | ||
| 142 | if (!n) | ||
| 143 | return 1; | ||
| 144 | printch = 1; | ||
| 145 | } else { | ||
| 146 | n = 0; | ||
| 147 | } | ||
| 148 | |||
| 149 | if (kgdb_nmi_tty_enabled) { | ||
| 150 | kgdb_tty_recv(c); | ||
| 151 | return 0; | ||
| 152 | } | ||
| 153 | |||
| 154 | if (printch) { | ||
| 155 | kdb_printf("%c", c); | ||
| 156 | return 0; | ||
| 157 | } | ||
| 158 | |||
| 159 | kdb_printf("\r%s %s to enter the debugger> %*s", | ||
| 160 | kgdb_nmi_knock ? "Type" : "Hit", | ||
| 161 | kgdb_nmi_knock ? magic : "<return>", (int)m, ""); | ||
| 162 | while (m--) | ||
| 163 | kdb_printf("\b"); | ||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | /** | ||
| 168 | * kgdb_nmi_poll_knock - Check if it is time to enter the debugger | ||
| 169 | * | ||
| 170 | * "Serial ports are often noisy, especially when muxed over another port (we | ||
| 171 | * often use serial over the headset connector). Noise on the async command | ||
| 172 | * line just causes characters that are ignored, on a command line that blocked | ||
| 173 | * execution noise would be catastrophic." -- Colin Cross | ||
| 174 | * | ||
| 175 | * So, this function implements KGDB/KDB knocking on the serial line: we won't | ||
| 176 | * enter the debugger until we receive a known magic phrase (which is actually | ||
| 177 | * "$3#33", known as "escape to KDB" command. There is also a relaxed variant | ||
| 178 | * of knocking, i.e. just pressing the return key is enough to enter the | ||
| 179 | * debugger. And if knocking is disabled, the function always returns 1. | ||
| 180 | */ | ||
| 181 | bool kgdb_nmi_poll_knock(void) | ||
| 182 | { | ||
| 183 | if (kgdb_nmi_knock < 0) | ||
| 184 | return 1; | ||
| 185 | |||
| 186 | while (1) { | ||
| 187 | int ret; | ||
| 188 | |||
| 189 | ret = kgdb_nmi_poll_one_knock(); | ||
| 190 | if (ret == NO_POLL_CHAR) | ||
| 191 | return 0; | ||
| 192 | else if (ret == 1) | ||
| 193 | break; | ||
| 194 | } | ||
| 195 | return 1; | ||
| 196 | } | ||
| 197 | |||
| 198 | /* | ||
| 199 | * The tasklet is cheap, it does not cause wakeups when reschedules itself, | ||
| 200 | * instead it waits for the next tick. | ||
| 201 | */ | ||
| 202 | static void kgdb_nmi_tty_receiver(unsigned long data) | ||
| 203 | { | ||
| 204 | struct kgdb_nmi_tty_priv *priv = (void *)data; | ||
| 205 | struct tty_struct *tty; | ||
| 206 | char ch; | ||
| 207 | |||
| 208 | tasklet_schedule(&priv->tlet); | ||
| 209 | |||
| 210 | if (likely(!kgdb_nmi_tty_enabled || !kfifo_len(&priv->fifo))) | ||
| 211 | return; | ||
| 212 | |||
| 213 | /* Port is there, but tty might be hung up, check. */ | ||
| 214 | tty = tty_port_tty_get(kgdb_nmi_port); | ||
| 215 | if (!tty) | ||
| 216 | return; | ||
| 217 | |||
| 218 | while (kfifo_out(&priv->fifo, &ch, 1)) | ||
| 219 | tty_insert_flip_char(priv->port.tty, ch, TTY_NORMAL); | ||
| 220 | tty_flip_buffer_push(priv->port.tty); | ||
| 221 | |||
| 222 | tty_kref_put(tty); | ||
| 223 | } | ||
| 224 | |||
| 225 | static int kgdb_nmi_tty_activate(struct tty_port *port, struct tty_struct *tty) | ||
| 226 | { | ||
| 227 | struct kgdb_nmi_tty_priv *priv = tty->driver_data; | ||
| 228 | |||
| 229 | kgdb_nmi_port = port; | ||
| 230 | tasklet_schedule(&priv->tlet); | ||
| 231 | return 0; | ||
| 232 | } | ||
| 233 | |||
| 234 | static void kgdb_nmi_tty_shutdown(struct tty_port *port) | ||
| 235 | { | ||
| 236 | struct kgdb_nmi_tty_priv *priv = port->tty->driver_data; | ||
| 237 | |||
| 238 | tasklet_kill(&priv->tlet); | ||
| 239 | kgdb_nmi_port = NULL; | ||
| 240 | } | ||
| 241 | |||
| 242 | static const struct tty_port_operations kgdb_nmi_tty_port_ops = { | ||
| 243 | .activate = kgdb_nmi_tty_activate, | ||
| 244 | .shutdown = kgdb_nmi_tty_shutdown, | ||
| 245 | }; | ||
| 246 | |||
| 247 | static int kgdb_nmi_tty_install(struct tty_driver *drv, struct tty_struct *tty) | ||
| 248 | { | ||
| 249 | struct kgdb_nmi_tty_priv *priv; | ||
| 250 | int ret; | ||
| 251 | |||
| 252 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
| 253 | if (!priv) | ||
| 254 | return -ENOMEM; | ||
| 255 | |||
| 256 | INIT_KFIFO(priv->fifo); | ||
| 257 | tasklet_init(&priv->tlet, kgdb_nmi_tty_receiver, (unsigned long)priv); | ||
| 258 | tty_port_init(&priv->port); | ||
| 259 | priv->port.ops = &kgdb_nmi_tty_port_ops; | ||
| 260 | tty->driver_data = priv; | ||
| 261 | |||
| 262 | ret = tty_port_install(&priv->port, drv, tty); | ||
| 263 | if (ret) { | ||
| 264 | pr_err("%s: can't install tty port: %d\n", __func__, ret); | ||
| 265 | goto err; | ||
| 266 | } | ||
| 267 | return 0; | ||
| 268 | err: | ||
| 269 | kfree(priv); | ||
| 270 | return ret; | ||
| 271 | } | ||
| 272 | |||
| 273 | static void kgdb_nmi_tty_cleanup(struct tty_struct *tty) | ||
| 274 | { | ||
| 275 | struct kgdb_nmi_tty_priv *priv = tty->driver_data; | ||
| 276 | |||
| 277 | tty->driver_data = NULL; | ||
| 278 | kfree(priv); | ||
| 279 | } | ||
| 280 | |||
| 281 | static int kgdb_nmi_tty_open(struct tty_struct *tty, struct file *file) | ||
| 282 | { | ||
| 283 | struct kgdb_nmi_tty_priv *priv = tty->driver_data; | ||
| 284 | |||
| 285 | return tty_port_open(&priv->port, tty, file); | ||
| 286 | } | ||
| 287 | |||
| 288 | static void kgdb_nmi_tty_close(struct tty_struct *tty, struct file *file) | ||
| 289 | { | ||
| 290 | struct kgdb_nmi_tty_priv *priv = tty->driver_data; | ||
| 291 | |||
| 292 | tty_port_close(&priv->port, tty, file); | ||
| 293 | } | ||
| 294 | |||
| 295 | static void kgdb_nmi_tty_hangup(struct tty_struct *tty) | ||
| 296 | { | ||
| 297 | struct kgdb_nmi_tty_priv *priv = tty->driver_data; | ||
| 298 | |||
| 299 | tty_port_hangup(&priv->port); | ||
| 300 | } | ||
| 301 | |||
| 302 | static int kgdb_nmi_tty_write_room(struct tty_struct *tty) | ||
| 303 | { | ||
| 304 | /* Actually, we can handle any amount as we use polled writes. */ | ||
| 305 | return 2048; | ||
| 306 | } | ||
| 307 | |||
| 308 | static int kgdb_nmi_tty_write(struct tty_struct *tty, const unchar *buf, int c) | ||
| 309 | { | ||
| 310 | int i; | ||
| 311 | |||
| 312 | for (i = 0; i < c; i++) | ||
| 313 | dbg_io_ops->write_char(buf[i]); | ||
| 314 | return c; | ||
| 315 | } | ||
| 316 | |||
| 317 | static const struct tty_operations kgdb_nmi_tty_ops = { | ||
| 318 | .open = kgdb_nmi_tty_open, | ||
| 319 | .close = kgdb_nmi_tty_close, | ||
| 320 | .install = kgdb_nmi_tty_install, | ||
| 321 | .cleanup = kgdb_nmi_tty_cleanup, | ||
| 322 | .hangup = kgdb_nmi_tty_hangup, | ||
| 323 | .write_room = kgdb_nmi_tty_write_room, | ||
| 324 | .write = kgdb_nmi_tty_write, | ||
| 325 | }; | ||
| 326 | |||
| 327 | static int kgdb_nmi_enable_console(int argc, const char *argv[]) | ||
| 328 | { | ||
| 329 | kgdb_nmi_tty_enabled = !(argc == 1 && !strcmp(argv[1], "off")); | ||
| 330 | return 0; | ||
| 331 | } | ||
| 332 | |||
| 333 | int kgdb_register_nmi_console(void) | ||
| 334 | { | ||
| 335 | int ret; | ||
| 336 | |||
| 337 | if (!arch_kgdb_ops.enable_nmi) | ||
| 338 | return 0; | ||
| 339 | |||
| 340 | kgdb_nmi_tty_driver = alloc_tty_driver(1); | ||
| 341 | if (!kgdb_nmi_tty_driver) { | ||
| 342 | pr_err("%s: cannot allocate tty\n", __func__); | ||
| 343 | return -ENOMEM; | ||
| 344 | } | ||
| 345 | kgdb_nmi_tty_driver->driver_name = "ttyNMI"; | ||
| 346 | kgdb_nmi_tty_driver->name = "ttyNMI"; | ||
| 347 | kgdb_nmi_tty_driver->num = 1; | ||
| 348 | kgdb_nmi_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
| 349 | kgdb_nmi_tty_driver->subtype = SERIAL_TYPE_NORMAL; | ||
| 350 | kgdb_nmi_tty_driver->flags = TTY_DRIVER_REAL_RAW; | ||
| 351 | kgdb_nmi_tty_driver->init_termios = tty_std_termios; | ||
| 352 | tty_termios_encode_baud_rate(&kgdb_nmi_tty_driver->init_termios, | ||
| 353 | KGDB_NMI_BAUD, KGDB_NMI_BAUD); | ||
| 354 | tty_set_operations(kgdb_nmi_tty_driver, &kgdb_nmi_tty_ops); | ||
| 355 | |||
| 356 | ret = tty_register_driver(kgdb_nmi_tty_driver); | ||
| 357 | if (ret) { | ||
| 358 | pr_err("%s: can't register tty driver: %d\n", __func__, ret); | ||
| 359 | goto err_drv_reg; | ||
| 360 | } | ||
| 361 | |||
| 362 | ret = kdb_register("nmi_console", kgdb_nmi_enable_console, "[off]", | ||
| 363 | "switch to Linux NMI console", 0); | ||
| 364 | if (ret) { | ||
| 365 | pr_err("%s: can't register kdb command: %d\n", __func__, ret); | ||
| 366 | goto err_kdb_reg; | ||
| 367 | } | ||
| 368 | |||
| 369 | register_console(&kgdb_nmi_console); | ||
| 370 | arch_kgdb_ops.enable_nmi(1); | ||
| 371 | |||
| 372 | return 0; | ||
| 373 | err_kdb_reg: | ||
| 374 | tty_unregister_driver(kgdb_nmi_tty_driver); | ||
| 375 | err_drv_reg: | ||
| 376 | put_tty_driver(kgdb_nmi_tty_driver); | ||
| 377 | return ret; | ||
| 378 | } | ||
| 379 | EXPORT_SYMBOL_GPL(kgdb_register_nmi_console); | ||
| 380 | |||
| 381 | int kgdb_unregister_nmi_console(void) | ||
| 382 | { | ||
| 383 | int ret; | ||
| 384 | |||
| 385 | if (!arch_kgdb_ops.enable_nmi) | ||
| 386 | return 0; | ||
| 387 | arch_kgdb_ops.enable_nmi(0); | ||
| 388 | |||
| 389 | kdb_unregister("nmi_console"); | ||
| 390 | |||
| 391 | ret = unregister_console(&kgdb_nmi_console); | ||
| 392 | if (ret) | ||
| 393 | return ret; | ||
| 394 | |||
| 395 | ret = tty_unregister_driver(kgdb_nmi_tty_driver); | ||
| 396 | if (ret) | ||
| 397 | return ret; | ||
| 398 | put_tty_driver(kgdb_nmi_tty_driver); | ||
| 399 | |||
| 400 | return 0; | ||
| 401 | } | ||
| 402 | EXPORT_SYMBOL_GPL(kgdb_unregister_nmi_console); | ||
diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c index 2b42a01a81c6..3f63d834cbc9 100644 --- a/drivers/tty/serial/kgdboc.c +++ b/drivers/tty/serial/kgdboc.c | |||
| @@ -145,6 +145,8 @@ __setup("kgdboc=", kgdboc_option_setup); | |||
| 145 | 145 | ||
| 146 | static void cleanup_kgdboc(void) | 146 | static void cleanup_kgdboc(void) |
| 147 | { | 147 | { |
| 148 | if (kgdb_unregister_nmi_console()) | ||
| 149 | return; | ||
| 148 | kgdboc_unregister_kbd(); | 150 | kgdboc_unregister_kbd(); |
| 149 | if (configured == 1) | 151 | if (configured == 1) |
| 150 | kgdb_unregister_io_module(&kgdboc_io_ops); | 152 | kgdb_unregister_io_module(&kgdboc_io_ops); |
| @@ -198,11 +200,18 @@ do_register: | |||
| 198 | if (err) | 200 | if (err) |
| 199 | goto noconfig; | 201 | goto noconfig; |
| 200 | 202 | ||
| 203 | err = kgdb_register_nmi_console(); | ||
| 204 | if (err) | ||
| 205 | goto nmi_con_failed; | ||
| 206 | |||
| 201 | configured = 1; | 207 | configured = 1; |
| 202 | 208 | ||
| 203 | return 0; | 209 | return 0; |
| 204 | 210 | ||
| 211 | nmi_con_failed: | ||
| 212 | kgdb_unregister_io_module(&kgdboc_io_ops); | ||
| 205 | noconfig: | 213 | noconfig: |
| 214 | kgdboc_unregister_kbd(); | ||
| 206 | config[0] = 0; | 215 | config[0] = 0; |
| 207 | configured = 0; | 216 | configured = 0; |
| 208 | cleanup_kgdboc(); | 217 | cleanup_kgdboc(); |
diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c new file mode 100644 index 000000000000..ba3af3bf6d43 --- /dev/null +++ b/drivers/tty/serial/lpc32xx_hs.c | |||
| @@ -0,0 +1,823 @@ | |||
| 1 | /* | ||
| 2 | * High Speed Serial Ports on NXP LPC32xx SoC | ||
| 3 | * | ||
| 4 | * Authors: Kevin Wells <kevin.wells@nxp.com> | ||
| 5 | * Roland Stigge <stigge@antcom.de> | ||
| 6 | * | ||
| 7 | * Copyright (C) 2010 NXP Semiconductors | ||
| 8 | * Copyright (C) 2012 Roland Stigge | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/ioport.h> | ||
| 23 | #include <linux/init.h> | ||
| 24 | #include <linux/console.h> | ||
| 25 | #include <linux/sysrq.h> | ||
| 26 | #include <linux/tty.h> | ||
| 27 | #include <linux/tty_flip.h> | ||
| 28 | #include <linux/serial_core.h> | ||
| 29 | #include <linux/serial.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | #include <linux/delay.h> | ||
| 32 | #include <linux/nmi.h> | ||
| 33 | #include <linux/io.h> | ||
| 34 | #include <linux/irq.h> | ||
| 35 | #include <linux/gpio.h> | ||
| 36 | #include <linux/of.h> | ||
| 37 | #include <mach/platform.h> | ||
| 38 | #include <mach/hardware.h> | ||
| 39 | |||
| 40 | /* | ||
| 41 | * High Speed UART register offsets | ||
| 42 | */ | ||
| 43 | #define LPC32XX_HSUART_FIFO(x) ((x) + 0x00) | ||
| 44 | #define LPC32XX_HSUART_LEVEL(x) ((x) + 0x04) | ||
| 45 | #define LPC32XX_HSUART_IIR(x) ((x) + 0x08) | ||
| 46 | #define LPC32XX_HSUART_CTRL(x) ((x) + 0x0C) | ||
| 47 | #define LPC32XX_HSUART_RATE(x) ((x) + 0x10) | ||
| 48 | |||
| 49 | #define LPC32XX_HSU_BREAK_DATA (1 << 10) | ||
| 50 | #define LPC32XX_HSU_ERROR_DATA (1 << 9) | ||
| 51 | #define LPC32XX_HSU_RX_EMPTY (1 << 8) | ||
| 52 | |||
| 53 | #define LPC32XX_HSU_TX_LEV(n) (((n) >> 8) & 0xFF) | ||
| 54 | #define LPC32XX_HSU_RX_LEV(n) ((n) & 0xFF) | ||
| 55 | |||
| 56 | #define LPC32XX_HSU_TX_INT_SET (1 << 6) | ||
| 57 | #define LPC32XX_HSU_RX_OE_INT (1 << 5) | ||
| 58 | #define LPC32XX_HSU_BRK_INT (1 << 4) | ||
| 59 | #define LPC32XX_HSU_FE_INT (1 << 3) | ||
| 60 | #define LPC32XX_HSU_RX_TIMEOUT_INT (1 << 2) | ||
| 61 | #define LPC32XX_HSU_RX_TRIG_INT (1 << 1) | ||
| 62 | #define LPC32XX_HSU_TX_INT (1 << 0) | ||
| 63 | |||
| 64 | #define LPC32XX_HSU_HRTS_INV (1 << 21) | ||
| 65 | #define LPC32XX_HSU_HRTS_TRIG_8B (0x0 << 19) | ||
| 66 | #define LPC32XX_HSU_HRTS_TRIG_16B (0x1 << 19) | ||
| 67 | #define LPC32XX_HSU_HRTS_TRIG_32B (0x2 << 19) | ||
| 68 | #define LPC32XX_HSU_HRTS_TRIG_48B (0x3 << 19) | ||
| 69 | #define LPC32XX_HSU_HRTS_EN (1 << 18) | ||
| 70 | #define LPC32XX_HSU_TMO_DISABLED (0x0 << 16) | ||
| 71 | #define LPC32XX_HSU_TMO_INACT_4B (0x1 << 16) | ||
| 72 | #define LPC32XX_HSU_TMO_INACT_8B (0x2 << 16) | ||
| 73 | #define LPC32XX_HSU_TMO_INACT_16B (0x3 << 16) | ||
| 74 | #define LPC32XX_HSU_HCTS_INV (1 << 15) | ||
| 75 | #define LPC32XX_HSU_HCTS_EN (1 << 14) | ||
| 76 | #define LPC32XX_HSU_OFFSET(n) ((n) << 9) | ||
| 77 | #define LPC32XX_HSU_BREAK (1 << 8) | ||
| 78 | #define LPC32XX_HSU_ERR_INT_EN (1 << 7) | ||
| 79 | #define LPC32XX_HSU_RX_INT_EN (1 << 6) | ||
| 80 | #define LPC32XX_HSU_TX_INT_EN (1 << 5) | ||
| 81 | #define LPC32XX_HSU_RX_TL1B (0x0 << 2) | ||
| 82 | #define LPC32XX_HSU_RX_TL4B (0x1 << 2) | ||
| 83 | #define LPC32XX_HSU_RX_TL8B (0x2 << 2) | ||
| 84 | #define LPC32XX_HSU_RX_TL16B (0x3 << 2) | ||
| 85 | #define LPC32XX_HSU_RX_TL32B (0x4 << 2) | ||
| 86 | #define LPC32XX_HSU_RX_TL48B (0x5 << 2) | ||
| 87 | #define LPC32XX_HSU_TX_TLEMPTY (0x0 << 0) | ||
| 88 | #define LPC32XX_HSU_TX_TL0B (0x0 << 0) | ||
| 89 | #define LPC32XX_HSU_TX_TL4B (0x1 << 0) | ||
| 90 | #define LPC32XX_HSU_TX_TL8B (0x2 << 0) | ||
| 91 | #define LPC32XX_HSU_TX_TL16B (0x3 << 0) | ||
| 92 | |||
| 93 | #define MODNAME "lpc32xx_hsuart" | ||
| 94 | |||
| 95 | struct lpc32xx_hsuart_port { | ||
| 96 | struct uart_port port; | ||
| 97 | }; | ||
| 98 | |||
| 99 | #define FIFO_READ_LIMIT 128 | ||
| 100 | #define MAX_PORTS 3 | ||
| 101 | #define LPC32XX_TTY_NAME "ttyTX" | ||
| 102 | static struct lpc32xx_hsuart_port lpc32xx_hs_ports[MAX_PORTS]; | ||
| 103 | |||
| 104 | #ifdef CONFIG_SERIAL_HS_LPC32XX_CONSOLE | ||
| 105 | static void wait_for_xmit_empty(struct uart_port *port) | ||
| 106 | { | ||
| 107 | unsigned int timeout = 10000; | ||
| 108 | |||
| 109 | do { | ||
| 110 | if (LPC32XX_HSU_TX_LEV(readl(LPC32XX_HSUART_LEVEL( | ||
| 111 | port->membase))) == 0) | ||
| 112 | break; | ||
| 113 | if (--timeout == 0) | ||
| 114 | break; | ||
| 115 | udelay(1); | ||
| 116 | } while (1); | ||
| 117 | } | ||
| 118 | |||
| 119 | static void wait_for_xmit_ready(struct uart_port *port) | ||
| 120 | { | ||
| 121 | unsigned int timeout = 10000; | ||
| 122 | |||
| 123 | while (1) { | ||
| 124 | if (LPC32XX_HSU_TX_LEV(readl(LPC32XX_HSUART_LEVEL( | ||
| 125 | port->membase))) < 32) | ||
| 126 | break; | ||
| 127 | if (--timeout == 0) | ||
| 128 | break; | ||
| 129 | udelay(1); | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | static void lpc32xx_hsuart_console_putchar(struct uart_port *port, int ch) | ||
| 134 | { | ||
| 135 | wait_for_xmit_ready(port); | ||
| 136 | writel((u32)ch, LPC32XX_HSUART_FIFO(port->membase)); | ||
| 137 | } | ||
| 138 | |||
| 139 | static void lpc32xx_hsuart_console_write(struct console *co, const char *s, | ||
| 140 | unsigned int count) | ||
| 141 | { | ||
| 142 | struct lpc32xx_hsuart_port *up = &lpc32xx_hs_ports[co->index]; | ||
| 143 | unsigned long flags; | ||
| 144 | int locked = 1; | ||
| 145 | |||
| 146 | touch_nmi_watchdog(); | ||
| 147 | local_irq_save(flags); | ||
| 148 | if (up->port.sysrq) | ||
| 149 | locked = 0; | ||
| 150 | else if (oops_in_progress) | ||
| 151 | locked = spin_trylock(&up->port.lock); | ||
| 152 | else | ||
| 153 | spin_lock(&up->port.lock); | ||
| 154 | |||
| 155 | uart_console_write(&up->port, s, count, lpc32xx_hsuart_console_putchar); | ||
| 156 | wait_for_xmit_empty(&up->port); | ||
| 157 | |||
| 158 | if (locked) | ||
| 159 | spin_unlock(&up->port.lock); | ||
| 160 | local_irq_restore(flags); | ||
| 161 | } | ||
| 162 | |||
| 163 | static int __init lpc32xx_hsuart_console_setup(struct console *co, | ||
| 164 | char *options) | ||
| 165 | { | ||
| 166 | struct uart_port *port; | ||
| 167 | int baud = 115200; | ||
| 168 | int bits = 8; | ||
| 169 | int parity = 'n'; | ||
| 170 | int flow = 'n'; | ||
| 171 | |||
| 172 | if (co->index >= MAX_PORTS) | ||
| 173 | co->index = 0; | ||
| 174 | |||
| 175 | port = &lpc32xx_hs_ports[co->index].port; | ||
| 176 | if (!port->membase) | ||
| 177 | return -ENODEV; | ||
| 178 | |||
| 179 | if (options) | ||
| 180 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
| 181 | |||
| 182 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
| 183 | } | ||
| 184 | |||
| 185 | static struct uart_driver lpc32xx_hsuart_reg; | ||
| 186 | static struct console lpc32xx_hsuart_console = { | ||
| 187 | .name = LPC32XX_TTY_NAME, | ||
| 188 | .write = lpc32xx_hsuart_console_write, | ||
| 189 | .device = uart_console_device, | ||
| 190 | .setup = lpc32xx_hsuart_console_setup, | ||
| 191 | .flags = CON_PRINTBUFFER, | ||
| 192 | .index = -1, | ||
| 193 | .data = &lpc32xx_hsuart_reg, | ||
| 194 | }; | ||
| 195 | |||
| 196 | static int __init lpc32xx_hsuart_console_init(void) | ||
| 197 | { | ||
| 198 | register_console(&lpc32xx_hsuart_console); | ||
| 199 | return 0; | ||
| 200 | } | ||
| 201 | console_initcall(lpc32xx_hsuart_console_init); | ||
| 202 | |||
| 203 | #define LPC32XX_HSUART_CONSOLE (&lpc32xx_hsuart_console) | ||
| 204 | #else | ||
| 205 | #define LPC32XX_HSUART_CONSOLE NULL | ||
| 206 | #endif | ||
| 207 | |||
| 208 | static struct uart_driver lpc32xx_hs_reg = { | ||
| 209 | .owner = THIS_MODULE, | ||
| 210 | .driver_name = MODNAME, | ||
| 211 | .dev_name = LPC32XX_TTY_NAME, | ||
| 212 | .nr = MAX_PORTS, | ||
| 213 | .cons = LPC32XX_HSUART_CONSOLE, | ||
| 214 | }; | ||
| 215 | static int uarts_registered; | ||
| 216 | |||
| 217 | static unsigned int __serial_get_clock_div(unsigned long uartclk, | ||
| 218 | unsigned long rate) | ||
| 219 | { | ||
| 220 | u32 div, goodrate, hsu_rate, l_hsu_rate, comprate; | ||
| 221 | u32 rate_diff; | ||
| 222 | |||
| 223 | /* Find the closest divider to get the desired clock rate */ | ||
| 224 | div = uartclk / rate; | ||
| 225 | goodrate = hsu_rate = (div / 14) - 1; | ||
| 226 | if (hsu_rate != 0) | ||
| 227 | hsu_rate--; | ||
| 228 | |||
| 229 | /* Tweak divider */ | ||
| 230 | l_hsu_rate = hsu_rate + 3; | ||
| 231 | rate_diff = 0xFFFFFFFF; | ||
| 232 | |||
| 233 | while (hsu_rate < l_hsu_rate) { | ||
| 234 | comprate = uartclk / ((hsu_rate + 1) * 14); | ||
| 235 | if (abs(comprate - rate) < rate_diff) { | ||
| 236 | goodrate = hsu_rate; | ||
| 237 | rate_diff = abs(comprate - rate); | ||
| 238 | } | ||
| 239 | |||
| 240 | hsu_rate++; | ||
| 241 | } | ||
| 242 | if (hsu_rate > 0xFF) | ||
| 243 | hsu_rate = 0xFF; | ||
| 244 | |||
| 245 | return goodrate; | ||
| 246 | } | ||
| 247 | |||
| 248 | static void __serial_uart_flush(struct uart_port *port) | ||
| 249 | { | ||
| 250 | u32 tmp; | ||
| 251 | int cnt = 0; | ||
| 252 | |||
| 253 | while ((readl(LPC32XX_HSUART_LEVEL(port->membase)) > 0) && | ||
| 254 | (cnt++ < FIFO_READ_LIMIT)) | ||
| 255 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); | ||
| 256 | } | ||
| 257 | |||
| 258 | static void __serial_lpc32xx_rx(struct uart_port *port) | ||
| 259 | { | ||
| 260 | unsigned int tmp, flag; | ||
| 261 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
| 262 | |||
| 263 | if (!tty) { | ||
| 264 | /* Discard data: no tty available */ | ||
| 265 | while (!(readl(LPC32XX_HSUART_FIFO(port->membase)) & | ||
| 266 | LPC32XX_HSU_RX_EMPTY)) | ||
| 267 | ; | ||
| 268 | |||
| 269 | return; | ||
| 270 | } | ||
| 271 | |||
| 272 | /* Read data from FIFO and push into terminal */ | ||
| 273 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); | ||
| 274 | while (!(tmp & LPC32XX_HSU_RX_EMPTY)) { | ||
| 275 | flag = TTY_NORMAL; | ||
| 276 | port->icount.rx++; | ||
| 277 | |||
| 278 | if (tmp & LPC32XX_HSU_ERROR_DATA) { | ||
| 279 | /* Framing error */ | ||
| 280 | writel(LPC32XX_HSU_FE_INT, | ||
| 281 | LPC32XX_HSUART_IIR(port->membase)); | ||
| 282 | port->icount.frame++; | ||
| 283 | flag = TTY_FRAME; | ||
| 284 | tty_insert_flip_char(tty, 0, TTY_FRAME); | ||
| 285 | } | ||
| 286 | |||
| 287 | tty_insert_flip_char(tty, (tmp & 0xFF), flag); | ||
| 288 | |||
| 289 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); | ||
| 290 | } | ||
| 291 | tty_flip_buffer_push(tty); | ||
| 292 | tty_kref_put(tty); | ||
| 293 | } | ||
| 294 | |||
| 295 | static void __serial_lpc32xx_tx(struct uart_port *port) | ||
| 296 | { | ||
| 297 | struct circ_buf *xmit = &port->state->xmit; | ||
| 298 | unsigned int tmp; | ||
| 299 | |||
| 300 | if (port->x_char) { | ||
| 301 | writel((u32)port->x_char, LPC32XX_HSUART_FIFO(port->membase)); | ||
| 302 | port->icount.tx++; | ||
| 303 | port->x_char = 0; | ||
| 304 | return; | ||
| 305 | } | ||
| 306 | |||
| 307 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | ||
| 308 | goto exit_tx; | ||
| 309 | |||
| 310 | /* Transfer data */ | ||
| 311 | while (LPC32XX_HSU_TX_LEV(readl( | ||
| 312 | LPC32XX_HSUART_LEVEL(port->membase))) < 64) { | ||
| 313 | writel((u32) xmit->buf[xmit->tail], | ||
| 314 | LPC32XX_HSUART_FIFO(port->membase)); | ||
| 315 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
| 316 | port->icount.tx++; | ||
| 317 | if (uart_circ_empty(xmit)) | ||
| 318 | break; | ||
| 319 | } | ||
| 320 | |||
| 321 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
| 322 | uart_write_wakeup(port); | ||
| 323 | |||
| 324 | exit_tx: | ||
| 325 | if (uart_circ_empty(xmit)) { | ||
| 326 | tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); | ||
| 327 | tmp &= ~LPC32XX_HSU_TX_INT_EN; | ||
| 328 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
| 329 | } | ||
| 330 | } | ||
| 331 | |||
| 332 | static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) | ||
| 333 | { | ||
| 334 | struct uart_port *port = dev_id; | ||
| 335 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
| 336 | u32 status; | ||
| 337 | |||
| 338 | spin_lock(&port->lock); | ||
| 339 | |||
| 340 | /* Read UART status and clear latched interrupts */ | ||
| 341 | status = readl(LPC32XX_HSUART_IIR(port->membase)); | ||
| 342 | |||
| 343 | if (status & LPC32XX_HSU_BRK_INT) { | ||
| 344 | /* Break received */ | ||
| 345 | writel(LPC32XX_HSU_BRK_INT, LPC32XX_HSUART_IIR(port->membase)); | ||
| 346 | port->icount.brk++; | ||
| 347 | uart_handle_break(port); | ||
| 348 | } | ||
| 349 | |||
| 350 | /* Framing error */ | ||
| 351 | if (status & LPC32XX_HSU_FE_INT) | ||
| 352 | writel(LPC32XX_HSU_FE_INT, LPC32XX_HSUART_IIR(port->membase)); | ||
| 353 | |||
| 354 | if (status & LPC32XX_HSU_RX_OE_INT) { | ||
| 355 | /* Receive FIFO overrun */ | ||
| 356 | writel(LPC32XX_HSU_RX_OE_INT, | ||
| 357 | LPC32XX_HSUART_IIR(port->membase)); | ||
| 358 | port->icount.overrun++; | ||
| 359 | if (tty) { | ||
| 360 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
| 361 | tty_schedule_flip(tty); | ||
| 362 | } | ||
| 363 | } | ||
| 364 | |||
| 365 | /* Data received? */ | ||
| 366 | if (status & (LPC32XX_HSU_RX_TIMEOUT_INT | LPC32XX_HSU_RX_TRIG_INT)) { | ||
| 367 | __serial_lpc32xx_rx(port); | ||
| 368 | if (tty) | ||
| 369 | tty_flip_buffer_push(tty); | ||
| 370 | } | ||
| 371 | |||
| 372 | /* Transmit data request? */ | ||
| 373 | if ((status & LPC32XX_HSU_TX_INT) && (!uart_tx_stopped(port))) { | ||
| 374 | writel(LPC32XX_HSU_TX_INT, LPC32XX_HSUART_IIR(port->membase)); | ||
| 375 | __serial_lpc32xx_tx(port); | ||
| 376 | } | ||
| 377 | |||
| 378 | spin_unlock(&port->lock); | ||
| 379 | tty_kref_put(tty); | ||
| 380 | |||
| 381 | return IRQ_HANDLED; | ||
| 382 | } | ||
| 383 | |||
| 384 | /* port->lock is not held. */ | ||
| 385 | static unsigned int serial_lpc32xx_tx_empty(struct uart_port *port) | ||
| 386 | { | ||
| 387 | unsigned int ret = 0; | ||
| 388 | |||
| 389 | if (LPC32XX_HSU_TX_LEV(readl(LPC32XX_HSUART_LEVEL(port->membase))) == 0) | ||
| 390 | ret = TIOCSER_TEMT; | ||
| 391 | |||
| 392 | return ret; | ||
| 393 | } | ||
| 394 | |||
| 395 | /* port->lock held by caller. */ | ||
| 396 | static void serial_lpc32xx_set_mctrl(struct uart_port *port, | ||
| 397 | unsigned int mctrl) | ||
| 398 | { | ||
| 399 | /* No signals are supported on HS UARTs */ | ||
| 400 | } | ||
| 401 | |||
| 402 | /* port->lock is held by caller and interrupts are disabled. */ | ||
| 403 | static unsigned int serial_lpc32xx_get_mctrl(struct uart_port *port) | ||
| 404 | { | ||
| 405 | /* No signals are supported on HS UARTs */ | ||
| 406 | return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; | ||
| 407 | } | ||
| 408 | |||
| 409 | /* port->lock held by caller. */ | ||
| 410 | static void serial_lpc32xx_stop_tx(struct uart_port *port) | ||
| 411 | { | ||
| 412 | u32 tmp; | ||
| 413 | |||
| 414 | tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); | ||
| 415 | tmp &= ~LPC32XX_HSU_TX_INT_EN; | ||
| 416 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
| 417 | } | ||
| 418 | |||
| 419 | /* port->lock held by caller. */ | ||
| 420 | static void serial_lpc32xx_start_tx(struct uart_port *port) | ||
| 421 | { | ||
| 422 | u32 tmp; | ||
| 423 | |||
| 424 | __serial_lpc32xx_tx(port); | ||
| 425 | tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); | ||
| 426 | tmp |= LPC32XX_HSU_TX_INT_EN; | ||
| 427 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
| 428 | } | ||
| 429 | |||
| 430 | /* port->lock held by caller. */ | ||
| 431 | static void serial_lpc32xx_stop_rx(struct uart_port *port) | ||
| 432 | { | ||
| 433 | u32 tmp; | ||
| 434 | |||
| 435 | tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); | ||
| 436 | tmp &= ~(LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN); | ||
| 437 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
| 438 | |||
| 439 | writel((LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT | | ||
| 440 | LPC32XX_HSU_FE_INT), LPC32XX_HSUART_IIR(port->membase)); | ||
| 441 | } | ||
| 442 | |||
| 443 | /* port->lock held by caller. */ | ||
| 444 | static void serial_lpc32xx_enable_ms(struct uart_port *port) | ||
| 445 | { | ||
| 446 | /* Modem status is not supported */ | ||
| 447 | } | ||
| 448 | |||
| 449 | /* port->lock is not held. */ | ||
| 450 | static void serial_lpc32xx_break_ctl(struct uart_port *port, | ||
| 451 | int break_state) | ||
| 452 | { | ||
| 453 | unsigned long flags; | ||
| 454 | u32 tmp; | ||
| 455 | |||
| 456 | spin_lock_irqsave(&port->lock, flags); | ||
| 457 | tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); | ||
| 458 | if (break_state != 0) | ||
| 459 | tmp |= LPC32XX_HSU_BREAK; | ||
| 460 | else | ||
| 461 | tmp &= ~LPC32XX_HSU_BREAK; | ||
| 462 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
| 463 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 464 | } | ||
| 465 | |||
| 466 | /* LPC3250 Errata HSUART.1: Hang workaround via loopback mode on inactivity */ | ||
| 467 | static void lpc32xx_loopback_set(resource_size_t mapbase, int state) | ||
| 468 | { | ||
| 469 | int bit; | ||
| 470 | u32 tmp; | ||
| 471 | |||
| 472 | switch (mapbase) { | ||
| 473 | case LPC32XX_HS_UART1_BASE: | ||
| 474 | bit = 0; | ||
| 475 | break; | ||
| 476 | case LPC32XX_HS_UART2_BASE: | ||
| 477 | bit = 1; | ||
| 478 | break; | ||
| 479 | case LPC32XX_HS_UART7_BASE: | ||
| 480 | bit = 6; | ||
| 481 | break; | ||
| 482 | default: | ||
| 483 | WARN(1, "lpc32xx_hs: Warning: Unknown port at %08x\n", mapbase); | ||
| 484 | return; | ||
| 485 | } | ||
| 486 | |||
| 487 | tmp = readl(LPC32XX_UARTCTL_CLOOP); | ||
| 488 | if (state) | ||
| 489 | tmp |= (1 << bit); | ||
| 490 | else | ||
| 491 | tmp &= ~(1 << bit); | ||
| 492 | writel(tmp, LPC32XX_UARTCTL_CLOOP); | ||
| 493 | } | ||
| 494 | |||
| 495 | /* port->lock is not held. */ | ||
| 496 | static int serial_lpc32xx_startup(struct uart_port *port) | ||
| 497 | { | ||
| 498 | int retval; | ||
| 499 | unsigned long flags; | ||
| 500 | u32 tmp; | ||
| 501 | |||
| 502 | spin_lock_irqsave(&port->lock, flags); | ||
| 503 | |||
| 504 | __serial_uart_flush(port); | ||
| 505 | |||
| 506 | writel((LPC32XX_HSU_TX_INT | LPC32XX_HSU_FE_INT | | ||
| 507 | LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT), | ||
| 508 | LPC32XX_HSUART_IIR(port->membase)); | ||
| 509 | |||
| 510 | writel(0xFF, LPC32XX_HSUART_RATE(port->membase)); | ||
| 511 | |||
| 512 | /* | ||
| 513 | * Set receiver timeout, HSU offset of 20, no break, no interrupts, | ||
| 514 | * and default FIFO trigger levels | ||
| 515 | */ | ||
| 516 | tmp = LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B | | ||
| 517 | LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B; | ||
| 518 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
| 519 | |||
| 520 | lpc32xx_loopback_set(port->mapbase, 0); /* get out of loopback mode */ | ||
| 521 | |||
| 522 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 523 | |||
| 524 | retval = request_irq(port->irq, serial_lpc32xx_interrupt, | ||
| 525 | 0, MODNAME, port); | ||
| 526 | if (!retval) | ||
| 527 | writel((tmp | LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN), | ||
| 528 | LPC32XX_HSUART_CTRL(port->membase)); | ||
| 529 | |||
| 530 | return retval; | ||
| 531 | } | ||
| 532 | |||
| 533 | /* port->lock is not held. */ | ||
| 534 | static void serial_lpc32xx_shutdown(struct uart_port *port) | ||
| 535 | { | ||
| 536 | u32 tmp; | ||
| 537 | unsigned long flags; | ||
| 538 | |||
| 539 | spin_lock_irqsave(&port->lock, flags); | ||
| 540 | |||
| 541 | tmp = LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B | | ||
| 542 | LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B; | ||
| 543 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
| 544 | |||
| 545 | lpc32xx_loopback_set(port->mapbase, 1); /* go to loopback mode */ | ||
| 546 | |||
| 547 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 548 | |||
| 549 | free_irq(port->irq, port); | ||
| 550 | } | ||
| 551 | |||
| 552 | /* port->lock is not held. */ | ||
| 553 | static void serial_lpc32xx_set_termios(struct uart_port *port, | ||
| 554 | struct ktermios *termios, | ||
| 555 | struct ktermios *old) | ||
| 556 | { | ||
| 557 | unsigned long flags; | ||
| 558 | unsigned int baud, quot; | ||
| 559 | u32 tmp; | ||
| 560 | |||
| 561 | /* Always 8-bit, no parity, 1 stop bit */ | ||
| 562 | termios->c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD); | ||
| 563 | termios->c_cflag |= CS8; | ||
| 564 | |||
| 565 | termios->c_cflag &= ~(HUPCL | CMSPAR | CLOCAL | CRTSCTS); | ||
| 566 | |||
| 567 | baud = uart_get_baud_rate(port, termios, old, 0, | ||
| 568 | port->uartclk / 14); | ||
| 569 | |||
| 570 | quot = __serial_get_clock_div(port->uartclk, baud); | ||
| 571 | |||
| 572 | spin_lock_irqsave(&port->lock, flags); | ||
| 573 | |||
| 574 | /* Ignore characters? */ | ||
| 575 | tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); | ||
| 576 | if ((termios->c_cflag & CREAD) == 0) | ||
| 577 | tmp &= ~(LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN); | ||
| 578 | else | ||
| 579 | tmp |= LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN; | ||
| 580 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
| 581 | |||
| 582 | writel(quot, LPC32XX_HSUART_RATE(port->membase)); | ||
| 583 | |||
| 584 | uart_update_timeout(port, termios->c_cflag, baud); | ||
| 585 | |||
| 586 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 587 | |||
| 588 | /* Don't rewrite B0 */ | ||
| 589 | if (tty_termios_baud_rate(termios)) | ||
| 590 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
| 591 | } | ||
| 592 | |||
| 593 | static const char *serial_lpc32xx_type(struct uart_port *port) | ||
| 594 | { | ||
| 595 | return MODNAME; | ||
| 596 | } | ||
| 597 | |||
| 598 | static void serial_lpc32xx_release_port(struct uart_port *port) | ||
| 599 | { | ||
| 600 | if ((port->iotype == UPIO_MEM32) && (port->mapbase)) { | ||
| 601 | if (port->flags & UPF_IOREMAP) { | ||
| 602 | iounmap(port->membase); | ||
| 603 | port->membase = NULL; | ||
| 604 | } | ||
| 605 | |||
| 606 | release_mem_region(port->mapbase, SZ_4K); | ||
| 607 | } | ||
| 608 | } | ||
| 609 | |||
| 610 | static int serial_lpc32xx_request_port(struct uart_port *port) | ||
| 611 | { | ||
| 612 | int ret = -ENODEV; | ||
| 613 | |||
| 614 | if ((port->iotype == UPIO_MEM32) && (port->mapbase)) { | ||
| 615 | ret = 0; | ||
| 616 | |||
| 617 | if (!request_mem_region(port->mapbase, SZ_4K, MODNAME)) | ||
| 618 | ret = -EBUSY; | ||
| 619 | else if (port->flags & UPF_IOREMAP) { | ||
| 620 | port->membase = ioremap(port->mapbase, SZ_4K); | ||
| 621 | if (!port->membase) { | ||
| 622 | release_mem_region(port->mapbase, SZ_4K); | ||
| 623 | ret = -ENOMEM; | ||
| 624 | } | ||
| 625 | } | ||
| 626 | } | ||
| 627 | |||
| 628 | return ret; | ||
| 629 | } | ||
| 630 | |||
| 631 | static void serial_lpc32xx_config_port(struct uart_port *port, int uflags) | ||
| 632 | { | ||
| 633 | int ret; | ||
| 634 | |||
| 635 | ret = serial_lpc32xx_request_port(port); | ||
| 636 | if (ret < 0) | ||
| 637 | return; | ||
| 638 | port->type = PORT_UART00; | ||
| 639 | port->fifosize = 64; | ||
| 640 | |||
| 641 | __serial_uart_flush(port); | ||
| 642 | |||
| 643 | writel((LPC32XX_HSU_TX_INT | LPC32XX_HSU_FE_INT | | ||
| 644 | LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT), | ||
| 645 | LPC32XX_HSUART_IIR(port->membase)); | ||
| 646 | |||
| 647 | writel(0xFF, LPC32XX_HSUART_RATE(port->membase)); | ||
| 648 | |||
| 649 | /* Set receiver timeout, HSU offset of 20, no break, no interrupts, | ||
| 650 | and default FIFO trigger levels */ | ||
| 651 | writel(LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B | | ||
| 652 | LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B, | ||
| 653 | LPC32XX_HSUART_CTRL(port->membase)); | ||
| 654 | } | ||
| 655 | |||
| 656 | static int serial_lpc32xx_verify_port(struct uart_port *port, | ||
| 657 | struct serial_struct *ser) | ||
| 658 | { | ||
| 659 | int ret = 0; | ||
| 660 | |||
| 661 | if (ser->type != PORT_UART00) | ||
| 662 | ret = -EINVAL; | ||
| 663 | |||
| 664 | return ret; | ||
| 665 | } | ||
| 666 | |||
| 667 | static struct uart_ops serial_lpc32xx_pops = { | ||
| 668 | .tx_empty = serial_lpc32xx_tx_empty, | ||
| 669 | .set_mctrl = serial_lpc32xx_set_mctrl, | ||
| 670 | .get_mctrl = serial_lpc32xx_get_mctrl, | ||
| 671 | .stop_tx = serial_lpc32xx_stop_tx, | ||
| 672 | .start_tx = serial_lpc32xx_start_tx, | ||
| 673 | .stop_rx = serial_lpc32xx_stop_rx, | ||
| 674 | .enable_ms = serial_lpc32xx_enable_ms, | ||
| 675 | .break_ctl = serial_lpc32xx_break_ctl, | ||
| 676 | .startup = serial_lpc32xx_startup, | ||
| 677 | .shutdown = serial_lpc32xx_shutdown, | ||
| 678 | .set_termios = serial_lpc32xx_set_termios, | ||
| 679 | .type = serial_lpc32xx_type, | ||
| 680 | .release_port = serial_lpc32xx_release_port, | ||
| 681 | .request_port = serial_lpc32xx_request_port, | ||
| 682 | .config_port = serial_lpc32xx_config_port, | ||
| 683 | .verify_port = serial_lpc32xx_verify_port, | ||
| 684 | }; | ||
| 685 | |||
| 686 | /* | ||
| 687 | * Register a set of serial devices attached to a platform device | ||
| 688 | */ | ||
| 689 | static int __devinit serial_hs_lpc32xx_probe(struct platform_device *pdev) | ||
| 690 | { | ||
| 691 | struct lpc32xx_hsuart_port *p = &lpc32xx_hs_ports[uarts_registered]; | ||
| 692 | int ret = 0; | ||
| 693 | struct resource *res; | ||
| 694 | |||
| 695 | if (uarts_registered >= MAX_PORTS) { | ||
| 696 | dev_err(&pdev->dev, | ||
| 697 | "Error: Number of possible ports exceeded (%d)!\n", | ||
| 698 | uarts_registered + 1); | ||
| 699 | return -ENXIO; | ||
| 700 | } | ||
| 701 | |||
| 702 | memset(p, 0, sizeof(*p)); | ||
| 703 | |||
| 704 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 705 | if (!res) { | ||
| 706 | dev_err(&pdev->dev, | ||
| 707 | "Error getting mem resource for HS UART port %d\n", | ||
| 708 | uarts_registered); | ||
| 709 | return -ENXIO; | ||
| 710 | } | ||
| 711 | p->port.mapbase = res->start; | ||
| 712 | p->port.membase = NULL; | ||
| 713 | |||
| 714 | p->port.irq = platform_get_irq(pdev, 0); | ||
| 715 | if (p->port.irq < 0) { | ||
| 716 | dev_err(&pdev->dev, "Error getting irq for HS UART port %d\n", | ||
| 717 | uarts_registered); | ||
| 718 | return p->port.irq; | ||
| 719 | } | ||
| 720 | |||
| 721 | p->port.iotype = UPIO_MEM32; | ||
| 722 | p->port.uartclk = LPC32XX_MAIN_OSC_FREQ; | ||
| 723 | p->port.regshift = 2; | ||
| 724 | p->port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_IOREMAP; | ||
| 725 | p->port.dev = &pdev->dev; | ||
| 726 | p->port.ops = &serial_lpc32xx_pops; | ||
| 727 | p->port.line = uarts_registered++; | ||
| 728 | spin_lock_init(&p->port.lock); | ||
| 729 | |||
| 730 | /* send port to loopback mode by default */ | ||
| 731 | lpc32xx_loopback_set(p->port.mapbase, 1); | ||
| 732 | |||
| 733 | ret = uart_add_one_port(&lpc32xx_hs_reg, &p->port); | ||
| 734 | |||
| 735 | platform_set_drvdata(pdev, p); | ||
| 736 | |||
| 737 | return ret; | ||
| 738 | } | ||
| 739 | |||
| 740 | /* | ||
| 741 | * Remove serial ports registered against a platform device. | ||
| 742 | */ | ||
| 743 | static int __devexit serial_hs_lpc32xx_remove(struct platform_device *pdev) | ||
| 744 | { | ||
| 745 | struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev); | ||
| 746 | |||
| 747 | uart_remove_one_port(&lpc32xx_hs_reg, &p->port); | ||
| 748 | |||
| 749 | return 0; | ||
| 750 | } | ||
| 751 | |||
| 752 | |||
| 753 | #ifdef CONFIG_PM | ||
| 754 | static int serial_hs_lpc32xx_suspend(struct platform_device *pdev, | ||
| 755 | pm_message_t state) | ||
| 756 | { | ||
| 757 | struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev); | ||
| 758 | |||
| 759 | uart_suspend_port(&lpc32xx_hs_reg, &p->port); | ||
| 760 | |||
| 761 | return 0; | ||
| 762 | } | ||
| 763 | |||
| 764 | static int serial_hs_lpc32xx_resume(struct platform_device *pdev) | ||
| 765 | { | ||
| 766 | struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev); | ||
| 767 | |||
| 768 | uart_resume_port(&lpc32xx_hs_reg, &p->port); | ||
| 769 | |||
| 770 | return 0; | ||
| 771 | } | ||
| 772 | #else | ||
| 773 | #define serial_hs_lpc32xx_suspend NULL | ||
| 774 | #define serial_hs_lpc32xx_resume NULL | ||
| 775 | #endif | ||
| 776 | |||
| 777 | static const struct of_device_id serial_hs_lpc32xx_dt_ids[] = { | ||
| 778 | { .compatible = "nxp,lpc3220-hsuart" }, | ||
| 779 | { /* sentinel */ } | ||
| 780 | }; | ||
| 781 | |||
| 782 | MODULE_DEVICE_TABLE(of, serial_hs_lpc32xx_dt_ids); | ||
| 783 | |||
| 784 | static struct platform_driver serial_hs_lpc32xx_driver = { | ||
| 785 | .probe = serial_hs_lpc32xx_probe, | ||
| 786 | .remove = __devexit_p(serial_hs_lpc32xx_remove), | ||
| 787 | .suspend = serial_hs_lpc32xx_suspend, | ||
| 788 | .resume = serial_hs_lpc32xx_resume, | ||
| 789 | .driver = { | ||
| 790 | .name = MODNAME, | ||
| 791 | .owner = THIS_MODULE, | ||
| 792 | .of_match_table = serial_hs_lpc32xx_dt_ids, | ||
| 793 | }, | ||
| 794 | }; | ||
| 795 | |||
| 796 | static int __init lpc32xx_hsuart_init(void) | ||
| 797 | { | ||
| 798 | int ret; | ||
| 799 | |||
| 800 | ret = uart_register_driver(&lpc32xx_hs_reg); | ||
| 801 | if (ret) | ||
| 802 | return ret; | ||
| 803 | |||
| 804 | ret = platform_driver_register(&serial_hs_lpc32xx_driver); | ||
| 805 | if (ret) | ||
| 806 | uart_unregister_driver(&lpc32xx_hs_reg); | ||
| 807 | |||
| 808 | return ret; | ||
| 809 | } | ||
| 810 | |||
| 811 | static void __exit lpc32xx_hsuart_exit(void) | ||
| 812 | { | ||
| 813 | platform_driver_unregister(&serial_hs_lpc32xx_driver); | ||
| 814 | uart_unregister_driver(&lpc32xx_hs_reg); | ||
| 815 | } | ||
| 816 | |||
| 817 | module_init(lpc32xx_hsuart_init); | ||
| 818 | module_exit(lpc32xx_hsuart_exit); | ||
| 819 | |||
| 820 | MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>"); | ||
| 821 | MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); | ||
| 822 | MODULE_DESCRIPTION("NXP LPC32XX High Speed UART driver"); | ||
| 823 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index a0703624d5e5..b13949ad3408 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c | |||
| @@ -44,8 +44,6 @@ | |||
| 44 | #include <asm/io.h> | 44 | #include <asm/io.h> |
| 45 | #include <asm/irq.h> | 45 | #include <asm/irq.h> |
| 46 | 46 | ||
| 47 | #define PORT_M32R_BASE PORT_M32R_SIO | ||
| 48 | #define PORT_INDEX(x) (x - PORT_M32R_BASE + 1) | ||
| 49 | #define BAUD_RATE 115200 | 47 | #define BAUD_RATE 115200 |
| 50 | 48 | ||
| 51 | #include <linux/serial_core.h> | 49 | #include <linux/serial_core.h> |
| @@ -132,22 +130,6 @@ struct irq_info { | |||
| 132 | 130 | ||
| 133 | static struct irq_info irq_lists[NR_IRQS]; | 131 | static struct irq_info irq_lists[NR_IRQS]; |
| 134 | 132 | ||
| 135 | /* | ||
| 136 | * Here we define the default xmit fifo size used for each type of UART. | ||
| 137 | */ | ||
| 138 | static const struct serial_uart_config uart_config[] = { | ||
| 139 | [PORT_UNKNOWN] = { | ||
| 140 | .name = "unknown", | ||
| 141 | .dfl_xmit_fifo_size = 1, | ||
| 142 | .flags = 0, | ||
| 143 | }, | ||
| 144 | [PORT_INDEX(PORT_M32R_SIO)] = { | ||
| 145 | .name = "M32RSIO", | ||
| 146 | .dfl_xmit_fifo_size = 1, | ||
| 147 | .flags = 0, | ||
| 148 | }, | ||
| 149 | }; | ||
| 150 | |||
| 151 | #ifdef CONFIG_SERIAL_M32R_PLDSIO | 133 | #ifdef CONFIG_SERIAL_M32R_PLDSIO |
| 152 | 134 | ||
| 153 | #define __sio_in(x) inw((unsigned long)(x)) | 135 | #define __sio_in(x) inw((unsigned long)(x)) |
| @@ -907,8 +889,7 @@ static void m32r_sio_config_port(struct uart_port *port, int unused) | |||
| 907 | 889 | ||
| 908 | spin_lock_irqsave(&up->port.lock, flags); | 890 | spin_lock_irqsave(&up->port.lock, flags); |
| 909 | 891 | ||
| 910 | up->port.type = (PORT_M32R_SIO - PORT_M32R_BASE + 1); | 892 | up->port.fifosize = 1; |
| 911 | up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size; | ||
| 912 | 893 | ||
| 913 | spin_unlock_irqrestore(&up->port.lock, flags); | 894 | spin_unlock_irqrestore(&up->port.lock, flags); |
| 914 | } | 895 | } |
| @@ -916,23 +897,11 @@ static void m32r_sio_config_port(struct uart_port *port, int unused) | |||
| 916 | static int | 897 | static int |
| 917 | m32r_sio_verify_port(struct uart_port *port, struct serial_struct *ser) | 898 | m32r_sio_verify_port(struct uart_port *port, struct serial_struct *ser) |
| 918 | { | 899 | { |
| 919 | if (ser->irq >= nr_irqs || ser->irq < 0 || | 900 | if (ser->irq >= nr_irqs || ser->irq < 0 || ser->baud_base < 9600) |
| 920 | ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || | ||
| 921 | ser->type >= ARRAY_SIZE(uart_config)) | ||
| 922 | return -EINVAL; | 901 | return -EINVAL; |
| 923 | return 0; | 902 | return 0; |
| 924 | } | 903 | } |
| 925 | 904 | ||
| 926 | static const char * | ||
| 927 | m32r_sio_type(struct uart_port *port) | ||
| 928 | { | ||
| 929 | int type = port->type; | ||
| 930 | |||
| 931 | if (type >= ARRAY_SIZE(uart_config)) | ||
| 932 | type = 0; | ||
| 933 | return uart_config[type].name; | ||
| 934 | } | ||
| 935 | |||
| 936 | static struct uart_ops m32r_sio_pops = { | 905 | static struct uart_ops m32r_sio_pops = { |
| 937 | .tx_empty = m32r_sio_tx_empty, | 906 | .tx_empty = m32r_sio_tx_empty, |
| 938 | .set_mctrl = m32r_sio_set_mctrl, | 907 | .set_mctrl = m32r_sio_set_mctrl, |
| @@ -946,7 +915,6 @@ static struct uart_ops m32r_sio_pops = { | |||
| 946 | .shutdown = m32r_sio_shutdown, | 915 | .shutdown = m32r_sio_shutdown, |
| 947 | .set_termios = m32r_sio_set_termios, | 916 | .set_termios = m32r_sio_set_termios, |
| 948 | .pm = m32r_sio_pm, | 917 | .pm = m32r_sio_pm, |
| 949 | .type = m32r_sio_type, | ||
| 950 | .release_port = m32r_sio_release_port, | 918 | .release_port = m32r_sio_release_port, |
| 951 | .request_port = m32r_sio_request_port, | 919 | .request_port = m32r_sio_request_port, |
| 952 | .config_port = m32r_sio_config_port, | 920 | .config_port = m32r_sio_config_port, |
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index b4902b99cfd2..0f24486be532 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c | |||
| @@ -827,14 +827,16 @@ static int __devexit max3100_remove(struct spi_device *spi) | |||
| 827 | 827 | ||
| 828 | /* find out the index for the chip we are removing */ | 828 | /* find out the index for the chip we are removing */ |
| 829 | for (i = 0; i < MAX_MAX3100; i++) | 829 | for (i = 0; i < MAX_MAX3100; i++) |
| 830 | if (max3100s[i] == s) | 830 | if (max3100s[i] == s) { |
| 831 | dev_dbg(&spi->dev, "%s: removing port %d\n", __func__, i); | ||
| 832 | uart_remove_one_port(&max3100_uart_driver, &max3100s[i]->port); | ||
| 833 | kfree(max3100s[i]); | ||
| 834 | max3100s[i] = NULL; | ||
| 831 | break; | 835 | break; |
| 836 | } | ||
| 832 | 837 | ||
| 833 | dev_dbg(&spi->dev, "%s: removing port %d\n", __func__, i); | 838 | WARN_ON(i == MAX_MAX3100); |
| 834 | uart_remove_one_port(&max3100_uart_driver, &max3100s[i]->port); | 839 | |
| 835 | kfree(max3100s[i]); | ||
| 836 | max3100s[i] = NULL; | ||
| 837 | |||
| 838 | /* check if this is the last chip we have */ | 840 | /* check if this is the last chip we have */ |
| 839 | for (i = 0; i < MAX_MAX3100; i++) | 841 | for (i = 0; i < MAX_MAX3100; i++) |
| 840 | if (max3100s[i]) { | 842 | if (max3100s[i]) { |
| @@ -910,17 +912,7 @@ static struct spi_driver max3100_driver = { | |||
| 910 | .resume = max3100_resume, | 912 | .resume = max3100_resume, |
| 911 | }; | 913 | }; |
| 912 | 914 | ||
| 913 | static int __init max3100_init(void) | 915 | module_spi_driver(max3100_driver); |
| 914 | { | ||
| 915 | return spi_register_driver(&max3100_driver); | ||
| 916 | } | ||
| 917 | module_init(max3100_init); | ||
| 918 | |||
| 919 | static void __exit max3100_exit(void) | ||
| 920 | { | ||
| 921 | spi_unregister_driver(&max3100_driver); | ||
| 922 | } | ||
| 923 | module_exit(max3100_exit); | ||
| 924 | 916 | ||
| 925 | MODULE_DESCRIPTION("MAX3100 driver"); | 917 | MODULE_DESCRIPTION("MAX3100 driver"); |
| 926 | MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>"); | 918 | MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>"); |
diff --git a/drivers/tty/serial/max3107.c b/drivers/tty/serial/max3107.c deleted file mode 100644 index 17c7ba805d98..000000000000 --- a/drivers/tty/serial/max3107.c +++ /dev/null | |||
| @@ -1,1215 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * max3107.c - spi uart protocol driver for Maxim 3107 | ||
| 3 | * Based on max3100.c | ||
| 4 | * by Christian Pellegrin <chripell@evolware.org> | ||
| 5 | * and max3110.c | ||
| 6 | * by Feng Tang <feng.tang@intel.com> | ||
| 7 | * | ||
| 8 | * Copyright (C) Aavamobile 2009 | ||
| 9 | * | ||
| 10 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify | ||
| 13 | * it under the terms of the GNU General Public License as published by | ||
| 14 | * the Free Software Foundation; either version 2 of the License, or | ||
| 15 | * (at your option) any later version. | ||
| 16 | * | ||
| 17 | * This program is distributed in the hope that it will be useful, | ||
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 20 | * GNU General Public License for more details. | ||
| 21 | * | ||
| 22 | * You should have received a copy of the GNU General Public License | ||
| 23 | * along with this program; if not, write to the Free Software | ||
| 24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 25 | * | ||
| 26 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 27 | * | ||
| 28 | */ | ||
| 29 | |||
| 30 | #include <linux/delay.h> | ||
| 31 | #include <linux/device.h> | ||
| 32 | #include <linux/serial_core.h> | ||
| 33 | #include <linux/serial.h> | ||
| 34 | #include <linux/tty.h> | ||
| 35 | #include <linux/tty_flip.h> | ||
| 36 | #include <linux/gpio.h> | ||
| 37 | #include <linux/spi/spi.h> | ||
| 38 | #include <linux/freezer.h> | ||
| 39 | #include <linux/module.h> | ||
| 40 | #include "max3107.h" | ||
| 41 | |||
| 42 | static const struct baud_table brg26_ext[] = { | ||
| 43 | { 300, MAX3107_BRG26_B300 }, | ||
| 44 | { 600, MAX3107_BRG26_B600 }, | ||
| 45 | { 1200, MAX3107_BRG26_B1200 }, | ||
| 46 | { 2400, MAX3107_BRG26_B2400 }, | ||
| 47 | { 4800, MAX3107_BRG26_B4800 }, | ||
| 48 | { 9600, MAX3107_BRG26_B9600 }, | ||
| 49 | { 19200, MAX3107_BRG26_B19200 }, | ||
| 50 | { 57600, MAX3107_BRG26_B57600 }, | ||
| 51 | { 115200, MAX3107_BRG26_B115200 }, | ||
| 52 | { 230400, MAX3107_BRG26_B230400 }, | ||
| 53 | { 460800, MAX3107_BRG26_B460800 }, | ||
| 54 | { 921600, MAX3107_BRG26_B921600 }, | ||
| 55 | { 0, 0 } | ||
| 56 | }; | ||
| 57 | |||
| 58 | static const struct baud_table brg13_int[] = { | ||
| 59 | { 300, MAX3107_BRG13_IB300 }, | ||
| 60 | { 600, MAX3107_BRG13_IB600 }, | ||
| 61 | { 1200, MAX3107_BRG13_IB1200 }, | ||
| 62 | { 2400, MAX3107_BRG13_IB2400 }, | ||
| 63 | { 4800, MAX3107_BRG13_IB4800 }, | ||
| 64 | { 9600, MAX3107_BRG13_IB9600 }, | ||
| 65 | { 19200, MAX3107_BRG13_IB19200 }, | ||
| 66 | { 57600, MAX3107_BRG13_IB57600 }, | ||
| 67 | { 115200, MAX3107_BRG13_IB115200 }, | ||
| 68 | { 230400, MAX3107_BRG13_IB230400 }, | ||
| 69 | { 460800, MAX3107_BRG13_IB460800 }, | ||
| 70 | { 921600, MAX3107_BRG13_IB921600 }, | ||
| 71 | { 0, 0 } | ||
| 72 | }; | ||
| 73 | |||
| 74 | static u32 get_new_brg(int baud, struct max3107_port *s) | ||
| 75 | { | ||
| 76 | int i; | ||
| 77 | const struct baud_table *baud_tbl = s->baud_tbl; | ||
| 78 | |||
| 79 | for (i = 0; i < 13; i++) { | ||
| 80 | if (baud == baud_tbl[i].baud) | ||
| 81 | return baud_tbl[i].new_brg; | ||
| 82 | } | ||
| 83 | |||
| 84 | return 0; | ||
| 85 | } | ||
| 86 | |||
| 87 | /* Perform SPI transfer for write/read of device register(s) */ | ||
| 88 | int max3107_rw(struct max3107_port *s, u8 *tx, u8 *rx, int len) | ||
| 89 | { | ||
| 90 | struct spi_message spi_msg; | ||
| 91 | struct spi_transfer spi_xfer; | ||
| 92 | |||
| 93 | /* Initialize SPI ,message */ | ||
| 94 | spi_message_init(&spi_msg); | ||
| 95 | |||
| 96 | /* Initialize SPI transfer */ | ||
| 97 | memset(&spi_xfer, 0, sizeof spi_xfer); | ||
| 98 | spi_xfer.len = len; | ||
| 99 | spi_xfer.tx_buf = tx; | ||
| 100 | spi_xfer.rx_buf = rx; | ||
| 101 | spi_xfer.speed_hz = MAX3107_SPI_SPEED; | ||
| 102 | |||
| 103 | /* Add SPI transfer to SPI message */ | ||
| 104 | spi_message_add_tail(&spi_xfer, &spi_msg); | ||
| 105 | |||
| 106 | #ifdef DBG_TRACE_SPI_DATA | ||
| 107 | { | ||
| 108 | int i; | ||
| 109 | pr_info("tx len %d:\n", spi_xfer.len); | ||
| 110 | for (i = 0 ; i < spi_xfer.len && i < 32 ; i++) | ||
| 111 | pr_info(" %x", ((u8 *)spi_xfer.tx_buf)[i]); | ||
| 112 | pr_info("\n"); | ||
| 113 | } | ||
| 114 | #endif | ||
| 115 | |||
| 116 | /* Perform synchronous SPI transfer */ | ||
| 117 | if (spi_sync(s->spi, &spi_msg)) { | ||
| 118 | dev_err(&s->spi->dev, "spi_sync failure\n"); | ||
| 119 | return -EIO; | ||
| 120 | } | ||
| 121 | |||
| 122 | #ifdef DBG_TRACE_SPI_DATA | ||
| 123 | if (spi_xfer.rx_buf) { | ||
| 124 | int i; | ||
| 125 | pr_info("rx len %d:\n", spi_xfer.len); | ||
| 126 | for (i = 0 ; i < spi_xfer.len && i < 32 ; i++) | ||
| 127 | pr_info(" %x", ((u8 *)spi_xfer.rx_buf)[i]); | ||
| 128 | pr_info("\n"); | ||
| 129 | } | ||
| 130 | #endif | ||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | EXPORT_SYMBOL_GPL(max3107_rw); | ||
| 134 | |||
| 135 | /* Puts received data to circular buffer */ | ||
| 136 | static void put_data_to_circ_buf(struct max3107_port *s, unsigned char *data, | ||
| 137 | int len) | ||
| 138 | { | ||
| 139 | struct uart_port *port = &s->port; | ||
| 140 | struct tty_struct *tty; | ||
| 141 | |||
| 142 | if (!port->state) | ||
| 143 | return; | ||
| 144 | |||
| 145 | tty = port->state->port.tty; | ||
| 146 | if (!tty) | ||
| 147 | return; | ||
| 148 | |||
| 149 | /* Insert received data */ | ||
| 150 | tty_insert_flip_string(tty, data, len); | ||
| 151 | /* Update RX counter */ | ||
| 152 | port->icount.rx += len; | ||
| 153 | } | ||
| 154 | |||
| 155 | /* Handle data receiving */ | ||
| 156 | static void max3107_handlerx(struct max3107_port *s, u16 rxlvl) | ||
| 157 | { | ||
| 158 | int i; | ||
| 159 | int j; | ||
| 160 | int len; /* SPI transfer buffer length */ | ||
| 161 | u16 *buf; | ||
| 162 | u8 *valid_str; | ||
| 163 | |||
| 164 | if (!s->rx_enabled) | ||
| 165 | /* RX is disabled */ | ||
| 166 | return; | ||
| 167 | |||
| 168 | if (rxlvl == 0) { | ||
| 169 | /* RX fifo is empty */ | ||
| 170 | return; | ||
| 171 | } else if (rxlvl >= MAX3107_RX_FIFO_SIZE) { | ||
| 172 | dev_warn(&s->spi->dev, "Possible RX FIFO overrun %d\n", rxlvl); | ||
| 173 | /* Ensure sanity of RX level */ | ||
| 174 | rxlvl = MAX3107_RX_FIFO_SIZE; | ||
| 175 | } | ||
| 176 | if ((s->rxbuf == 0) || (s->rxstr == 0)) { | ||
| 177 | dev_warn(&s->spi->dev, "Rx buffer/str isn't ready\n"); | ||
| 178 | return; | ||
| 179 | } | ||
| 180 | buf = s->rxbuf; | ||
| 181 | valid_str = s->rxstr; | ||
| 182 | while (rxlvl) { | ||
| 183 | pr_debug("rxlvl %d\n", rxlvl); | ||
| 184 | /* Clear buffer */ | ||
| 185 | memset(buf, 0, sizeof(u16) * (MAX3107_RX_FIFO_SIZE + 2)); | ||
| 186 | len = 0; | ||
| 187 | if (s->irqen_reg & MAX3107_IRQ_RXFIFO_BIT) { | ||
| 188 | /* First disable RX FIFO interrupt */ | ||
| 189 | pr_debug("Disabling RX INT\n"); | ||
| 190 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); | ||
| 191 | s->irqen_reg &= ~MAX3107_IRQ_RXFIFO_BIT; | ||
| 192 | buf[0] |= s->irqen_reg; | ||
| 193 | len++; | ||
| 194 | } | ||
| 195 | /* Just increase the length by amount of words in FIFO since | ||
| 196 | * buffer was zeroed and SPI transfer of 0x0000 means reading | ||
| 197 | * from RX FIFO | ||
| 198 | */ | ||
| 199 | len += rxlvl; | ||
| 200 | /* Append RX level query */ | ||
| 201 | buf[len] = MAX3107_RXFIFOLVL_REG; | ||
| 202 | len++; | ||
| 203 | |||
| 204 | /* Perform the SPI transfer */ | ||
| 205 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, len * 2)) { | ||
| 206 | dev_err(&s->spi->dev, "SPI transfer for RX h failed\n"); | ||
| 207 | return; | ||
| 208 | } | ||
| 209 | |||
| 210 | /* Skip RX FIFO interrupt disabling word if it was added */ | ||
| 211 | j = ((len - 1) - rxlvl); | ||
| 212 | /* Read received words */ | ||
| 213 | for (i = 0; i < rxlvl; i++, j++) | ||
| 214 | valid_str[i] = (u8)buf[j]; | ||
| 215 | put_data_to_circ_buf(s, valid_str, rxlvl); | ||
| 216 | /* Get new RX level */ | ||
| 217 | rxlvl = (buf[len - 1] & MAX3107_SPI_RX_DATA_MASK); | ||
| 218 | } | ||
| 219 | |||
| 220 | if (s->rx_enabled) { | ||
| 221 | /* RX still enabled, re-enable RX FIFO interrupt */ | ||
| 222 | pr_debug("Enabling RX INT\n"); | ||
| 223 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); | ||
| 224 | s->irqen_reg |= MAX3107_IRQ_RXFIFO_BIT; | ||
| 225 | buf[0] |= s->irqen_reg; | ||
| 226 | if (max3107_rw(s, (u8 *)buf, NULL, 2)) | ||
| 227 | dev_err(&s->spi->dev, "RX FIFO INT enabling failed\n"); | ||
| 228 | } | ||
| 229 | |||
| 230 | /* Push the received data to receivers */ | ||
| 231 | if (s->port.state->port.tty) | ||
| 232 | tty_flip_buffer_push(s->port.state->port.tty); | ||
| 233 | } | ||
| 234 | |||
| 235 | |||
| 236 | /* Handle data sending */ | ||
| 237 | static void max3107_handletx(struct max3107_port *s) | ||
| 238 | { | ||
| 239 | struct circ_buf *xmit = &s->port.state->xmit; | ||
| 240 | int i; | ||
| 241 | unsigned long flags; | ||
| 242 | int len; /* SPI transfer buffer length */ | ||
| 243 | u16 *buf; | ||
| 244 | |||
| 245 | if (!s->tx_fifo_empty) | ||
| 246 | /* Don't send more data before previous data is sent */ | ||
| 247 | return; | ||
| 248 | |||
| 249 | if (uart_circ_empty(xmit) || uart_tx_stopped(&s->port)) | ||
| 250 | /* No data to send or TX is stopped */ | ||
| 251 | return; | ||
| 252 | |||
| 253 | if (!s->txbuf) { | ||
| 254 | dev_warn(&s->spi->dev, "Txbuf isn't ready\n"); | ||
| 255 | return; | ||
| 256 | } | ||
| 257 | buf = s->txbuf; | ||
| 258 | /* Get length of data pending in circular buffer */ | ||
| 259 | len = uart_circ_chars_pending(xmit); | ||
| 260 | if (len) { | ||
| 261 | /* Limit to size of TX FIFO */ | ||
| 262 | if (len > MAX3107_TX_FIFO_SIZE) | ||
| 263 | len = MAX3107_TX_FIFO_SIZE; | ||
| 264 | |||
| 265 | pr_debug("txlen %d\n", len); | ||
| 266 | |||
| 267 | /* Update TX counter */ | ||
| 268 | s->port.icount.tx += len; | ||
| 269 | |||
| 270 | /* TX FIFO will no longer be empty */ | ||
| 271 | s->tx_fifo_empty = 0; | ||
| 272 | |||
| 273 | i = 0; | ||
| 274 | if (s->irqen_reg & MAX3107_IRQ_TXEMPTY_BIT) { | ||
| 275 | /* First disable TX empty interrupt */ | ||
| 276 | pr_debug("Disabling TE INT\n"); | ||
| 277 | buf[i] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); | ||
| 278 | s->irqen_reg &= ~MAX3107_IRQ_TXEMPTY_BIT; | ||
| 279 | buf[i] |= s->irqen_reg; | ||
| 280 | i++; | ||
| 281 | len++; | ||
| 282 | } | ||
| 283 | /* Add data to send */ | ||
| 284 | spin_lock_irqsave(&s->port.lock, flags); | ||
| 285 | for ( ; i < len ; i++) { | ||
| 286 | buf[i] = (MAX3107_WRITE_BIT | MAX3107_THR_REG); | ||
| 287 | buf[i] |= ((u16)xmit->buf[xmit->tail] & | ||
| 288 | MAX3107_SPI_TX_DATA_MASK); | ||
| 289 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
| 290 | } | ||
| 291 | spin_unlock_irqrestore(&s->port.lock, flags); | ||
| 292 | if (!(s->irqen_reg & MAX3107_IRQ_TXEMPTY_BIT)) { | ||
| 293 | /* Enable TX empty interrupt */ | ||
| 294 | pr_debug("Enabling TE INT\n"); | ||
| 295 | buf[i] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); | ||
| 296 | s->irqen_reg |= MAX3107_IRQ_TXEMPTY_BIT; | ||
| 297 | buf[i] |= s->irqen_reg; | ||
| 298 | i++; | ||
| 299 | len++; | ||
| 300 | } | ||
| 301 | if (!s->tx_enabled) { | ||
| 302 | /* Enable TX */ | ||
| 303 | pr_debug("Enable TX\n"); | ||
| 304 | buf[i] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); | ||
| 305 | spin_lock_irqsave(&s->data_lock, flags); | ||
| 306 | s->mode1_reg &= ~MAX3107_MODE1_TXDIS_BIT; | ||
| 307 | buf[i] |= s->mode1_reg; | ||
| 308 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
| 309 | s->tx_enabled = 1; | ||
| 310 | i++; | ||
| 311 | len++; | ||
| 312 | } | ||
| 313 | |||
| 314 | /* Perform the SPI transfer */ | ||
| 315 | if (max3107_rw(s, (u8 *)buf, NULL, len*2)) { | ||
| 316 | dev_err(&s->spi->dev, | ||
| 317 | "SPI transfer TX handling failed\n"); | ||
| 318 | return; | ||
| 319 | } | ||
| 320 | } | ||
| 321 | |||
| 322 | /* Indicate wake up if circular buffer is getting low on data */ | ||
| 323 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
| 324 | uart_write_wakeup(&s->port); | ||
| 325 | |||
| 326 | } | ||
| 327 | |||
| 328 | /* Handle interrupts | ||
| 329 | * Also reads and returns current RX FIFO level | ||
| 330 | */ | ||
| 331 | static u16 handle_interrupt(struct max3107_port *s) | ||
| 332 | { | ||
| 333 | u16 buf[4]; /* Buffer for SPI transfers */ | ||
| 334 | u8 irq_status; | ||
| 335 | u16 rx_level; | ||
| 336 | unsigned long flags; | ||
| 337 | |||
| 338 | /* Read IRQ status register */ | ||
| 339 | buf[0] = MAX3107_IRQSTS_REG; | ||
| 340 | /* Read status IRQ status register */ | ||
| 341 | buf[1] = MAX3107_STS_IRQSTS_REG; | ||
| 342 | /* Read LSR IRQ status register */ | ||
| 343 | buf[2] = MAX3107_LSR_IRQSTS_REG; | ||
| 344 | /* Query RX level */ | ||
| 345 | buf[3] = MAX3107_RXFIFOLVL_REG; | ||
| 346 | |||
| 347 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 8)) { | ||
| 348 | dev_err(&s->spi->dev, | ||
| 349 | "SPI transfer for INTR handling failed\n"); | ||
| 350 | return 0; | ||
| 351 | } | ||
| 352 | |||
| 353 | irq_status = (u8)buf[0]; | ||
| 354 | pr_debug("IRQSTS %x\n", irq_status); | ||
| 355 | rx_level = (buf[3] & MAX3107_SPI_RX_DATA_MASK); | ||
| 356 | |||
| 357 | if (irq_status & MAX3107_IRQ_LSR_BIT) { | ||
| 358 | /* LSR interrupt */ | ||
| 359 | if (buf[2] & MAX3107_LSR_RXTO_BIT) | ||
| 360 | /* RX timeout interrupt, | ||
| 361 | * handled by normal RX handling | ||
| 362 | */ | ||
| 363 | pr_debug("RX TO INT\n"); | ||
| 364 | } | ||
| 365 | |||
| 366 | if (irq_status & MAX3107_IRQ_TXEMPTY_BIT) { | ||
| 367 | /* Tx empty interrupt, | ||
| 368 | * disable TX and set tx_fifo_empty flag | ||
| 369 | */ | ||
| 370 | pr_debug("TE INT, disabling TX\n"); | ||
| 371 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); | ||
| 372 | spin_lock_irqsave(&s->data_lock, flags); | ||
| 373 | s->mode1_reg |= MAX3107_MODE1_TXDIS_BIT; | ||
| 374 | buf[0] |= s->mode1_reg; | ||
| 375 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
| 376 | if (max3107_rw(s, (u8 *)buf, NULL, 2)) | ||
| 377 | dev_err(&s->spi->dev, "SPI transfer TX dis failed\n"); | ||
| 378 | s->tx_enabled = 0; | ||
| 379 | s->tx_fifo_empty = 1; | ||
| 380 | } | ||
| 381 | |||
| 382 | if (irq_status & MAX3107_IRQ_RXFIFO_BIT) | ||
| 383 | /* RX FIFO interrupt, | ||
| 384 | * handled by normal RX handling | ||
| 385 | */ | ||
| 386 | pr_debug("RFIFO INT\n"); | ||
| 387 | |||
| 388 | /* Return RX level */ | ||
| 389 | return rx_level; | ||
| 390 | } | ||
| 391 | |||
| 392 | /* Trigger work thread*/ | ||
| 393 | static void max3107_dowork(struct max3107_port *s) | ||
| 394 | { | ||
| 395 | if (!work_pending(&s->work) && !freezing(current) && !s->suspended) | ||
| 396 | queue_work(s->workqueue, &s->work); | ||
| 397 | else | ||
| 398 | dev_warn(&s->spi->dev, "interrup isn't serviced normally!\n"); | ||
| 399 | } | ||
| 400 | |||
| 401 | /* Work thread */ | ||
| 402 | static void max3107_work(struct work_struct *w) | ||
| 403 | { | ||
| 404 | struct max3107_port *s = container_of(w, struct max3107_port, work); | ||
| 405 | u16 rxlvl = 0; | ||
| 406 | int len; /* SPI transfer buffer length */ | ||
| 407 | u16 buf[5]; /* Buffer for SPI transfers */ | ||
| 408 | unsigned long flags; | ||
| 409 | |||
| 410 | /* Start by reading current RX FIFO level */ | ||
| 411 | buf[0] = MAX3107_RXFIFOLVL_REG; | ||
| 412 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { | ||
| 413 | dev_err(&s->spi->dev, "SPI transfer RX lev failed\n"); | ||
| 414 | rxlvl = 0; | ||
| 415 | } else { | ||
| 416 | rxlvl = (buf[0] & MAX3107_SPI_RX_DATA_MASK); | ||
| 417 | } | ||
| 418 | |||
| 419 | do { | ||
| 420 | pr_debug("rxlvl %d\n", rxlvl); | ||
| 421 | |||
| 422 | /* Handle RX */ | ||
| 423 | max3107_handlerx(s, rxlvl); | ||
| 424 | rxlvl = 0; | ||
| 425 | |||
| 426 | if (s->handle_irq) { | ||
| 427 | /* Handle pending interrupts | ||
| 428 | * We also get new RX FIFO level since new data may | ||
| 429 | * have been received while pushing received data to | ||
| 430 | * receivers | ||
| 431 | */ | ||
| 432 | s->handle_irq = 0; | ||
| 433 | rxlvl = handle_interrupt(s); | ||
| 434 | } | ||
| 435 | |||
| 436 | /* Handle TX */ | ||
| 437 | max3107_handletx(s); | ||
| 438 | |||
| 439 | /* Handle configuration changes */ | ||
| 440 | len = 0; | ||
| 441 | spin_lock_irqsave(&s->data_lock, flags); | ||
| 442 | if (s->mode1_commit) { | ||
| 443 | pr_debug("mode1_commit\n"); | ||
| 444 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); | ||
| 445 | buf[len++] |= s->mode1_reg; | ||
| 446 | s->mode1_commit = 0; | ||
| 447 | } | ||
| 448 | if (s->lcr_commit) { | ||
| 449 | pr_debug("lcr_commit\n"); | ||
| 450 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_LCR_REG); | ||
| 451 | buf[len++] |= s->lcr_reg; | ||
| 452 | s->lcr_commit = 0; | ||
| 453 | } | ||
| 454 | if (s->brg_commit) { | ||
| 455 | pr_debug("brg_commit\n"); | ||
| 456 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVMSB_REG); | ||
| 457 | buf[len++] |= ((s->brg_cfg >> 16) & | ||
| 458 | MAX3107_SPI_TX_DATA_MASK); | ||
| 459 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVLSB_REG); | ||
| 460 | buf[len++] |= ((s->brg_cfg >> 8) & | ||
| 461 | MAX3107_SPI_TX_DATA_MASK); | ||
| 462 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGCFG_REG); | ||
| 463 | buf[len++] |= ((s->brg_cfg) & 0xff); | ||
| 464 | s->brg_commit = 0; | ||
| 465 | } | ||
| 466 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
| 467 | |||
| 468 | if (len > 0) { | ||
| 469 | if (max3107_rw(s, (u8 *)buf, NULL, len * 2)) | ||
| 470 | dev_err(&s->spi->dev, | ||
| 471 | "SPI transfer config failed\n"); | ||
| 472 | } | ||
| 473 | |||
| 474 | /* Reloop if interrupt handling indicated data in RX FIFO */ | ||
| 475 | } while (rxlvl); | ||
| 476 | |||
| 477 | } | ||
| 478 | |||
| 479 | /* Set sleep mode */ | ||
| 480 | static void max3107_set_sleep(struct max3107_port *s, int mode) | ||
| 481 | { | ||
| 482 | u16 buf[1]; /* Buffer for SPI transfer */ | ||
| 483 | unsigned long flags; | ||
| 484 | pr_debug("enter, mode %d\n", mode); | ||
| 485 | |||
| 486 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); | ||
| 487 | spin_lock_irqsave(&s->data_lock, flags); | ||
| 488 | switch (mode) { | ||
| 489 | case MAX3107_DISABLE_FORCED_SLEEP: | ||
| 490 | s->mode1_reg &= ~MAX3107_MODE1_FORCESLEEP_BIT; | ||
| 491 | break; | ||
| 492 | case MAX3107_ENABLE_FORCED_SLEEP: | ||
| 493 | s->mode1_reg |= MAX3107_MODE1_FORCESLEEP_BIT; | ||
| 494 | break; | ||
| 495 | case MAX3107_DISABLE_AUTOSLEEP: | ||
| 496 | s->mode1_reg &= ~MAX3107_MODE1_AUTOSLEEP_BIT; | ||
| 497 | break; | ||
| 498 | case MAX3107_ENABLE_AUTOSLEEP: | ||
| 499 | s->mode1_reg |= MAX3107_MODE1_AUTOSLEEP_BIT; | ||
| 500 | break; | ||
| 501 | default: | ||
| 502 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
| 503 | dev_warn(&s->spi->dev, "invalid sleep mode\n"); | ||
| 504 | return; | ||
| 505 | } | ||
| 506 | buf[0] |= s->mode1_reg; | ||
| 507 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
| 508 | |||
| 509 | if (max3107_rw(s, (u8 *)buf, NULL, 2)) | ||
| 510 | dev_err(&s->spi->dev, "SPI transfer sleep mode failed\n"); | ||
| 511 | |||
| 512 | if (mode == MAX3107_DISABLE_AUTOSLEEP || | ||
| 513 | mode == MAX3107_DISABLE_FORCED_SLEEP) | ||
| 514 | msleep(MAX3107_WAKEUP_DELAY); | ||
| 515 | } | ||
| 516 | |||
| 517 | /* Perform full register initialization */ | ||
| 518 | static void max3107_register_init(struct max3107_port *s) | ||
| 519 | { | ||
| 520 | u16 buf[11]; /* Buffer for SPI transfers */ | ||
| 521 | |||
| 522 | /* 1. Configure baud rate, 9600 as default */ | ||
| 523 | s->baud = 9600; | ||
| 524 | /* the below is default*/ | ||
| 525 | if (s->ext_clk) { | ||
| 526 | s->brg_cfg = MAX3107_BRG26_B9600; | ||
| 527 | s->baud_tbl = (struct baud_table *)brg26_ext; | ||
| 528 | } else { | ||
| 529 | s->brg_cfg = MAX3107_BRG13_IB9600; | ||
| 530 | s->baud_tbl = (struct baud_table *)brg13_int; | ||
| 531 | } | ||
| 532 | |||
| 533 | if (s->pdata->init) | ||
| 534 | s->pdata->init(s); | ||
| 535 | |||
| 536 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVMSB_REG) | ||
| 537 | | ((s->brg_cfg >> 16) & MAX3107_SPI_TX_DATA_MASK); | ||
| 538 | buf[1] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVLSB_REG) | ||
| 539 | | ((s->brg_cfg >> 8) & MAX3107_SPI_TX_DATA_MASK); | ||
| 540 | buf[2] = (MAX3107_WRITE_BIT | MAX3107_BRGCFG_REG) | ||
| 541 | | ((s->brg_cfg) & 0xff); | ||
| 542 | |||
| 543 | /* 2. Configure LCR register, 8N1 mode by default */ | ||
| 544 | s->lcr_reg = MAX3107_LCR_WORD_LEN_8; | ||
| 545 | buf[3] = (MAX3107_WRITE_BIT | MAX3107_LCR_REG) | ||
| 546 | | s->lcr_reg; | ||
| 547 | |||
| 548 | /* 3. Configure MODE 1 register */ | ||
| 549 | s->mode1_reg = 0; | ||
| 550 | /* Enable IRQ pin */ | ||
| 551 | s->mode1_reg |= MAX3107_MODE1_IRQSEL_BIT; | ||
| 552 | /* Disable TX */ | ||
| 553 | s->mode1_reg |= MAX3107_MODE1_TXDIS_BIT; | ||
| 554 | s->tx_enabled = 0; | ||
| 555 | /* RX is enabled */ | ||
| 556 | s->rx_enabled = 1; | ||
| 557 | buf[4] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG) | ||
| 558 | | s->mode1_reg; | ||
| 559 | |||
| 560 | /* 4. Configure MODE 2 register */ | ||
| 561 | buf[5] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG); | ||
| 562 | if (s->loopback) { | ||
| 563 | /* Enable loopback */ | ||
| 564 | buf[5] |= MAX3107_MODE2_LOOPBACK_BIT; | ||
| 565 | } | ||
| 566 | /* Reset FIFOs */ | ||
| 567 | buf[5] |= MAX3107_MODE2_FIFORST_BIT; | ||
| 568 | s->tx_fifo_empty = 1; | ||
| 569 | |||
| 570 | /* 5. Configure FIFO trigger level register */ | ||
| 571 | buf[6] = (MAX3107_WRITE_BIT | MAX3107_FIFOTRIGLVL_REG); | ||
| 572 | /* RX FIFO trigger for 16 words, TX FIFO trigger not used */ | ||
| 573 | buf[6] |= (MAX3107_FIFOTRIGLVL_RX(16) | MAX3107_FIFOTRIGLVL_TX(0)); | ||
| 574 | |||
| 575 | /* 6. Configure flow control levels */ | ||
| 576 | buf[7] = (MAX3107_WRITE_BIT | MAX3107_FLOWLVL_REG); | ||
| 577 | /* Flow control halt level 96, resume level 48 */ | ||
| 578 | buf[7] |= (MAX3107_FLOWLVL_RES(48) | MAX3107_FLOWLVL_HALT(96)); | ||
| 579 | |||
| 580 | /* 7. Configure flow control */ | ||
| 581 | buf[8] = (MAX3107_WRITE_BIT | MAX3107_FLOWCTRL_REG); | ||
| 582 | /* Enable auto CTS and auto RTS flow control */ | ||
| 583 | buf[8] |= (MAX3107_FLOWCTRL_AUTOCTS_BIT | MAX3107_FLOWCTRL_AUTORTS_BIT); | ||
| 584 | |||
| 585 | /* 8. Configure RX timeout register */ | ||
| 586 | buf[9] = (MAX3107_WRITE_BIT | MAX3107_RXTO_REG); | ||
| 587 | /* Timeout after 48 character intervals */ | ||
| 588 | buf[9] |= 0x0030; | ||
| 589 | |||
| 590 | /* 9. Configure LSR interrupt enable register */ | ||
| 591 | buf[10] = (MAX3107_WRITE_BIT | MAX3107_LSR_IRQEN_REG); | ||
| 592 | /* Enable RX timeout interrupt */ | ||
| 593 | buf[10] |= MAX3107_LSR_RXTO_BIT; | ||
| 594 | |||
| 595 | /* Perform SPI transfer */ | ||
| 596 | if (max3107_rw(s, (u8 *)buf, NULL, 22)) | ||
| 597 | dev_err(&s->spi->dev, "SPI transfer for init failed\n"); | ||
| 598 | |||
| 599 | /* 10. Clear IRQ status register by reading it */ | ||
| 600 | buf[0] = MAX3107_IRQSTS_REG; | ||
| 601 | |||
| 602 | /* 11. Configure interrupt enable register */ | ||
| 603 | /* Enable LSR interrupt */ | ||
| 604 | s->irqen_reg = MAX3107_IRQ_LSR_BIT; | ||
| 605 | /* Enable RX FIFO interrupt */ | ||
| 606 | s->irqen_reg |= MAX3107_IRQ_RXFIFO_BIT; | ||
| 607 | buf[1] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG) | ||
| 608 | | s->irqen_reg; | ||
| 609 | |||
| 610 | /* 12. Clear FIFO reset that was set in step 6 */ | ||
| 611 | buf[2] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG); | ||
| 612 | if (s->loopback) { | ||
| 613 | /* Keep loopback enabled */ | ||
| 614 | buf[2] |= MAX3107_MODE2_LOOPBACK_BIT; | ||
| 615 | } | ||
| 616 | |||
| 617 | /* Perform SPI transfer */ | ||
| 618 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 6)) | ||
| 619 | dev_err(&s->spi->dev, "SPI transfer for init failed\n"); | ||
| 620 | |||
| 621 | } | ||
| 622 | |||
| 623 | /* IRQ handler */ | ||
| 624 | static irqreturn_t max3107_irq(int irqno, void *dev_id) | ||
| 625 | { | ||
| 626 | struct max3107_port *s = dev_id; | ||
| 627 | |||
| 628 | if (irqno != s->spi->irq) { | ||
| 629 | /* Unexpected IRQ */ | ||
| 630 | return IRQ_NONE; | ||
| 631 | } | ||
| 632 | |||
| 633 | /* Indicate irq */ | ||
| 634 | s->handle_irq = 1; | ||
| 635 | |||
| 636 | /* Trigger work thread */ | ||
| 637 | max3107_dowork(s); | ||
| 638 | |||
| 639 | return IRQ_HANDLED; | ||
| 640 | } | ||
| 641 | |||
| 642 | /* HW suspension function | ||
| 643 | * | ||
| 644 | * Currently autosleep is used to decrease current consumption, alternative | ||
| 645 | * approach would be to set the chip to reset mode if UART is not being | ||
| 646 | * used but that would mess the GPIOs | ||
| 647 | * | ||
| 648 | */ | ||
| 649 | void max3107_hw_susp(struct max3107_port *s, int suspend) | ||
| 650 | { | ||
| 651 | pr_debug("enter, suspend %d\n", suspend); | ||
| 652 | |||
| 653 | if (suspend) { | ||
| 654 | /* Suspend requested, | ||
| 655 | * enable autosleep to decrease current consumption | ||
| 656 | */ | ||
| 657 | s->suspended = 1; | ||
| 658 | max3107_set_sleep(s, MAX3107_ENABLE_AUTOSLEEP); | ||
| 659 | } else { | ||
| 660 | /* Resume requested, | ||
| 661 | * disable autosleep | ||
| 662 | */ | ||
| 663 | s->suspended = 0; | ||
| 664 | max3107_set_sleep(s, MAX3107_DISABLE_AUTOSLEEP); | ||
| 665 | } | ||
| 666 | } | ||
| 667 | EXPORT_SYMBOL_GPL(max3107_hw_susp); | ||
| 668 | |||
| 669 | /* Modem status IRQ enabling */ | ||
| 670 | static void max3107_enable_ms(struct uart_port *port) | ||
| 671 | { | ||
| 672 | /* Modem status not supported */ | ||
| 673 | } | ||
| 674 | |||
| 675 | /* Data send function */ | ||
| 676 | static void max3107_start_tx(struct uart_port *port) | ||
| 677 | { | ||
| 678 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
| 679 | |||
| 680 | /* Trigger work thread for sending data */ | ||
| 681 | max3107_dowork(s); | ||
| 682 | } | ||
| 683 | |||
| 684 | /* Function for checking that there is no pending transfers */ | ||
| 685 | static unsigned int max3107_tx_empty(struct uart_port *port) | ||
| 686 | { | ||
| 687 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
| 688 | |||
| 689 | pr_debug("returning %d\n", | ||
| 690 | (s->tx_fifo_empty && uart_circ_empty(&s->port.state->xmit))); | ||
| 691 | return s->tx_fifo_empty && uart_circ_empty(&s->port.state->xmit); | ||
| 692 | } | ||
| 693 | |||
| 694 | /* Function for stopping RX */ | ||
| 695 | static void max3107_stop_rx(struct uart_port *port) | ||
| 696 | { | ||
| 697 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
| 698 | unsigned long flags; | ||
| 699 | |||
| 700 | /* Set RX disabled in MODE 1 register */ | ||
| 701 | spin_lock_irqsave(&s->data_lock, flags); | ||
| 702 | s->mode1_reg |= MAX3107_MODE1_RXDIS_BIT; | ||
| 703 | s->mode1_commit = 1; | ||
| 704 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
| 705 | /* Set RX disabled */ | ||
| 706 | s->rx_enabled = 0; | ||
| 707 | /* Trigger work thread for doing the actual configuration change */ | ||
| 708 | max3107_dowork(s); | ||
| 709 | } | ||
| 710 | |||
| 711 | /* Function for returning control pin states */ | ||
| 712 | static unsigned int max3107_get_mctrl(struct uart_port *port) | ||
| 713 | { | ||
| 714 | /* DCD and DSR are not wired and CTS/RTS is handled automatically | ||
| 715 | * so just indicate DSR and CAR asserted | ||
| 716 | */ | ||
| 717 | return TIOCM_DSR | TIOCM_CAR; | ||
| 718 | } | ||
| 719 | |||
| 720 | /* Function for setting control pin states */ | ||
| 721 | static void max3107_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
| 722 | { | ||
| 723 | /* DCD and DSR are not wired and CTS/RTS is hadnled automatically | ||
| 724 | * so do nothing | ||
| 725 | */ | ||
| 726 | } | ||
| 727 | |||
| 728 | /* Function for configuring UART parameters */ | ||
| 729 | static void max3107_set_termios(struct uart_port *port, | ||
| 730 | struct ktermios *termios, | ||
| 731 | struct ktermios *old) | ||
| 732 | { | ||
| 733 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
| 734 | struct tty_struct *tty; | ||
| 735 | int baud; | ||
| 736 | u16 new_lcr = 0; | ||
| 737 | u32 new_brg = 0; | ||
| 738 | unsigned long flags; | ||
| 739 | |||
| 740 | if (!port->state) | ||
| 741 | return; | ||
| 742 | |||
| 743 | tty = port->state->port.tty; | ||
| 744 | if (!tty) | ||
| 745 | return; | ||
| 746 | |||
| 747 | /* Get new LCR register values */ | ||
| 748 | /* Word size */ | ||
| 749 | if ((termios->c_cflag & CSIZE) == CS7) | ||
| 750 | new_lcr |= MAX3107_LCR_WORD_LEN_7; | ||
| 751 | else | ||
| 752 | new_lcr |= MAX3107_LCR_WORD_LEN_8; | ||
| 753 | |||
| 754 | /* Parity */ | ||
| 755 | if (termios->c_cflag & PARENB) { | ||
| 756 | new_lcr |= MAX3107_LCR_PARITY_BIT; | ||
| 757 | if (!(termios->c_cflag & PARODD)) | ||
| 758 | new_lcr |= MAX3107_LCR_EVENPARITY_BIT; | ||
| 759 | } | ||
| 760 | |||
| 761 | /* Stop bits */ | ||
| 762 | if (termios->c_cflag & CSTOPB) { | ||
| 763 | /* 2 stop bits */ | ||
| 764 | new_lcr |= MAX3107_LCR_STOPLEN_BIT; | ||
| 765 | } | ||
| 766 | |||
| 767 | /* Mask termios capabilities we don't support */ | ||
| 768 | termios->c_cflag &= ~CMSPAR; | ||
| 769 | |||
| 770 | /* Set status ignore mask */ | ||
| 771 | s->port.ignore_status_mask = 0; | ||
| 772 | if (termios->c_iflag & IGNPAR) | ||
| 773 | s->port.ignore_status_mask |= MAX3107_ALL_ERRORS; | ||
| 774 | |||
| 775 | /* Set low latency to immediately handle pushed data */ | ||
| 776 | s->port.state->port.tty->low_latency = 1; | ||
| 777 | |||
| 778 | /* Get new baud rate generator configuration */ | ||
| 779 | baud = tty_get_baud_rate(tty); | ||
| 780 | |||
| 781 | spin_lock_irqsave(&s->data_lock, flags); | ||
| 782 | new_brg = get_new_brg(baud, s); | ||
| 783 | /* if can't find the corrent config, use previous */ | ||
| 784 | if (!new_brg) { | ||
| 785 | baud = s->baud; | ||
| 786 | new_brg = s->brg_cfg; | ||
| 787 | } | ||
| 788 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
| 789 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
| 790 | s->baud = baud; | ||
| 791 | |||
| 792 | /* Update timeout according to new baud rate */ | ||
| 793 | uart_update_timeout(port, termios->c_cflag, baud); | ||
| 794 | |||
| 795 | spin_lock_irqsave(&s->data_lock, flags); | ||
| 796 | if (s->lcr_reg != new_lcr) { | ||
| 797 | s->lcr_reg = new_lcr; | ||
| 798 | s->lcr_commit = 1; | ||
| 799 | } | ||
| 800 | if (s->brg_cfg != new_brg) { | ||
| 801 | s->brg_cfg = new_brg; | ||
| 802 | s->brg_commit = 1; | ||
| 803 | } | ||
| 804 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
| 805 | |||
| 806 | /* Trigger work thread for doing the actual configuration change */ | ||
| 807 | max3107_dowork(s); | ||
| 808 | } | ||
| 809 | |||
| 810 | /* Port shutdown function */ | ||
| 811 | static void max3107_shutdown(struct uart_port *port) | ||
| 812 | { | ||
| 813 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
| 814 | |||
| 815 | if (s->suspended && s->pdata->hw_suspend) | ||
| 816 | s->pdata->hw_suspend(s, 0); | ||
| 817 | |||
| 818 | /* Free the interrupt */ | ||
| 819 | free_irq(s->spi->irq, s); | ||
| 820 | |||
| 821 | if (s->workqueue) { | ||
| 822 | /* Flush and destroy work queue */ | ||
| 823 | flush_workqueue(s->workqueue); | ||
| 824 | destroy_workqueue(s->workqueue); | ||
| 825 | s->workqueue = NULL; | ||
| 826 | } | ||
| 827 | |||
| 828 | /* Suspend HW */ | ||
| 829 | if (s->pdata->hw_suspend) | ||
| 830 | s->pdata->hw_suspend(s, 1); | ||
| 831 | } | ||
| 832 | |||
| 833 | /* Port startup function */ | ||
| 834 | static int max3107_startup(struct uart_port *port) | ||
| 835 | { | ||
| 836 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
| 837 | |||
| 838 | /* Initialize work queue */ | ||
| 839 | s->workqueue = create_freezable_workqueue("max3107"); | ||
| 840 | if (!s->workqueue) { | ||
| 841 | dev_err(&s->spi->dev, "Workqueue creation failed\n"); | ||
| 842 | return -EBUSY; | ||
| 843 | } | ||
| 844 | INIT_WORK(&s->work, max3107_work); | ||
| 845 | |||
| 846 | /* Setup IRQ */ | ||
| 847 | if (request_irq(s->spi->irq, max3107_irq, IRQF_TRIGGER_FALLING, | ||
| 848 | "max3107", s)) { | ||
| 849 | dev_err(&s->spi->dev, "IRQ reguest failed\n"); | ||
| 850 | destroy_workqueue(s->workqueue); | ||
| 851 | s->workqueue = NULL; | ||
| 852 | return -EBUSY; | ||
| 853 | } | ||
| 854 | |||
| 855 | /* Resume HW */ | ||
| 856 | if (s->pdata->hw_suspend) | ||
| 857 | s->pdata->hw_suspend(s, 0); | ||
| 858 | |||
| 859 | /* Init registers */ | ||
| 860 | max3107_register_init(s); | ||
| 861 | |||
| 862 | return 0; | ||
| 863 | } | ||
| 864 | |||
| 865 | /* Port type function */ | ||
| 866 | static const char *max3107_type(struct uart_port *port) | ||
| 867 | { | ||
| 868 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
| 869 | return s->spi->modalias; | ||
| 870 | } | ||
| 871 | |||
| 872 | /* Port release function */ | ||
| 873 | static void max3107_release_port(struct uart_port *port) | ||
| 874 | { | ||
| 875 | /* Do nothing */ | ||
| 876 | } | ||
| 877 | |||
| 878 | /* Port request function */ | ||
| 879 | static int max3107_request_port(struct uart_port *port) | ||
| 880 | { | ||
| 881 | /* Do nothing */ | ||
| 882 | return 0; | ||
| 883 | } | ||
| 884 | |||
| 885 | /* Port config function */ | ||
| 886 | static void max3107_config_port(struct uart_port *port, int flags) | ||
| 887 | { | ||
| 888 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
| 889 | s->port.type = PORT_MAX3107; | ||
| 890 | } | ||
| 891 | |||
| 892 | /* Port verify function */ | ||
| 893 | static int max3107_verify_port(struct uart_port *port, | ||
| 894 | struct serial_struct *ser) | ||
| 895 | { | ||
| 896 | if (ser->type == PORT_UNKNOWN || ser->type == PORT_MAX3107) | ||
| 897 | return 0; | ||
| 898 | |||
| 899 | return -EINVAL; | ||
| 900 | } | ||
| 901 | |||
| 902 | /* Port stop TX function */ | ||
| 903 | static void max3107_stop_tx(struct uart_port *port) | ||
| 904 | { | ||
| 905 | /* Do nothing */ | ||
| 906 | } | ||
| 907 | |||
| 908 | /* Port break control function */ | ||
| 909 | static void max3107_break_ctl(struct uart_port *port, int break_state) | ||
| 910 | { | ||
| 911 | /* We don't support break control, do nothing */ | ||
| 912 | } | ||
| 913 | |||
| 914 | |||
| 915 | /* Port functions */ | ||
| 916 | static struct uart_ops max3107_ops = { | ||
| 917 | .tx_empty = max3107_tx_empty, | ||
| 918 | .set_mctrl = max3107_set_mctrl, | ||
| 919 | .get_mctrl = max3107_get_mctrl, | ||
| 920 | .stop_tx = max3107_stop_tx, | ||
| 921 | .start_tx = max3107_start_tx, | ||
| 922 | .stop_rx = max3107_stop_rx, | ||
| 923 | .enable_ms = max3107_enable_ms, | ||
| 924 | .break_ctl = max3107_break_ctl, | ||
| 925 | .startup = max3107_startup, | ||
| 926 | .shutdown = max3107_shutdown, | ||
| 927 | .set_termios = max3107_set_termios, | ||
| 928 | .type = max3107_type, | ||
| 929 | .release_port = max3107_release_port, | ||
| 930 | .request_port = max3107_request_port, | ||
| 931 | .config_port = max3107_config_port, | ||
| 932 | .verify_port = max3107_verify_port, | ||
| 933 | }; | ||
| 934 | |||
| 935 | /* UART driver data */ | ||
| 936 | static struct uart_driver max3107_uart_driver = { | ||
| 937 | .owner = THIS_MODULE, | ||
| 938 | .driver_name = "ttyMAX", | ||
| 939 | .dev_name = "ttyMAX", | ||
| 940 | .nr = 1, | ||
| 941 | }; | ||
| 942 | |||
| 943 | static int driver_registered = 0; | ||
| 944 | |||
| 945 | |||
| 946 | |||
| 947 | /* 'Generic' platform data */ | ||
| 948 | static struct max3107_plat generic_plat_data = { | ||
| 949 | .loopback = 0, | ||
| 950 | .ext_clk = 1, | ||
| 951 | .hw_suspend = max3107_hw_susp, | ||
| 952 | .polled_mode = 0, | ||
| 953 | .poll_time = 0, | ||
| 954 | }; | ||
| 955 | |||
| 956 | |||
| 957 | /*******************************************************************/ | ||
| 958 | |||
| 959 | /** | ||
| 960 | * max3107_probe - SPI bus probe entry point | ||
| 961 | * @spi: the spi device | ||
| 962 | * | ||
| 963 | * SPI wants us to probe this device and if appropriate claim it. | ||
| 964 | * Perform any platform specific requirements and then initialise | ||
| 965 | * the device. | ||
| 966 | */ | ||
| 967 | |||
| 968 | int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata) | ||
| 969 | { | ||
| 970 | struct max3107_port *s; | ||
| 971 | u16 buf[2]; /* Buffer for SPI transfers */ | ||
| 972 | int retval; | ||
| 973 | |||
| 974 | pr_info("enter max3107 probe\n"); | ||
| 975 | |||
| 976 | /* Allocate port structure */ | ||
| 977 | s = kzalloc(sizeof(*s), GFP_KERNEL); | ||
| 978 | if (!s) { | ||
| 979 | pr_err("Allocating port structure failed\n"); | ||
| 980 | return -ENOMEM; | ||
| 981 | } | ||
| 982 | |||
| 983 | s->pdata = pdata; | ||
| 984 | |||
| 985 | /* SPI Rx buffer | ||
| 986 | * +2 for RX FIFO interrupt | ||
| 987 | * disabling and RX level query | ||
| 988 | */ | ||
| 989 | s->rxbuf = kzalloc(sizeof(u16) * (MAX3107_RX_FIFO_SIZE+2), GFP_KERNEL); | ||
| 990 | if (!s->rxbuf) { | ||
| 991 | pr_err("Allocating RX buffer failed\n"); | ||
| 992 | retval = -ENOMEM; | ||
| 993 | goto err_free4; | ||
| 994 | } | ||
| 995 | s->rxstr = kzalloc(sizeof(u8) * MAX3107_RX_FIFO_SIZE, GFP_KERNEL); | ||
| 996 | if (!s->rxstr) { | ||
| 997 | pr_err("Allocating RX buffer failed\n"); | ||
| 998 | retval = -ENOMEM; | ||
| 999 | goto err_free3; | ||
| 1000 | } | ||
| 1001 | /* SPI Tx buffer | ||
| 1002 | * SPI transfer buffer | ||
| 1003 | * +3 for TX FIFO empty | ||
| 1004 | * interrupt disabling and | ||
| 1005 | * enabling and TX enabling | ||
| 1006 | */ | ||
| 1007 | s->txbuf = kzalloc(sizeof(u16) * MAX3107_TX_FIFO_SIZE + 3, GFP_KERNEL); | ||
| 1008 | if (!s->txbuf) { | ||
| 1009 | pr_err("Allocating TX buffer failed\n"); | ||
| 1010 | retval = -ENOMEM; | ||
| 1011 | goto err_free2; | ||
| 1012 | } | ||
| 1013 | /* Initialize shared data lock */ | ||
| 1014 | spin_lock_init(&s->data_lock); | ||
| 1015 | |||
| 1016 | /* SPI intializations */ | ||
| 1017 | dev_set_drvdata(&spi->dev, s); | ||
| 1018 | spi->mode = SPI_MODE_0; | ||
| 1019 | spi->dev.platform_data = pdata; | ||
| 1020 | spi->bits_per_word = 16; | ||
| 1021 | s->ext_clk = pdata->ext_clk; | ||
| 1022 | s->loopback = pdata->loopback; | ||
| 1023 | spi_setup(spi); | ||
| 1024 | s->spi = spi; | ||
| 1025 | |||
| 1026 | /* Check REV ID to ensure we are talking to what we expect */ | ||
| 1027 | buf[0] = MAX3107_REVID_REG; | ||
| 1028 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { | ||
| 1029 | dev_err(&s->spi->dev, "SPI transfer for REVID read failed\n"); | ||
| 1030 | retval = -EIO; | ||
| 1031 | goto err_free1; | ||
| 1032 | } | ||
| 1033 | if ((buf[0] & MAX3107_SPI_RX_DATA_MASK) != MAX3107_REVID1 && | ||
| 1034 | (buf[0] & MAX3107_SPI_RX_DATA_MASK) != MAX3107_REVID2) { | ||
| 1035 | dev_err(&s->spi->dev, "REVID %x does not match\n", | ||
| 1036 | (buf[0] & MAX3107_SPI_RX_DATA_MASK)); | ||
| 1037 | retval = -ENODEV; | ||
| 1038 | goto err_free1; | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | /* Disable all interrupts */ | ||
| 1042 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG | 0x0000); | ||
| 1043 | buf[0] |= 0x0000; | ||
| 1044 | |||
| 1045 | /* Configure clock source */ | ||
| 1046 | buf[1] = (MAX3107_WRITE_BIT | MAX3107_CLKSRC_REG); | ||
| 1047 | if (s->ext_clk) { | ||
| 1048 | /* External clock */ | ||
| 1049 | buf[1] |= MAX3107_CLKSRC_EXTCLK_BIT; | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | /* PLL bypass ON */ | ||
| 1053 | buf[1] |= MAX3107_CLKSRC_PLLBYP_BIT; | ||
| 1054 | |||
| 1055 | /* Perform SPI transfer */ | ||
| 1056 | if (max3107_rw(s, (u8 *)buf, NULL, 4)) { | ||
| 1057 | dev_err(&s->spi->dev, "SPI transfer for init failed\n"); | ||
| 1058 | retval = -EIO; | ||
| 1059 | goto err_free1; | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | /* Register UART driver */ | ||
| 1063 | if (!driver_registered) { | ||
| 1064 | retval = uart_register_driver(&max3107_uart_driver); | ||
| 1065 | if (retval) { | ||
| 1066 | dev_err(&s->spi->dev, "Registering UART driver failed\n"); | ||
| 1067 | goto err_free1; | ||
| 1068 | } | ||
| 1069 | driver_registered = 1; | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | /* Initialize UART port data */ | ||
| 1073 | s->port.fifosize = 128; | ||
| 1074 | s->port.ops = &max3107_ops; | ||
| 1075 | s->port.line = 0; | ||
| 1076 | s->port.dev = &spi->dev; | ||
| 1077 | s->port.uartclk = 9600; | ||
| 1078 | s->port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; | ||
| 1079 | s->port.irq = s->spi->irq; | ||
| 1080 | s->port.type = PORT_MAX3107; | ||
| 1081 | |||
| 1082 | /* Add UART port */ | ||
| 1083 | retval = uart_add_one_port(&max3107_uart_driver, &s->port); | ||
| 1084 | if (retval < 0) { | ||
| 1085 | dev_err(&s->spi->dev, "Adding UART port failed\n"); | ||
| 1086 | goto err_free1; | ||
| 1087 | } | ||
| 1088 | |||
| 1089 | if (pdata->configure) { | ||
| 1090 | retval = pdata->configure(s); | ||
| 1091 | if (retval < 0) | ||
| 1092 | goto err_free1; | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | /* Go to suspend mode */ | ||
| 1096 | if (pdata->hw_suspend) | ||
| 1097 | pdata->hw_suspend(s, 1); | ||
| 1098 | |||
| 1099 | return 0; | ||
| 1100 | |||
| 1101 | err_free1: | ||
| 1102 | kfree(s->txbuf); | ||
| 1103 | err_free2: | ||
| 1104 | kfree(s->rxstr); | ||
| 1105 | err_free3: | ||
| 1106 | kfree(s->rxbuf); | ||
| 1107 | err_free4: | ||
| 1108 | kfree(s); | ||
| 1109 | return retval; | ||
| 1110 | } | ||
| 1111 | EXPORT_SYMBOL_GPL(max3107_probe); | ||
| 1112 | |||
| 1113 | /* Driver remove function */ | ||
| 1114 | int max3107_remove(struct spi_device *spi) | ||
| 1115 | { | ||
| 1116 | struct max3107_port *s = dev_get_drvdata(&spi->dev); | ||
| 1117 | |||
| 1118 | pr_info("enter max3107 remove\n"); | ||
| 1119 | |||
| 1120 | /* Remove port */ | ||
| 1121 | if (uart_remove_one_port(&max3107_uart_driver, &s->port)) | ||
| 1122 | dev_warn(&s->spi->dev, "Removing UART port failed\n"); | ||
| 1123 | |||
| 1124 | |||
| 1125 | /* Free TxRx buffer */ | ||
| 1126 | kfree(s->rxbuf); | ||
| 1127 | kfree(s->rxstr); | ||
| 1128 | kfree(s->txbuf); | ||
| 1129 | |||
| 1130 | /* Free port structure */ | ||
| 1131 | kfree(s); | ||
| 1132 | |||
| 1133 | return 0; | ||
| 1134 | } | ||
| 1135 | EXPORT_SYMBOL_GPL(max3107_remove); | ||
| 1136 | |||
| 1137 | /* Driver suspend function */ | ||
| 1138 | int max3107_suspend(struct spi_device *spi, pm_message_t state) | ||
| 1139 | { | ||
| 1140 | #ifdef CONFIG_PM | ||
| 1141 | struct max3107_port *s = dev_get_drvdata(&spi->dev); | ||
| 1142 | |||
| 1143 | pr_debug("enter suspend\n"); | ||
| 1144 | |||
| 1145 | /* Suspend UART port */ | ||
| 1146 | uart_suspend_port(&max3107_uart_driver, &s->port); | ||
| 1147 | |||
| 1148 | /* Go to suspend mode */ | ||
| 1149 | if (s->pdata->hw_suspend) | ||
| 1150 | s->pdata->hw_suspend(s, 1); | ||
| 1151 | #endif /* CONFIG_PM */ | ||
| 1152 | return 0; | ||
| 1153 | } | ||
| 1154 | EXPORT_SYMBOL_GPL(max3107_suspend); | ||
| 1155 | |||
| 1156 | /* Driver resume function */ | ||
| 1157 | int max3107_resume(struct spi_device *spi) | ||
| 1158 | { | ||
| 1159 | #ifdef CONFIG_PM | ||
| 1160 | struct max3107_port *s = dev_get_drvdata(&spi->dev); | ||
| 1161 | |||
| 1162 | pr_debug("enter resume\n"); | ||
| 1163 | |||
| 1164 | /* Resume from suspend */ | ||
| 1165 | if (s->pdata->hw_suspend) | ||
| 1166 | s->pdata->hw_suspend(s, 0); | ||
| 1167 | |||
| 1168 | /* Resume UART port */ | ||
| 1169 | uart_resume_port(&max3107_uart_driver, &s->port); | ||
| 1170 | #endif /* CONFIG_PM */ | ||
| 1171 | return 0; | ||
| 1172 | } | ||
| 1173 | EXPORT_SYMBOL_GPL(max3107_resume); | ||
| 1174 | |||
| 1175 | static int max3107_probe_generic(struct spi_device *spi) | ||
| 1176 | { | ||
| 1177 | return max3107_probe(spi, &generic_plat_data); | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | /* Spi driver data */ | ||
| 1181 | static struct spi_driver max3107_driver = { | ||
| 1182 | .driver = { | ||
| 1183 | .name = "max3107", | ||
| 1184 | .owner = THIS_MODULE, | ||
| 1185 | }, | ||
| 1186 | .probe = max3107_probe_generic, | ||
| 1187 | .remove = __devexit_p(max3107_remove), | ||
| 1188 | .suspend = max3107_suspend, | ||
| 1189 | .resume = max3107_resume, | ||
| 1190 | }; | ||
| 1191 | |||
| 1192 | /* Driver init function */ | ||
| 1193 | static int __init max3107_init(void) | ||
| 1194 | { | ||
| 1195 | pr_info("enter max3107 init\n"); | ||
| 1196 | return spi_register_driver(&max3107_driver); | ||
| 1197 | } | ||
| 1198 | |||
| 1199 | /* Driver exit function */ | ||
| 1200 | static void __exit max3107_exit(void) | ||
| 1201 | { | ||
| 1202 | pr_info("enter max3107 exit\n"); | ||
| 1203 | /* Unregister UART driver */ | ||
| 1204 | if (driver_registered) | ||
| 1205 | uart_unregister_driver(&max3107_uart_driver); | ||
| 1206 | spi_unregister_driver(&max3107_driver); | ||
| 1207 | } | ||
| 1208 | |||
| 1209 | module_init(max3107_init); | ||
| 1210 | module_exit(max3107_exit); | ||
| 1211 | |||
| 1212 | MODULE_DESCRIPTION("MAX3107 driver"); | ||
| 1213 | MODULE_AUTHOR("Aavamobile"); | ||
| 1214 | MODULE_ALIAS("spi:max3107"); | ||
| 1215 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/serial/max3107.h b/drivers/tty/serial/max3107.h deleted file mode 100644 index 8415fc723b96..000000000000 --- a/drivers/tty/serial/max3107.h +++ /dev/null | |||
| @@ -1,441 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * max3107.h - spi uart protocol driver header for Maxim 3107 | ||
| 3 | * | ||
| 4 | * Copyright (C) Aavamobile 2009 | ||
| 5 | * Based on serial_max3100.h by Christian Pellegrin | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef _MAX3107_H | ||
| 14 | #define _MAX3107_H | ||
| 15 | |||
| 16 | /* Serial error status definitions */ | ||
| 17 | #define MAX3107_PARITY_ERROR 1 | ||
| 18 | #define MAX3107_FRAME_ERROR 2 | ||
| 19 | #define MAX3107_OVERRUN_ERROR 4 | ||
| 20 | #define MAX3107_ALL_ERRORS (MAX3107_PARITY_ERROR | \ | ||
| 21 | MAX3107_FRAME_ERROR | \ | ||
| 22 | MAX3107_OVERRUN_ERROR) | ||
| 23 | |||
| 24 | /* GPIO definitions */ | ||
| 25 | #define MAX3107_GPIO_BASE 88 | ||
| 26 | #define MAX3107_GPIO_COUNT 4 | ||
| 27 | |||
| 28 | |||
| 29 | /* GPIO connected to chip's reset pin */ | ||
| 30 | #define MAX3107_RESET_GPIO 87 | ||
| 31 | |||
| 32 | |||
| 33 | /* Chip reset delay */ | ||
| 34 | #define MAX3107_RESET_DELAY 10 | ||
| 35 | |||
| 36 | /* Chip wakeup delay */ | ||
| 37 | #define MAX3107_WAKEUP_DELAY 50 | ||
| 38 | |||
| 39 | |||
| 40 | /* Sleep mode definitions */ | ||
| 41 | #define MAX3107_DISABLE_FORCED_SLEEP 0 | ||
| 42 | #define MAX3107_ENABLE_FORCED_SLEEP 1 | ||
| 43 | #define MAX3107_DISABLE_AUTOSLEEP 2 | ||
| 44 | #define MAX3107_ENABLE_AUTOSLEEP 3 | ||
| 45 | |||
| 46 | |||
| 47 | /* Definitions for register access with SPI transfers | ||
| 48 | * | ||
| 49 | * SPI transfer format: | ||
| 50 | * | ||
| 51 | * Master to slave bits xzzzzzzzyyyyyyyy | ||
| 52 | * Slave to master bits aaaaaaaabbbbbbbb | ||
| 53 | * | ||
| 54 | * where: | ||
| 55 | * x = 0 for reads, 1 for writes | ||
| 56 | * z = register address | ||
| 57 | * y = new register value if write, 0 if read | ||
| 58 | * a = unspecified | ||
| 59 | * b = register value if read, unspecified if write | ||
| 60 | */ | ||
| 61 | |||
| 62 | /* SPI speed */ | ||
| 63 | #define MAX3107_SPI_SPEED (3125000 * 2) | ||
| 64 | |||
| 65 | /* Write bit */ | ||
| 66 | #define MAX3107_WRITE_BIT (1 << 15) | ||
| 67 | |||
| 68 | /* SPI TX data mask */ | ||
| 69 | #define MAX3107_SPI_RX_DATA_MASK (0x00ff) | ||
| 70 | |||
| 71 | /* SPI RX data mask */ | ||
| 72 | #define MAX3107_SPI_TX_DATA_MASK (0x00ff) | ||
| 73 | |||
| 74 | /* Register access masks */ | ||
| 75 | #define MAX3107_RHR_REG (0x0000) /* RX FIFO */ | ||
| 76 | #define MAX3107_THR_REG (0x0000) /* TX FIFO */ | ||
| 77 | #define MAX3107_IRQEN_REG (0x0100) /* IRQ enable */ | ||
| 78 | #define MAX3107_IRQSTS_REG (0x0200) /* IRQ status */ | ||
| 79 | #define MAX3107_LSR_IRQEN_REG (0x0300) /* LSR IRQ enable */ | ||
| 80 | #define MAX3107_LSR_IRQSTS_REG (0x0400) /* LSR IRQ status */ | ||
| 81 | #define MAX3107_SPCHR_IRQEN_REG (0x0500) /* Special char IRQ enable */ | ||
| 82 | #define MAX3107_SPCHR_IRQSTS_REG (0x0600) /* Special char IRQ status */ | ||
| 83 | #define MAX3107_STS_IRQEN_REG (0x0700) /* Status IRQ enable */ | ||
| 84 | #define MAX3107_STS_IRQSTS_REG (0x0800) /* Status IRQ status */ | ||
| 85 | #define MAX3107_MODE1_REG (0x0900) /* MODE1 */ | ||
| 86 | #define MAX3107_MODE2_REG (0x0a00) /* MODE2 */ | ||
| 87 | #define MAX3107_LCR_REG (0x0b00) /* LCR */ | ||
| 88 | #define MAX3107_RXTO_REG (0x0c00) /* RX timeout */ | ||
| 89 | #define MAX3107_HDPIXDELAY_REG (0x0d00) /* Auto transceiver delays */ | ||
| 90 | #define MAX3107_IRDA_REG (0x0e00) /* IRDA settings */ | ||
| 91 | #define MAX3107_FLOWLVL_REG (0x0f00) /* Flow control levels */ | ||
| 92 | #define MAX3107_FIFOTRIGLVL_REG (0x1000) /* FIFO IRQ trigger levels */ | ||
| 93 | #define MAX3107_TXFIFOLVL_REG (0x1100) /* TX FIFO level */ | ||
| 94 | #define MAX3107_RXFIFOLVL_REG (0x1200) /* RX FIFO level */ | ||
| 95 | #define MAX3107_FLOWCTRL_REG (0x1300) /* Flow control */ | ||
| 96 | #define MAX3107_XON1_REG (0x1400) /* XON1 character */ | ||
| 97 | #define MAX3107_XON2_REG (0x1500) /* XON2 character */ | ||
| 98 | #define MAX3107_XOFF1_REG (0x1600) /* XOFF1 character */ | ||
| 99 | #define MAX3107_XOFF2_REG (0x1700) /* XOFF2 character */ | ||
| 100 | #define MAX3107_GPIOCFG_REG (0x1800) /* GPIO config */ | ||
| 101 | #define MAX3107_GPIODATA_REG (0x1900) /* GPIO data */ | ||
| 102 | #define MAX3107_PLLCFG_REG (0x1a00) /* PLL config */ | ||
| 103 | #define MAX3107_BRGCFG_REG (0x1b00) /* Baud rate generator conf */ | ||
| 104 | #define MAX3107_BRGDIVLSB_REG (0x1c00) /* Baud rate divisor LSB */ | ||
| 105 | #define MAX3107_BRGDIVMSB_REG (0x1d00) /* Baud rate divisor MSB */ | ||
| 106 | #define MAX3107_CLKSRC_REG (0x1e00) /* Clock source */ | ||
| 107 | #define MAX3107_REVID_REG (0x1f00) /* Revision identification */ | ||
| 108 | |||
| 109 | /* IRQ register bits */ | ||
| 110 | #define MAX3107_IRQ_LSR_BIT (1 << 0) /* LSR interrupt */ | ||
| 111 | #define MAX3107_IRQ_SPCHR_BIT (1 << 1) /* Special char interrupt */ | ||
| 112 | #define MAX3107_IRQ_STS_BIT (1 << 2) /* Status interrupt */ | ||
| 113 | #define MAX3107_IRQ_RXFIFO_BIT (1 << 3) /* RX FIFO interrupt */ | ||
| 114 | #define MAX3107_IRQ_TXFIFO_BIT (1 << 4) /* TX FIFO interrupt */ | ||
| 115 | #define MAX3107_IRQ_TXEMPTY_BIT (1 << 5) /* TX FIFO empty interrupt */ | ||
| 116 | #define MAX3107_IRQ_RXEMPTY_BIT (1 << 6) /* RX FIFO empty interrupt */ | ||
| 117 | #define MAX3107_IRQ_CTS_BIT (1 << 7) /* CTS interrupt */ | ||
| 118 | |||
| 119 | /* LSR register bits */ | ||
| 120 | #define MAX3107_LSR_RXTO_BIT (1 << 0) /* RX timeout */ | ||
| 121 | #define MAX3107_LSR_RXOVR_BIT (1 << 1) /* RX overrun */ | ||
| 122 | #define MAX3107_LSR_RXPAR_BIT (1 << 2) /* RX parity error */ | ||
| 123 | #define MAX3107_LSR_FRERR_BIT (1 << 3) /* Frame error */ | ||
| 124 | #define MAX3107_LSR_RXBRK_BIT (1 << 4) /* RX break */ | ||
| 125 | #define MAX3107_LSR_RXNOISE_BIT (1 << 5) /* RX noise */ | ||
| 126 | #define MAX3107_LSR_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
| 127 | #define MAX3107_LSR_CTS_BIT (1 << 7) /* CTS pin state */ | ||
| 128 | |||
| 129 | /* Special character register bits */ | ||
| 130 | #define MAX3107_SPCHR_XON1_BIT (1 << 0) /* XON1 character */ | ||
| 131 | #define MAX3107_SPCHR_XON2_BIT (1 << 1) /* XON2 character */ | ||
| 132 | #define MAX3107_SPCHR_XOFF1_BIT (1 << 2) /* XOFF1 character */ | ||
| 133 | #define MAX3107_SPCHR_XOFF2_BIT (1 << 3) /* XOFF2 character */ | ||
| 134 | #define MAX3107_SPCHR_BREAK_BIT (1 << 4) /* RX break */ | ||
| 135 | #define MAX3107_SPCHR_MULTIDROP_BIT (1 << 5) /* 9-bit multidrop addr char */ | ||
| 136 | #define MAX3107_SPCHR_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
| 137 | #define MAX3107_SPCHR_UNDEF7_BIT (1 << 7) /* Undefined/not used */ | ||
| 138 | |||
| 139 | /* Status register bits */ | ||
| 140 | #define MAX3107_STS_GPIO0_BIT (1 << 0) /* GPIO 0 interrupt */ | ||
| 141 | #define MAX3107_STS_GPIO1_BIT (1 << 1) /* GPIO 1 interrupt */ | ||
| 142 | #define MAX3107_STS_GPIO2_BIT (1 << 2) /* GPIO 2 interrupt */ | ||
| 143 | #define MAX3107_STS_GPIO3_BIT (1 << 3) /* GPIO 3 interrupt */ | ||
| 144 | #define MAX3107_STS_UNDEF4_BIT (1 << 4) /* Undefined/not used */ | ||
| 145 | #define MAX3107_STS_CLKREADY_BIT (1 << 5) /* Clock ready */ | ||
| 146 | #define MAX3107_STS_SLEEP_BIT (1 << 6) /* Sleep interrupt */ | ||
| 147 | #define MAX3107_STS_UNDEF7_BIT (1 << 7) /* Undefined/not used */ | ||
| 148 | |||
| 149 | /* MODE1 register bits */ | ||
| 150 | #define MAX3107_MODE1_RXDIS_BIT (1 << 0) /* RX disable */ | ||
| 151 | #define MAX3107_MODE1_TXDIS_BIT (1 << 1) /* TX disable */ | ||
| 152 | #define MAX3107_MODE1_TXHIZ_BIT (1 << 2) /* TX pin three-state */ | ||
| 153 | #define MAX3107_MODE1_RTSHIZ_BIT (1 << 3) /* RTS pin three-state */ | ||
| 154 | #define MAX3107_MODE1_TRNSCVCTRL_BIT (1 << 4) /* Transceiver ctrl enable */ | ||
| 155 | #define MAX3107_MODE1_FORCESLEEP_BIT (1 << 5) /* Force sleep mode */ | ||
| 156 | #define MAX3107_MODE1_AUTOSLEEP_BIT (1 << 6) /* Auto sleep enable */ | ||
| 157 | #define MAX3107_MODE1_IRQSEL_BIT (1 << 7) /* IRQ pin enable */ | ||
| 158 | |||
| 159 | /* MODE2 register bits */ | ||
| 160 | #define MAX3107_MODE2_RST_BIT (1 << 0) /* Chip reset */ | ||
| 161 | #define MAX3107_MODE2_FIFORST_BIT (1 << 1) /* FIFO reset */ | ||
| 162 | #define MAX3107_MODE2_RXTRIGINV_BIT (1 << 2) /* RX FIFO INT invert */ | ||
| 163 | #define MAX3107_MODE2_RXEMPTINV_BIT (1 << 3) /* RX FIFO empty INT invert */ | ||
| 164 | #define MAX3107_MODE2_SPCHR_BIT (1 << 4) /* Special chr detect enable */ | ||
| 165 | #define MAX3107_MODE2_LOOPBACK_BIT (1 << 5) /* Internal loopback enable */ | ||
| 166 | #define MAX3107_MODE2_MULTIDROP_BIT (1 << 6) /* 9-bit multidrop enable */ | ||
| 167 | #define MAX3107_MODE2_ECHOSUPR_BIT (1 << 7) /* ECHO suppression enable */ | ||
| 168 | |||
| 169 | /* LCR register bits */ | ||
| 170 | #define MAX3107_LCR_LENGTH0_BIT (1 << 0) /* Word length bit 0 */ | ||
| 171 | #define MAX3107_LCR_LENGTH1_BIT (1 << 1) /* Word length bit 1 | ||
| 172 | * | ||
| 173 | * Word length bits table: | ||
| 174 | * 00 -> 5 bit words | ||
| 175 | * 01 -> 6 bit words | ||
| 176 | * 10 -> 7 bit words | ||
| 177 | * 11 -> 8 bit words | ||
| 178 | */ | ||
| 179 | #define MAX3107_LCR_STOPLEN_BIT (1 << 2) /* STOP length bit | ||
| 180 | * | ||
| 181 | * STOP length bit table: | ||
| 182 | * 0 -> 1 stop bit | ||
| 183 | * 1 -> 1-1.5 stop bits if | ||
| 184 | * word length is 5, | ||
| 185 | * 2 stop bits otherwise | ||
| 186 | */ | ||
| 187 | #define MAX3107_LCR_PARITY_BIT (1 << 3) /* Parity bit enable */ | ||
| 188 | #define MAX3107_LCR_EVENPARITY_BIT (1 << 4) /* Even parity bit enable */ | ||
| 189 | #define MAX3107_LCR_FORCEPARITY_BIT (1 << 5) /* 9-bit multidrop parity */ | ||
| 190 | #define MAX3107_LCR_TXBREAK_BIT (1 << 6) /* TX break enable */ | ||
| 191 | #define MAX3107_LCR_RTS_BIT (1 << 7) /* RTS pin control */ | ||
| 192 | #define MAX3107_LCR_WORD_LEN_5 (0x0000) | ||
| 193 | #define MAX3107_LCR_WORD_LEN_6 (0x0001) | ||
| 194 | #define MAX3107_LCR_WORD_LEN_7 (0x0002) | ||
| 195 | #define MAX3107_LCR_WORD_LEN_8 (0x0003) | ||
| 196 | |||
| 197 | |||
| 198 | /* IRDA register bits */ | ||
| 199 | #define MAX3107_IRDA_IRDAEN_BIT (1 << 0) /* IRDA mode enable */ | ||
| 200 | #define MAX3107_IRDA_SIR_BIT (1 << 1) /* SIR mode enable */ | ||
| 201 | #define MAX3107_IRDA_SHORTIR_BIT (1 << 2) /* Short SIR mode enable */ | ||
| 202 | #define MAX3107_IRDA_MIR_BIT (1 << 3) /* MIR mode enable */ | ||
| 203 | #define MAX3107_IRDA_RXINV_BIT (1 << 4) /* RX logic inversion enable */ | ||
| 204 | #define MAX3107_IRDA_TXINV_BIT (1 << 5) /* TX logic inversion enable */ | ||
| 205 | #define MAX3107_IRDA_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
| 206 | #define MAX3107_IRDA_UNDEF7_BIT (1 << 7) /* Undefined/not used */ | ||
| 207 | |||
| 208 | /* Flow control trigger level register masks */ | ||
| 209 | #define MAX3107_FLOWLVL_HALT_MASK (0x000f) /* Flow control halt level */ | ||
| 210 | #define MAX3107_FLOWLVL_RES_MASK (0x00f0) /* Flow control resume level */ | ||
| 211 | #define MAX3107_FLOWLVL_HALT(words) ((words/8) & 0x000f) | ||
| 212 | #define MAX3107_FLOWLVL_RES(words) (((words/8) & 0x000f) << 4) | ||
| 213 | |||
| 214 | /* FIFO interrupt trigger level register masks */ | ||
| 215 | #define MAX3107_FIFOTRIGLVL_TX_MASK (0x000f) /* TX FIFO trigger level */ | ||
| 216 | #define MAX3107_FIFOTRIGLVL_RX_MASK (0x00f0) /* RX FIFO trigger level */ | ||
| 217 | #define MAX3107_FIFOTRIGLVL_TX(words) ((words/8) & 0x000f) | ||
| 218 | #define MAX3107_FIFOTRIGLVL_RX(words) (((words/8) & 0x000f) << 4) | ||
| 219 | |||
| 220 | /* Flow control register bits */ | ||
| 221 | #define MAX3107_FLOWCTRL_AUTORTS_BIT (1 << 0) /* Auto RTS flow ctrl enable */ | ||
| 222 | #define MAX3107_FLOWCTRL_AUTOCTS_BIT (1 << 1) /* Auto CTS flow ctrl enable */ | ||
| 223 | #define MAX3107_FLOWCTRL_GPIADDR_BIT (1 << 2) /* Enables that GPIO inputs | ||
| 224 | * are used in conjunction with | ||
| 225 | * XOFF2 for definition of | ||
| 226 | * special character */ | ||
| 227 | #define MAX3107_FLOWCTRL_SWFLOWEN_BIT (1 << 3) /* Auto SW flow ctrl enable */ | ||
| 228 | #define MAX3107_FLOWCTRL_SWFLOW0_BIT (1 << 4) /* SWFLOW bit 0 */ | ||
| 229 | #define MAX3107_FLOWCTRL_SWFLOW1_BIT (1 << 5) /* SWFLOW bit 1 | ||
| 230 | * | ||
| 231 | * SWFLOW bits 1 & 0 table: | ||
| 232 | * 00 -> no transmitter flow | ||
| 233 | * control | ||
| 234 | * 01 -> receiver compares | ||
| 235 | * XON2 and XOFF2 | ||
| 236 | * and controls | ||
| 237 | * transmitter | ||
| 238 | * 10 -> receiver compares | ||
| 239 | * XON1 and XOFF1 | ||
| 240 | * and controls | ||
| 241 | * transmitter | ||
| 242 | * 11 -> receiver compares | ||
| 243 | * XON1, XON2, XOFF1 and | ||
| 244 | * XOFF2 and controls | ||
| 245 | * transmitter | ||
| 246 | */ | ||
| 247 | #define MAX3107_FLOWCTRL_SWFLOW2_BIT (1 << 6) /* SWFLOW bit 2 */ | ||
| 248 | #define MAX3107_FLOWCTRL_SWFLOW3_BIT (1 << 7) /* SWFLOW bit 3 | ||
| 249 | * | ||
| 250 | * SWFLOW bits 3 & 2 table: | ||
| 251 | * 00 -> no received flow | ||
| 252 | * control | ||
| 253 | * 01 -> transmitter generates | ||
| 254 | * XON2 and XOFF2 | ||
| 255 | * 10 -> transmitter generates | ||
| 256 | * XON1 and XOFF1 | ||
| 257 | * 11 -> transmitter generates | ||
| 258 | * XON1, XON2, XOFF1 and | ||
| 259 | * XOFF2 | ||
| 260 | */ | ||
| 261 | |||
| 262 | /* GPIO configuration register bits */ | ||
| 263 | #define MAX3107_GPIOCFG_GP0OUT_BIT (1 << 0) /* GPIO 0 output enable */ | ||
| 264 | #define MAX3107_GPIOCFG_GP1OUT_BIT (1 << 1) /* GPIO 1 output enable */ | ||
| 265 | #define MAX3107_GPIOCFG_GP2OUT_BIT (1 << 2) /* GPIO 2 output enable */ | ||
| 266 | #define MAX3107_GPIOCFG_GP3OUT_BIT (1 << 3) /* GPIO 3 output enable */ | ||
| 267 | #define MAX3107_GPIOCFG_GP0OD_BIT (1 << 4) /* GPIO 0 open-drain enable */ | ||
| 268 | #define MAX3107_GPIOCFG_GP1OD_BIT (1 << 5) /* GPIO 1 open-drain enable */ | ||
| 269 | #define MAX3107_GPIOCFG_GP2OD_BIT (1 << 6) /* GPIO 2 open-drain enable */ | ||
| 270 | #define MAX3107_GPIOCFG_GP3OD_BIT (1 << 7) /* GPIO 3 open-drain enable */ | ||
| 271 | |||
| 272 | /* GPIO DATA register bits */ | ||
| 273 | #define MAX3107_GPIODATA_GP0OUT_BIT (1 << 0) /* GPIO 0 output value */ | ||
| 274 | #define MAX3107_GPIODATA_GP1OUT_BIT (1 << 1) /* GPIO 1 output value */ | ||
| 275 | #define MAX3107_GPIODATA_GP2OUT_BIT (1 << 2) /* GPIO 2 output value */ | ||
| 276 | #define MAX3107_GPIODATA_GP3OUT_BIT (1 << 3) /* GPIO 3 output value */ | ||
| 277 | #define MAX3107_GPIODATA_GP0IN_BIT (1 << 4) /* GPIO 0 input value */ | ||
| 278 | #define MAX3107_GPIODATA_GP1IN_BIT (1 << 5) /* GPIO 1 input value */ | ||
| 279 | #define MAX3107_GPIODATA_GP2IN_BIT (1 << 6) /* GPIO 2 input value */ | ||
| 280 | #define MAX3107_GPIODATA_GP3IN_BIT (1 << 7) /* GPIO 3 input value */ | ||
| 281 | |||
| 282 | /* PLL configuration register masks */ | ||
| 283 | #define MAX3107_PLLCFG_PREDIV_MASK (0x003f) /* PLL predivision value */ | ||
| 284 | #define MAX3107_PLLCFG_PLLFACTOR_MASK (0x00c0) /* PLL multiplication factor */ | ||
| 285 | |||
| 286 | /* Baud rate generator configuration register masks and bits */ | ||
| 287 | #define MAX3107_BRGCFG_FRACT_MASK (0x000f) /* Fractional portion of | ||
| 288 | * Baud rate generator divisor | ||
| 289 | */ | ||
| 290 | #define MAX3107_BRGCFG_2XMODE_BIT (1 << 4) /* Double baud rate */ | ||
| 291 | #define MAX3107_BRGCFG_4XMODE_BIT (1 << 5) /* Quadruple baud rate */ | ||
| 292 | #define MAX3107_BRGCFG_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
| 293 | #define MAX3107_BRGCFG_UNDEF7_BIT (1 << 7) /* Undefined/not used */ | ||
| 294 | |||
| 295 | /* Clock source register bits */ | ||
| 296 | #define MAX3107_CLKSRC_INTOSC_BIT (1 << 0) /* Internal osc enable */ | ||
| 297 | #define MAX3107_CLKSRC_CRYST_BIT (1 << 1) /* Crystal osc enable */ | ||
| 298 | #define MAX3107_CLKSRC_PLL_BIT (1 << 2) /* PLL enable */ | ||
| 299 | #define MAX3107_CLKSRC_PLLBYP_BIT (1 << 3) /* PLL bypass */ | ||
| 300 | #define MAX3107_CLKSRC_EXTCLK_BIT (1 << 4) /* External clock enable */ | ||
| 301 | #define MAX3107_CLKSRC_UNDEF5_BIT (1 << 5) /* Undefined/not used */ | ||
| 302 | #define MAX3107_CLKSRC_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
| 303 | #define MAX3107_CLKSRC_CLK2RTS_BIT (1 << 7) /* Baud clk to RTS pin */ | ||
| 304 | |||
| 305 | |||
| 306 | /* HW definitions */ | ||
| 307 | #define MAX3107_RX_FIFO_SIZE 128 | ||
| 308 | #define MAX3107_TX_FIFO_SIZE 128 | ||
| 309 | #define MAX3107_REVID1 0x00a0 | ||
| 310 | #define MAX3107_REVID2 0x00a1 | ||
| 311 | |||
| 312 | |||
| 313 | /* Baud rate generator configuration values for external clock 13MHz */ | ||
| 314 | #define MAX3107_BRG13_B300 (0x0A9400 | 0x05) | ||
| 315 | #define MAX3107_BRG13_B600 (0x054A00 | 0x03) | ||
| 316 | #define MAX3107_BRG13_B1200 (0x02A500 | 0x01) | ||
| 317 | #define MAX3107_BRG13_B2400 (0x015200 | 0x09) | ||
| 318 | #define MAX3107_BRG13_B4800 (0x00A900 | 0x04) | ||
| 319 | #define MAX3107_BRG13_B9600 (0x005400 | 0x0A) | ||
| 320 | #define MAX3107_BRG13_B19200 (0x002A00 | 0x05) | ||
| 321 | #define MAX3107_BRG13_B38400 (0x001500 | 0x03) | ||
| 322 | #define MAX3107_BRG13_B57600 (0x000E00 | 0x02) | ||
| 323 | #define MAX3107_BRG13_B115200 (0x000700 | 0x01) | ||
| 324 | #define MAX3107_BRG13_B230400 (0x000300 | 0x08) | ||
| 325 | #define MAX3107_BRG13_B460800 (0x000100 | 0x0c) | ||
| 326 | #define MAX3107_BRG13_B921600 (0x000100 | 0x1c) | ||
| 327 | |||
| 328 | /* Baud rate generator configuration values for external clock 26MHz */ | ||
| 329 | #define MAX3107_BRG26_B300 (0x152800 | 0x0A) | ||
| 330 | #define MAX3107_BRG26_B600 (0x0A9400 | 0x05) | ||
| 331 | #define MAX3107_BRG26_B1200 (0x054A00 | 0x03) | ||
| 332 | #define MAX3107_BRG26_B2400 (0x02A500 | 0x01) | ||
| 333 | #define MAX3107_BRG26_B4800 (0x015200 | 0x09) | ||
| 334 | #define MAX3107_BRG26_B9600 (0x00A900 | 0x04) | ||
| 335 | #define MAX3107_BRG26_B19200 (0x005400 | 0x0A) | ||
| 336 | #define MAX3107_BRG26_B38400 (0x002A00 | 0x05) | ||
| 337 | #define MAX3107_BRG26_B57600 (0x001C00 | 0x03) | ||
| 338 | #define MAX3107_BRG26_B115200 (0x000E00 | 0x02) | ||
| 339 | #define MAX3107_BRG26_B230400 (0x000700 | 0x01) | ||
| 340 | #define MAX3107_BRG26_B460800 (0x000300 | 0x08) | ||
| 341 | #define MAX3107_BRG26_B921600 (0x000100 | 0x0C) | ||
| 342 | |||
| 343 | /* Baud rate generator configuration values for internal clock */ | ||
| 344 | #define MAX3107_BRG13_IB300 (0x008000 | 0x00) | ||
| 345 | #define MAX3107_BRG13_IB600 (0x004000 | 0x00) | ||
| 346 | #define MAX3107_BRG13_IB1200 (0x002000 | 0x00) | ||
| 347 | #define MAX3107_BRG13_IB2400 (0x001000 | 0x00) | ||
| 348 | #define MAX3107_BRG13_IB4800 (0x000800 | 0x00) | ||
| 349 | #define MAX3107_BRG13_IB9600 (0x000400 | 0x00) | ||
| 350 | #define MAX3107_BRG13_IB19200 (0x000200 | 0x00) | ||
| 351 | #define MAX3107_BRG13_IB38400 (0x000100 | 0x00) | ||
| 352 | #define MAX3107_BRG13_IB57600 (0x000000 | 0x0B) | ||
| 353 | #define MAX3107_BRG13_IB115200 (0x000000 | 0x05) | ||
| 354 | #define MAX3107_BRG13_IB230400 (0x000000 | 0x03) | ||
| 355 | #define MAX3107_BRG13_IB460800 (0x000000 | 0x00) | ||
| 356 | #define MAX3107_BRG13_IB921600 (0x000000 | 0x00) | ||
| 357 | |||
| 358 | |||
| 359 | struct baud_table { | ||
| 360 | int baud; | ||
| 361 | u32 new_brg; | ||
| 362 | }; | ||
| 363 | |||
| 364 | struct max3107_port { | ||
| 365 | /* UART port structure */ | ||
| 366 | struct uart_port port; | ||
| 367 | |||
| 368 | /* SPI device structure */ | ||
| 369 | struct spi_device *spi; | ||
| 370 | |||
| 371 | #if defined(CONFIG_GPIOLIB) | ||
| 372 | /* GPIO chip structure */ | ||
| 373 | struct gpio_chip chip; | ||
| 374 | #endif | ||
| 375 | |||
| 376 | /* Workqueue that does all the magic */ | ||
| 377 | struct workqueue_struct *workqueue; | ||
| 378 | struct work_struct work; | ||
| 379 | |||
| 380 | /* Lock for shared data */ | ||
| 381 | spinlock_t data_lock; | ||
| 382 | |||
| 383 | /* Device configuration */ | ||
| 384 | int ext_clk; /* 1 if external clock used */ | ||
| 385 | int loopback; /* Current loopback mode state */ | ||
| 386 | int baud; /* Current baud rate */ | ||
| 387 | |||
| 388 | /* State flags */ | ||
| 389 | int suspended; /* Indicates suspend mode */ | ||
| 390 | int tx_fifo_empty; /* Flag for TX FIFO state */ | ||
| 391 | int rx_enabled; /* Flag for receiver state */ | ||
| 392 | int tx_enabled; /* Flag for transmitter state */ | ||
| 393 | |||
| 394 | u16 irqen_reg; /* Current IRQ enable register value */ | ||
| 395 | /* Shared data */ | ||
| 396 | u16 mode1_reg; /* Current mode1 register value*/ | ||
| 397 | int mode1_commit; /* Flag for setting new mode1 register value */ | ||
| 398 | u16 lcr_reg; /* Current LCR register value */ | ||
| 399 | int lcr_commit; /* Flag for setting new LCR register value */ | ||
| 400 | u32 brg_cfg; /* Current Baud rate generator config */ | ||
| 401 | int brg_commit; /* Flag for setting new baud rate generator | ||
| 402 | * config | ||
| 403 | */ | ||
| 404 | struct baud_table *baud_tbl; | ||
| 405 | int handle_irq; /* Indicates that IRQ should be handled */ | ||
| 406 | |||
| 407 | /* Rx buffer and str*/ | ||
| 408 | u16 *rxbuf; | ||
| 409 | u8 *rxstr; | ||
| 410 | /* Tx buffer*/ | ||
| 411 | u16 *txbuf; | ||
| 412 | |||
| 413 | struct max3107_plat *pdata; /* Platform data */ | ||
| 414 | }; | ||
| 415 | |||
| 416 | /* Platform data structure */ | ||
| 417 | struct max3107_plat { | ||
| 418 | /* Loopback mode enable */ | ||
| 419 | int loopback; | ||
| 420 | /* External clock enable */ | ||
| 421 | int ext_clk; | ||
| 422 | /* Called during the register initialisation */ | ||
| 423 | void (*init)(struct max3107_port *s); | ||
| 424 | /* Called when the port is found and configured */ | ||
| 425 | int (*configure)(struct max3107_port *s); | ||
| 426 | /* HW suspend function */ | ||
| 427 | void (*hw_suspend) (struct max3107_port *s, int suspend); | ||
| 428 | /* Polling mode enable */ | ||
| 429 | int polled_mode; | ||
| 430 | /* Polling period if polling mode enabled */ | ||
| 431 | int poll_time; | ||
| 432 | }; | ||
| 433 | |||
| 434 | extern int max3107_rw(struct max3107_port *s, u8 *tx, u8 *rx, int len); | ||
| 435 | extern void max3107_hw_susp(struct max3107_port *s, int suspend); | ||
| 436 | extern int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata); | ||
| 437 | extern int max3107_remove(struct spi_device *spi); | ||
| 438 | extern int max3107_suspend(struct spi_device *spi, pm_message_t state); | ||
| 439 | extern int max3107_resume(struct spi_device *spi); | ||
| 440 | |||
| 441 | #endif /* _LINUX_SERIAL_MAX3107_H */ | ||
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c new file mode 100644 index 000000000000..2bc28a59d385 --- /dev/null +++ b/drivers/tty/serial/max310x.c | |||
| @@ -0,0 +1,1260 @@ | |||
| 1 | /* | ||
| 2 | * Maxim (Dallas) MAX3107/8 serial driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> | ||
| 5 | * | ||
| 6 | * Based on max3100.c, by Christian Pellegrin <chripell@evolware.org> | ||
| 7 | * Based on max3110.c, by Feng Tang <feng.tang@intel.com> | ||
| 8 | * Based on max3107.c, by Aavamobile | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | */ | ||
| 15 | |||
| 16 | /* TODO: MAX3109 support (Dual) */ | ||
| 17 | /* TODO: MAX14830 support (Quad) */ | ||
| 18 | |||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/device.h> | ||
| 21 | #include <linux/serial_core.h> | ||
| 22 | #include <linux/serial.h> | ||
| 23 | #include <linux/tty.h> | ||
| 24 | #include <linux/tty_flip.h> | ||
| 25 | #include <linux/regmap.h> | ||
| 26 | #include <linux/gpio.h> | ||
| 27 | #include <linux/spi/spi.h> | ||
| 28 | #include <linux/platform_data/max310x.h> | ||
| 29 | |||
| 30 | #define MAX310X_MAJOR 204 | ||
| 31 | #define MAX310X_MINOR 209 | ||
| 32 | |||
| 33 | /* MAX310X register definitions */ | ||
| 34 | #define MAX310X_RHR_REG (0x00) /* RX FIFO */ | ||
| 35 | #define MAX310X_THR_REG (0x00) /* TX FIFO */ | ||
| 36 | #define MAX310X_IRQEN_REG (0x01) /* IRQ enable */ | ||
| 37 | #define MAX310X_IRQSTS_REG (0x02) /* IRQ status */ | ||
| 38 | #define MAX310X_LSR_IRQEN_REG (0x03) /* LSR IRQ enable */ | ||
| 39 | #define MAX310X_LSR_IRQSTS_REG (0x04) /* LSR IRQ status */ | ||
| 40 | #define MAX310X_SPCHR_IRQEN_REG (0x05) /* Special char IRQ enable */ | ||
| 41 | #define MAX310X_SPCHR_IRQSTS_REG (0x06) /* Special char IRQ status */ | ||
| 42 | #define MAX310X_STS_IRQEN_REG (0x07) /* Status IRQ enable */ | ||
| 43 | #define MAX310X_STS_IRQSTS_REG (0x08) /* Status IRQ status */ | ||
| 44 | #define MAX310X_MODE1_REG (0x09) /* MODE1 */ | ||
| 45 | #define MAX310X_MODE2_REG (0x0a) /* MODE2 */ | ||
| 46 | #define MAX310X_LCR_REG (0x0b) /* LCR */ | ||
| 47 | #define MAX310X_RXTO_REG (0x0c) /* RX timeout */ | ||
| 48 | #define MAX310X_HDPIXDELAY_REG (0x0d) /* Auto transceiver delays */ | ||
| 49 | #define MAX310X_IRDA_REG (0x0e) /* IRDA settings */ | ||
| 50 | #define MAX310X_FLOWLVL_REG (0x0f) /* Flow control levels */ | ||
| 51 | #define MAX310X_FIFOTRIGLVL_REG (0x10) /* FIFO IRQ trigger levels */ | ||
| 52 | #define MAX310X_TXFIFOLVL_REG (0x11) /* TX FIFO level */ | ||
| 53 | #define MAX310X_RXFIFOLVL_REG (0x12) /* RX FIFO level */ | ||
| 54 | #define MAX310X_FLOWCTRL_REG (0x13) /* Flow control */ | ||
| 55 | #define MAX310X_XON1_REG (0x14) /* XON1 character */ | ||
| 56 | #define MAX310X_XON2_REG (0x15) /* XON2 character */ | ||
| 57 | #define MAX310X_XOFF1_REG (0x16) /* XOFF1 character */ | ||
| 58 | #define MAX310X_XOFF2_REG (0x17) /* XOFF2 character */ | ||
| 59 | #define MAX310X_GPIOCFG_REG (0x18) /* GPIO config */ | ||
| 60 | #define MAX310X_GPIODATA_REG (0x19) /* GPIO data */ | ||
| 61 | #define MAX310X_PLLCFG_REG (0x1a) /* PLL config */ | ||
| 62 | #define MAX310X_BRGCFG_REG (0x1b) /* Baud rate generator conf */ | ||
| 63 | #define MAX310X_BRGDIVLSB_REG (0x1c) /* Baud rate divisor LSB */ | ||
| 64 | #define MAX310X_BRGDIVMSB_REG (0x1d) /* Baud rate divisor MSB */ | ||
| 65 | #define MAX310X_CLKSRC_REG (0x1e) /* Clock source */ | ||
| 66 | /* Only present in MAX3107 */ | ||
| 67 | #define MAX3107_REVID_REG (0x1f) /* Revision identification */ | ||
| 68 | |||
| 69 | /* IRQ register bits */ | ||
| 70 | #define MAX310X_IRQ_LSR_BIT (1 << 0) /* LSR interrupt */ | ||
| 71 | #define MAX310X_IRQ_SPCHR_BIT (1 << 1) /* Special char interrupt */ | ||
| 72 | #define MAX310X_IRQ_STS_BIT (1 << 2) /* Status interrupt */ | ||
| 73 | #define MAX310X_IRQ_RXFIFO_BIT (1 << 3) /* RX FIFO interrupt */ | ||
| 74 | #define MAX310X_IRQ_TXFIFO_BIT (1 << 4) /* TX FIFO interrupt */ | ||
| 75 | #define MAX310X_IRQ_TXEMPTY_BIT (1 << 5) /* TX FIFO empty interrupt */ | ||
| 76 | #define MAX310X_IRQ_RXEMPTY_BIT (1 << 6) /* RX FIFO empty interrupt */ | ||
| 77 | #define MAX310X_IRQ_CTS_BIT (1 << 7) /* CTS interrupt */ | ||
| 78 | |||
| 79 | /* LSR register bits */ | ||
| 80 | #define MAX310X_LSR_RXTO_BIT (1 << 0) /* RX timeout */ | ||
| 81 | #define MAX310X_LSR_RXOVR_BIT (1 << 1) /* RX overrun */ | ||
| 82 | #define MAX310X_LSR_RXPAR_BIT (1 << 2) /* RX parity error */ | ||
| 83 | #define MAX310X_LSR_FRERR_BIT (1 << 3) /* Frame error */ | ||
| 84 | #define MAX310X_LSR_RXBRK_BIT (1 << 4) /* RX break */ | ||
| 85 | #define MAX310X_LSR_RXNOISE_BIT (1 << 5) /* RX noise */ | ||
| 86 | #define MAX310X_LSR_CTS_BIT (1 << 7) /* CTS pin state */ | ||
| 87 | |||
| 88 | /* Special character register bits */ | ||
| 89 | #define MAX310X_SPCHR_XON1_BIT (1 << 0) /* XON1 character */ | ||
| 90 | #define MAX310X_SPCHR_XON2_BIT (1 << 1) /* XON2 character */ | ||
| 91 | #define MAX310X_SPCHR_XOFF1_BIT (1 << 2) /* XOFF1 character */ | ||
| 92 | #define MAX310X_SPCHR_XOFF2_BIT (1 << 3) /* XOFF2 character */ | ||
| 93 | #define MAX310X_SPCHR_BREAK_BIT (1 << 4) /* RX break */ | ||
| 94 | #define MAX310X_SPCHR_MULTIDROP_BIT (1 << 5) /* 9-bit multidrop addr char */ | ||
| 95 | |||
| 96 | /* Status register bits */ | ||
| 97 | #define MAX310X_STS_GPIO0_BIT (1 << 0) /* GPIO 0 interrupt */ | ||
| 98 | #define MAX310X_STS_GPIO1_BIT (1 << 1) /* GPIO 1 interrupt */ | ||
| 99 | #define MAX310X_STS_GPIO2_BIT (1 << 2) /* GPIO 2 interrupt */ | ||
| 100 | #define MAX310X_STS_GPIO3_BIT (1 << 3) /* GPIO 3 interrupt */ | ||
| 101 | #define MAX310X_STS_CLKREADY_BIT (1 << 5) /* Clock ready */ | ||
| 102 | #define MAX310X_STS_SLEEP_BIT (1 << 6) /* Sleep interrupt */ | ||
| 103 | |||
| 104 | /* MODE1 register bits */ | ||
| 105 | #define MAX310X_MODE1_RXDIS_BIT (1 << 0) /* RX disable */ | ||
| 106 | #define MAX310X_MODE1_TXDIS_BIT (1 << 1) /* TX disable */ | ||
| 107 | #define MAX310X_MODE1_TXHIZ_BIT (1 << 2) /* TX pin three-state */ | ||
| 108 | #define MAX310X_MODE1_RTSHIZ_BIT (1 << 3) /* RTS pin three-state */ | ||
| 109 | #define MAX310X_MODE1_TRNSCVCTRL_BIT (1 << 4) /* Transceiver ctrl enable */ | ||
| 110 | #define MAX310X_MODE1_FORCESLEEP_BIT (1 << 5) /* Force sleep mode */ | ||
| 111 | #define MAX310X_MODE1_AUTOSLEEP_BIT (1 << 6) /* Auto sleep enable */ | ||
| 112 | #define MAX310X_MODE1_IRQSEL_BIT (1 << 7) /* IRQ pin enable */ | ||
| 113 | |||
| 114 | /* MODE2 register bits */ | ||
| 115 | #define MAX310X_MODE2_RST_BIT (1 << 0) /* Chip reset */ | ||
| 116 | #define MAX310X_MODE2_FIFORST_BIT (1 << 1) /* FIFO reset */ | ||
| 117 | #define MAX310X_MODE2_RXTRIGINV_BIT (1 << 2) /* RX FIFO INT invert */ | ||
| 118 | #define MAX310X_MODE2_RXEMPTINV_BIT (1 << 3) /* RX FIFO empty INT invert */ | ||
| 119 | #define MAX310X_MODE2_SPCHR_BIT (1 << 4) /* Special chr detect enable */ | ||
| 120 | #define MAX310X_MODE2_LOOPBACK_BIT (1 << 5) /* Internal loopback enable */ | ||
| 121 | #define MAX310X_MODE2_MULTIDROP_BIT (1 << 6) /* 9-bit multidrop enable */ | ||
| 122 | #define MAX310X_MODE2_ECHOSUPR_BIT (1 << 7) /* ECHO suppression enable */ | ||
| 123 | |||
| 124 | /* LCR register bits */ | ||
| 125 | #define MAX310X_LCR_LENGTH0_BIT (1 << 0) /* Word length bit 0 */ | ||
| 126 | #define MAX310X_LCR_LENGTH1_BIT (1 << 1) /* Word length bit 1 | ||
| 127 | * | ||
| 128 | * Word length bits table: | ||
| 129 | * 00 -> 5 bit words | ||
| 130 | * 01 -> 6 bit words | ||
| 131 | * 10 -> 7 bit words | ||
| 132 | * 11 -> 8 bit words | ||
| 133 | */ | ||
| 134 | #define MAX310X_LCR_STOPLEN_BIT (1 << 2) /* STOP length bit | ||
| 135 | * | ||
| 136 | * STOP length bit table: | ||
| 137 | * 0 -> 1 stop bit | ||
| 138 | * 1 -> 1-1.5 stop bits if | ||
| 139 | * word length is 5, | ||
| 140 | * 2 stop bits otherwise | ||
| 141 | */ | ||
| 142 | #define MAX310X_LCR_PARITY_BIT (1 << 3) /* Parity bit enable */ | ||
| 143 | #define MAX310X_LCR_EVENPARITY_BIT (1 << 4) /* Even parity bit enable */ | ||
| 144 | #define MAX310X_LCR_FORCEPARITY_BIT (1 << 5) /* 9-bit multidrop parity */ | ||
| 145 | #define MAX310X_LCR_TXBREAK_BIT (1 << 6) /* TX break enable */ | ||
| 146 | #define MAX310X_LCR_RTS_BIT (1 << 7) /* RTS pin control */ | ||
| 147 | #define MAX310X_LCR_WORD_LEN_5 (0x00) | ||
| 148 | #define MAX310X_LCR_WORD_LEN_6 (0x01) | ||
| 149 | #define MAX310X_LCR_WORD_LEN_7 (0x02) | ||
| 150 | #define MAX310X_LCR_WORD_LEN_8 (0x03) | ||
| 151 | |||
| 152 | /* IRDA register bits */ | ||
| 153 | #define MAX310X_IRDA_IRDAEN_BIT (1 << 0) /* IRDA mode enable */ | ||
| 154 | #define MAX310X_IRDA_SIR_BIT (1 << 1) /* SIR mode enable */ | ||
| 155 | #define MAX310X_IRDA_SHORTIR_BIT (1 << 2) /* Short SIR mode enable */ | ||
| 156 | #define MAX310X_IRDA_MIR_BIT (1 << 3) /* MIR mode enable */ | ||
| 157 | #define MAX310X_IRDA_RXINV_BIT (1 << 4) /* RX logic inversion enable */ | ||
| 158 | #define MAX310X_IRDA_TXINV_BIT (1 << 5) /* TX logic inversion enable */ | ||
| 159 | |||
| 160 | /* Flow control trigger level register masks */ | ||
| 161 | #define MAX310X_FLOWLVL_HALT_MASK (0x000f) /* Flow control halt level */ | ||
| 162 | #define MAX310X_FLOWLVL_RES_MASK (0x00f0) /* Flow control resume level */ | ||
| 163 | #define MAX310X_FLOWLVL_HALT(words) ((words / 8) & 0x0f) | ||
| 164 | #define MAX310X_FLOWLVL_RES(words) (((words / 8) & 0x0f) << 4) | ||
| 165 | |||
| 166 | /* FIFO interrupt trigger level register masks */ | ||
| 167 | #define MAX310X_FIFOTRIGLVL_TX_MASK (0x0f) /* TX FIFO trigger level */ | ||
| 168 | #define MAX310X_FIFOTRIGLVL_RX_MASK (0xf0) /* RX FIFO trigger level */ | ||
| 169 | #define MAX310X_FIFOTRIGLVL_TX(words) ((words / 8) & 0x0f) | ||
| 170 | #define MAX310X_FIFOTRIGLVL_RX(words) (((words / 8) & 0x0f) << 4) | ||
| 171 | |||
| 172 | /* Flow control register bits */ | ||
| 173 | #define MAX310X_FLOWCTRL_AUTORTS_BIT (1 << 0) /* Auto RTS flow ctrl enable */ | ||
| 174 | #define MAX310X_FLOWCTRL_AUTOCTS_BIT (1 << 1) /* Auto CTS flow ctrl enable */ | ||
| 175 | #define MAX310X_FLOWCTRL_GPIADDR_BIT (1 << 2) /* Enables that GPIO inputs | ||
| 176 | * are used in conjunction with | ||
| 177 | * XOFF2 for definition of | ||
| 178 | * special character */ | ||
| 179 | #define MAX310X_FLOWCTRL_SWFLOWEN_BIT (1 << 3) /* Auto SW flow ctrl enable */ | ||
| 180 | #define MAX310X_FLOWCTRL_SWFLOW0_BIT (1 << 4) /* SWFLOW bit 0 */ | ||
| 181 | #define MAX310X_FLOWCTRL_SWFLOW1_BIT (1 << 5) /* SWFLOW bit 1 | ||
| 182 | * | ||
| 183 | * SWFLOW bits 1 & 0 table: | ||
| 184 | * 00 -> no transmitter flow | ||
| 185 | * control | ||
| 186 | * 01 -> receiver compares | ||
| 187 | * XON2 and XOFF2 | ||
| 188 | * and controls | ||
| 189 | * transmitter | ||
| 190 | * 10 -> receiver compares | ||
| 191 | * XON1 and XOFF1 | ||
| 192 | * and controls | ||
| 193 | * transmitter | ||
| 194 | * 11 -> receiver compares | ||
| 195 | * XON1, XON2, XOFF1 and | ||
| 196 | * XOFF2 and controls | ||
| 197 | * transmitter | ||
| 198 | */ | ||
| 199 | #define MAX310X_FLOWCTRL_SWFLOW2_BIT (1 << 6) /* SWFLOW bit 2 */ | ||
| 200 | #define MAX310X_FLOWCTRL_SWFLOW3_BIT (1 << 7) /* SWFLOW bit 3 | ||
| 201 | * | ||
| 202 | * SWFLOW bits 3 & 2 table: | ||
| 203 | * 00 -> no received flow | ||
| 204 | * control | ||
| 205 | * 01 -> transmitter generates | ||
| 206 | * XON2 and XOFF2 | ||
| 207 | * 10 -> transmitter generates | ||
| 208 | * XON1 and XOFF1 | ||
| 209 | * 11 -> transmitter generates | ||
| 210 | * XON1, XON2, XOFF1 and | ||
| 211 | * XOFF2 | ||
| 212 | */ | ||
| 213 | |||
| 214 | /* GPIO configuration register bits */ | ||
| 215 | #define MAX310X_GPIOCFG_GP0OUT_BIT (1 << 0) /* GPIO 0 output enable */ | ||
| 216 | #define MAX310X_GPIOCFG_GP1OUT_BIT (1 << 1) /* GPIO 1 output enable */ | ||
| 217 | #define MAX310X_GPIOCFG_GP2OUT_BIT (1 << 2) /* GPIO 2 output enable */ | ||
| 218 | #define MAX310X_GPIOCFG_GP3OUT_BIT (1 << 3) /* GPIO 3 output enable */ | ||
| 219 | #define MAX310X_GPIOCFG_GP0OD_BIT (1 << 4) /* GPIO 0 open-drain enable */ | ||
| 220 | #define MAX310X_GPIOCFG_GP1OD_BIT (1 << 5) /* GPIO 1 open-drain enable */ | ||
| 221 | #define MAX310X_GPIOCFG_GP2OD_BIT (1 << 6) /* GPIO 2 open-drain enable */ | ||
| 222 | #define MAX310X_GPIOCFG_GP3OD_BIT (1 << 7) /* GPIO 3 open-drain enable */ | ||
| 223 | |||
| 224 | /* GPIO DATA register bits */ | ||
| 225 | #define MAX310X_GPIODATA_GP0OUT_BIT (1 << 0) /* GPIO 0 output value */ | ||
| 226 | #define MAX310X_GPIODATA_GP1OUT_BIT (1 << 1) /* GPIO 1 output value */ | ||
| 227 | #define MAX310X_GPIODATA_GP2OUT_BIT (1 << 2) /* GPIO 2 output value */ | ||
| 228 | #define MAX310X_GPIODATA_GP3OUT_BIT (1 << 3) /* GPIO 3 output value */ | ||
| 229 | #define MAX310X_GPIODATA_GP0IN_BIT (1 << 4) /* GPIO 0 input value */ | ||
| 230 | #define MAX310X_GPIODATA_GP1IN_BIT (1 << 5) /* GPIO 1 input value */ | ||
| 231 | #define MAX310X_GPIODATA_GP2IN_BIT (1 << 6) /* GPIO 2 input value */ | ||
| 232 | #define MAX310X_GPIODATA_GP3IN_BIT (1 << 7) /* GPIO 3 input value */ | ||
| 233 | |||
| 234 | /* PLL configuration register masks */ | ||
| 235 | #define MAX310X_PLLCFG_PREDIV_MASK (0x3f) /* PLL predivision value */ | ||
| 236 | #define MAX310X_PLLCFG_PLLFACTOR_MASK (0xc0) /* PLL multiplication factor */ | ||
| 237 | |||
| 238 | /* Baud rate generator configuration register bits */ | ||
| 239 | #define MAX310X_BRGCFG_2XMODE_BIT (1 << 4) /* Double baud rate */ | ||
| 240 | #define MAX310X_BRGCFG_4XMODE_BIT (1 << 5) /* Quadruple baud rate */ | ||
| 241 | |||
| 242 | /* Clock source register bits */ | ||
| 243 | #define MAX310X_CLKSRC_CRYST_BIT (1 << 1) /* Crystal osc enable */ | ||
| 244 | #define MAX310X_CLKSRC_PLL_BIT (1 << 2) /* PLL enable */ | ||
| 245 | #define MAX310X_CLKSRC_PLLBYP_BIT (1 << 3) /* PLL bypass */ | ||
| 246 | #define MAX310X_CLKSRC_EXTCLK_BIT (1 << 4) /* External clock enable */ | ||
| 247 | #define MAX310X_CLKSRC_CLK2RTS_BIT (1 << 7) /* Baud clk to RTS pin */ | ||
| 248 | |||
| 249 | /* Misc definitions */ | ||
| 250 | #define MAX310X_FIFO_SIZE (128) | ||
| 251 | |||
| 252 | /* MAX3107 specific */ | ||
| 253 | #define MAX3107_REV_ID (0xa0) | ||
| 254 | #define MAX3107_REV_MASK (0xfe) | ||
| 255 | |||
| 256 | /* IRQ status bits definitions */ | ||
| 257 | #define MAX310X_IRQ_TX (MAX310X_IRQ_TXFIFO_BIT | \ | ||
| 258 | MAX310X_IRQ_TXEMPTY_BIT) | ||
| 259 | #define MAX310X_IRQ_RX (MAX310X_IRQ_RXFIFO_BIT | \ | ||
| 260 | MAX310X_IRQ_RXEMPTY_BIT) | ||
| 261 | |||
| 262 | /* Supported chip types */ | ||
| 263 | enum { | ||
| 264 | MAX310X_TYPE_MAX3107 = 3107, | ||
| 265 | MAX310X_TYPE_MAX3108 = 3108, | ||
| 266 | }; | ||
| 267 | |||
| 268 | struct max310x_port { | ||
| 269 | struct uart_driver uart; | ||
| 270 | struct uart_port port; | ||
| 271 | |||
| 272 | const char *name; | ||
| 273 | int uartclk; | ||
| 274 | |||
| 275 | unsigned int nr_gpio; | ||
| 276 | #ifdef CONFIG_GPIOLIB | ||
| 277 | struct gpio_chip gpio; | ||
| 278 | #endif | ||
| 279 | |||
| 280 | struct regmap *regmap; | ||
| 281 | struct regmap_config regcfg; | ||
| 282 | |||
| 283 | struct workqueue_struct *wq; | ||
| 284 | struct work_struct tx_work; | ||
| 285 | |||
| 286 | struct mutex max310x_mutex; | ||
| 287 | |||
| 288 | struct max310x_pdata *pdata; | ||
| 289 | }; | ||
| 290 | |||
| 291 | static bool max3107_8_reg_writeable(struct device *dev, unsigned int reg) | ||
| 292 | { | ||
| 293 | switch (reg) { | ||
| 294 | case MAX310X_IRQSTS_REG: | ||
| 295 | case MAX310X_LSR_IRQSTS_REG: | ||
| 296 | case MAX310X_SPCHR_IRQSTS_REG: | ||
| 297 | case MAX310X_STS_IRQSTS_REG: | ||
| 298 | case MAX310X_TXFIFOLVL_REG: | ||
| 299 | case MAX310X_RXFIFOLVL_REG: | ||
| 300 | case MAX3107_REVID_REG: /* Only available on MAX3107 */ | ||
| 301 | return false; | ||
| 302 | default: | ||
| 303 | break; | ||
| 304 | } | ||
| 305 | |||
| 306 | return true; | ||
| 307 | } | ||
| 308 | |||
| 309 | static bool max310x_reg_volatile(struct device *dev, unsigned int reg) | ||
| 310 | { | ||
| 311 | switch (reg) { | ||
| 312 | case MAX310X_RHR_REG: | ||
| 313 | case MAX310X_IRQSTS_REG: | ||
| 314 | case MAX310X_LSR_IRQSTS_REG: | ||
| 315 | case MAX310X_SPCHR_IRQSTS_REG: | ||
| 316 | case MAX310X_STS_IRQSTS_REG: | ||
| 317 | case MAX310X_TXFIFOLVL_REG: | ||
| 318 | case MAX310X_RXFIFOLVL_REG: | ||
| 319 | case MAX310X_GPIODATA_REG: | ||
| 320 | return true; | ||
| 321 | default: | ||
| 322 | break; | ||
| 323 | } | ||
| 324 | |||
| 325 | return false; | ||
| 326 | } | ||
| 327 | |||
| 328 | static bool max310x_reg_precious(struct device *dev, unsigned int reg) | ||
| 329 | { | ||
| 330 | switch (reg) { | ||
| 331 | case MAX310X_RHR_REG: | ||
| 332 | case MAX310X_IRQSTS_REG: | ||
| 333 | case MAX310X_SPCHR_IRQSTS_REG: | ||
| 334 | case MAX310X_STS_IRQSTS_REG: | ||
| 335 | return true; | ||
| 336 | default: | ||
| 337 | break; | ||
| 338 | } | ||
| 339 | |||
| 340 | return false; | ||
| 341 | } | ||
| 342 | |||
| 343 | static void max310x_set_baud(struct max310x_port *s, int baud) | ||
| 344 | { | ||
| 345 | unsigned int mode = 0, div = s->uartclk / baud; | ||
| 346 | |||
| 347 | if (!(div / 16)) { | ||
| 348 | /* Mode x2 */ | ||
| 349 | mode = MAX310X_BRGCFG_2XMODE_BIT; | ||
| 350 | div = (s->uartclk * 2) / baud; | ||
| 351 | } | ||
| 352 | |||
| 353 | if (!(div / 16)) { | ||
| 354 | /* Mode x4 */ | ||
| 355 | mode = MAX310X_BRGCFG_4XMODE_BIT; | ||
| 356 | div = (s->uartclk * 4) / baud; | ||
| 357 | } | ||
| 358 | |||
| 359 | regmap_write(s->regmap, MAX310X_BRGDIVMSB_REG, | ||
| 360 | ((div / 16) >> 8) & 0xff); | ||
| 361 | regmap_write(s->regmap, MAX310X_BRGDIVLSB_REG, (div / 16) & 0xff); | ||
| 362 | regmap_write(s->regmap, MAX310X_BRGCFG_REG, (div % 16) | mode); | ||
| 363 | } | ||
| 364 | |||
| 365 | static void max310x_wait_pll(struct max310x_port *s) | ||
| 366 | { | ||
| 367 | int tryes = 1000; | ||
| 368 | |||
| 369 | /* Wait for PLL only if crystal is used */ | ||
| 370 | if (!(s->pdata->driver_flags & MAX310X_EXT_CLK)) { | ||
| 371 | unsigned int sts = 0; | ||
| 372 | |||
| 373 | while (tryes--) { | ||
| 374 | regmap_read(s->regmap, MAX310X_STS_IRQSTS_REG, &sts); | ||
| 375 | if (sts & MAX310X_STS_CLKREADY_BIT) | ||
| 376 | break; | ||
| 377 | } | ||
| 378 | } | ||
| 379 | } | ||
| 380 | |||
| 381 | static int __devinit max310x_update_best_err(unsigned long f, long *besterr) | ||
| 382 | { | ||
| 383 | /* Use baudrate 115200 for calculate error */ | ||
| 384 | long err = f % (115200 * 16); | ||
| 385 | |||
| 386 | if ((*besterr < 0) || (*besterr > err)) { | ||
| 387 | *besterr = err; | ||
| 388 | return 0; | ||
| 389 | } | ||
| 390 | |||
| 391 | return 1; | ||
| 392 | } | ||
| 393 | |||
| 394 | static int __devinit max310x_set_ref_clk(struct max310x_port *s) | ||
| 395 | { | ||
| 396 | unsigned int div, clksrc, pllcfg = 0; | ||
| 397 | long besterr = -1; | ||
| 398 | unsigned long fdiv, fmul, bestfreq = s->pdata->frequency; | ||
| 399 | |||
| 400 | /* First, update error without PLL */ | ||
| 401 | max310x_update_best_err(s->pdata->frequency, &besterr); | ||
| 402 | |||
| 403 | /* Try all possible PLL dividers */ | ||
| 404 | for (div = 1; (div <= 63) && besterr; div++) { | ||
| 405 | fdiv = DIV_ROUND_CLOSEST(s->pdata->frequency, div); | ||
| 406 | |||
| 407 | /* Try multiplier 6 */ | ||
| 408 | fmul = fdiv * 6; | ||
| 409 | if ((fdiv >= 500000) && (fdiv <= 800000)) | ||
| 410 | if (!max310x_update_best_err(fmul, &besterr)) { | ||
| 411 | pllcfg = (0 << 6) | div; | ||
| 412 | bestfreq = fmul; | ||
| 413 | } | ||
| 414 | /* Try multiplier 48 */ | ||
| 415 | fmul = fdiv * 48; | ||
| 416 | if ((fdiv >= 850000) && (fdiv <= 1200000)) | ||
| 417 | if (!max310x_update_best_err(fmul, &besterr)) { | ||
| 418 | pllcfg = (1 << 6) | div; | ||
| 419 | bestfreq = fmul; | ||
| 420 | } | ||
| 421 | /* Try multiplier 96 */ | ||
| 422 | fmul = fdiv * 96; | ||
| 423 | if ((fdiv >= 425000) && (fdiv <= 1000000)) | ||
| 424 | if (!max310x_update_best_err(fmul, &besterr)) { | ||
| 425 | pllcfg = (2 << 6) | div; | ||
| 426 | bestfreq = fmul; | ||
| 427 | } | ||
| 428 | /* Try multiplier 144 */ | ||
| 429 | fmul = fdiv * 144; | ||
| 430 | if ((fdiv >= 390000) && (fdiv <= 667000)) | ||
| 431 | if (!max310x_update_best_err(fmul, &besterr)) { | ||
| 432 | pllcfg = (3 << 6) | div; | ||
| 433 | bestfreq = fmul; | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | /* Configure clock source */ | ||
| 438 | if (s->pdata->driver_flags & MAX310X_EXT_CLK) | ||
| 439 | clksrc = MAX310X_CLKSRC_EXTCLK_BIT; | ||
| 440 | else | ||
| 441 | clksrc = MAX310X_CLKSRC_CRYST_BIT; | ||
| 442 | |||
| 443 | /* Configure PLL */ | ||
| 444 | if (pllcfg) { | ||
| 445 | clksrc |= MAX310X_CLKSRC_PLL_BIT; | ||
| 446 | regmap_write(s->regmap, MAX310X_PLLCFG_REG, pllcfg); | ||
| 447 | } else | ||
| 448 | clksrc |= MAX310X_CLKSRC_PLLBYP_BIT; | ||
| 449 | |||
| 450 | regmap_write(s->regmap, MAX310X_CLKSRC_REG, clksrc); | ||
| 451 | |||
| 452 | if (pllcfg) | ||
| 453 | max310x_wait_pll(s); | ||
| 454 | |||
| 455 | dev_dbg(s->port.dev, "Reference clock set to %lu Hz\n", bestfreq); | ||
| 456 | |||
| 457 | return (int)bestfreq; | ||
| 458 | } | ||
| 459 | |||
| 460 | static void max310x_handle_rx(struct max310x_port *s, unsigned int rxlen) | ||
| 461 | { | ||
| 462 | unsigned int sts = 0, ch = 0, flag; | ||
| 463 | struct tty_struct *tty = tty_port_tty_get(&s->port.state->port); | ||
| 464 | |||
| 465 | if (!tty) | ||
| 466 | return; | ||
| 467 | |||
| 468 | if (unlikely(rxlen >= MAX310X_FIFO_SIZE)) { | ||
| 469 | dev_warn(s->port.dev, "Possible RX FIFO overrun %d\n", rxlen); | ||
| 470 | /* Ensure sanity of RX level */ | ||
| 471 | rxlen = MAX310X_FIFO_SIZE; | ||
| 472 | } | ||
| 473 | |||
| 474 | dev_dbg(s->port.dev, "RX Len = %u\n", rxlen); | ||
| 475 | |||
| 476 | while (rxlen--) { | ||
| 477 | regmap_read(s->regmap, MAX310X_RHR_REG, &ch); | ||
| 478 | regmap_read(s->regmap, MAX310X_LSR_IRQSTS_REG, &sts); | ||
| 479 | |||
| 480 | sts &= MAX310X_LSR_RXPAR_BIT | MAX310X_LSR_FRERR_BIT | | ||
| 481 | MAX310X_LSR_RXOVR_BIT | MAX310X_LSR_RXBRK_BIT; | ||
| 482 | |||
| 483 | s->port.icount.rx++; | ||
| 484 | flag = TTY_NORMAL; | ||
| 485 | |||
| 486 | if (unlikely(sts)) { | ||
| 487 | if (sts & MAX310X_LSR_RXBRK_BIT) { | ||
| 488 | s->port.icount.brk++; | ||
| 489 | if (uart_handle_break(&s->port)) | ||
| 490 | continue; | ||
| 491 | } else if (sts & MAX310X_LSR_RXPAR_BIT) | ||
| 492 | s->port.icount.parity++; | ||
| 493 | else if (sts & MAX310X_LSR_FRERR_BIT) | ||
| 494 | s->port.icount.frame++; | ||
| 495 | else if (sts & MAX310X_LSR_RXOVR_BIT) | ||
| 496 | s->port.icount.overrun++; | ||
| 497 | |||
| 498 | sts &= s->port.read_status_mask; | ||
| 499 | if (sts & MAX310X_LSR_RXBRK_BIT) | ||
| 500 | flag = TTY_BREAK; | ||
| 501 | else if (sts & MAX310X_LSR_RXPAR_BIT) | ||
| 502 | flag = TTY_PARITY; | ||
| 503 | else if (sts & MAX310X_LSR_FRERR_BIT) | ||
| 504 | flag = TTY_FRAME; | ||
| 505 | else if (sts & MAX310X_LSR_RXOVR_BIT) | ||
| 506 | flag = TTY_OVERRUN; | ||
| 507 | } | ||
| 508 | |||
| 509 | if (uart_handle_sysrq_char(s->port, ch)) | ||
| 510 | continue; | ||
| 511 | |||
| 512 | if (sts & s->port.ignore_status_mask) | ||
| 513 | continue; | ||
| 514 | |||
| 515 | uart_insert_char(&s->port, sts, MAX310X_LSR_RXOVR_BIT, | ||
| 516 | ch, flag); | ||
| 517 | } | ||
| 518 | |||
| 519 | tty_flip_buffer_push(tty); | ||
| 520 | |||
| 521 | tty_kref_put(tty); | ||
| 522 | } | ||
| 523 | |||
| 524 | static void max310x_handle_tx(struct max310x_port *s) | ||
| 525 | { | ||
| 526 | struct circ_buf *xmit = &s->port.state->xmit; | ||
| 527 | unsigned int txlen = 0, to_send; | ||
| 528 | |||
| 529 | if (unlikely(s->port.x_char)) { | ||
| 530 | regmap_write(s->regmap, MAX310X_THR_REG, s->port.x_char); | ||
| 531 | s->port.icount.tx++; | ||
| 532 | s->port.x_char = 0; | ||
| 533 | return; | ||
| 534 | } | ||
| 535 | |||
| 536 | if (uart_circ_empty(xmit) || uart_tx_stopped(&s->port)) | ||
| 537 | return; | ||
| 538 | |||
| 539 | /* Get length of data pending in circular buffer */ | ||
| 540 | to_send = uart_circ_chars_pending(xmit); | ||
| 541 | if (likely(to_send)) { | ||
| 542 | /* Limit to size of TX FIFO */ | ||
| 543 | regmap_read(s->regmap, MAX310X_TXFIFOLVL_REG, &txlen); | ||
| 544 | txlen = MAX310X_FIFO_SIZE - txlen; | ||
| 545 | to_send = (to_send > txlen) ? txlen : to_send; | ||
| 546 | |||
| 547 | dev_dbg(s->port.dev, "TX Len = %u\n", to_send); | ||
| 548 | |||
| 549 | /* Add data to send */ | ||
| 550 | s->port.icount.tx += to_send; | ||
| 551 | while (to_send--) { | ||
| 552 | regmap_write(s->regmap, MAX310X_THR_REG, | ||
| 553 | xmit->buf[xmit->tail]); | ||
| 554 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
| 555 | }; | ||
| 556 | } | ||
| 557 | |||
| 558 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
| 559 | uart_write_wakeup(&s->port); | ||
| 560 | } | ||
| 561 | |||
| 562 | static irqreturn_t max310x_ist(int irq, void *dev_id) | ||
| 563 | { | ||
| 564 | struct max310x_port *s = (struct max310x_port *)dev_id; | ||
| 565 | unsigned int ists = 0, lsr = 0, rxlen = 0; | ||
| 566 | |||
| 567 | mutex_lock(&s->max310x_mutex); | ||
| 568 | |||
| 569 | for (;;) { | ||
| 570 | /* Read IRQ status & RX FIFO level */ | ||
| 571 | regmap_read(s->regmap, MAX310X_IRQSTS_REG, &ists); | ||
| 572 | regmap_read(s->regmap, MAX310X_LSR_IRQSTS_REG, &lsr); | ||
| 573 | regmap_read(s->regmap, MAX310X_RXFIFOLVL_REG, &rxlen); | ||
| 574 | if (!ists && !(lsr & MAX310X_LSR_RXTO_BIT) && !rxlen) | ||
| 575 | break; | ||
| 576 | |||
| 577 | dev_dbg(s->port.dev, "IRQ status: 0x%02x\n", ists); | ||
| 578 | |||
| 579 | if (rxlen) | ||
| 580 | max310x_handle_rx(s, rxlen); | ||
| 581 | if (ists & MAX310X_IRQ_TX) | ||
| 582 | max310x_handle_tx(s); | ||
| 583 | if (ists & MAX310X_IRQ_CTS_BIT) | ||
| 584 | uart_handle_cts_change(&s->port, | ||
| 585 | !!(lsr & MAX310X_LSR_CTS_BIT)); | ||
| 586 | } | ||
| 587 | |||
| 588 | mutex_unlock(&s->max310x_mutex); | ||
| 589 | |||
| 590 | return IRQ_HANDLED; | ||
| 591 | } | ||
| 592 | |||
| 593 | static void max310x_wq_proc(struct work_struct *ws) | ||
| 594 | { | ||
| 595 | struct max310x_port *s = container_of(ws, struct max310x_port, tx_work); | ||
| 596 | |||
| 597 | mutex_lock(&s->max310x_mutex); | ||
| 598 | max310x_handle_tx(s); | ||
| 599 | mutex_unlock(&s->max310x_mutex); | ||
| 600 | } | ||
| 601 | |||
| 602 | static void max310x_start_tx(struct uart_port *port) | ||
| 603 | { | ||
| 604 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
| 605 | |||
| 606 | queue_work(s->wq, &s->tx_work); | ||
| 607 | } | ||
| 608 | |||
| 609 | static void max310x_stop_tx(struct uart_port *port) | ||
| 610 | { | ||
| 611 | /* Do nothing */ | ||
| 612 | } | ||
| 613 | |||
| 614 | static void max310x_stop_rx(struct uart_port *port) | ||
| 615 | { | ||
| 616 | /* Do nothing */ | ||
| 617 | } | ||
| 618 | |||
| 619 | static unsigned int max310x_tx_empty(struct uart_port *port) | ||
| 620 | { | ||
| 621 | unsigned int val = 0; | ||
| 622 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
| 623 | |||
| 624 | mutex_lock(&s->max310x_mutex); | ||
| 625 | regmap_read(s->regmap, MAX310X_TXFIFOLVL_REG, &val); | ||
| 626 | mutex_unlock(&s->max310x_mutex); | ||
| 627 | |||
| 628 | return val ? 0 : TIOCSER_TEMT; | ||
| 629 | } | ||
| 630 | |||
| 631 | static void max310x_enable_ms(struct uart_port *port) | ||
| 632 | { | ||
| 633 | /* Modem status not supported */ | ||
| 634 | } | ||
| 635 | |||
| 636 | static unsigned int max310x_get_mctrl(struct uart_port *port) | ||
| 637 | { | ||
| 638 | /* DCD and DSR are not wired and CTS/RTS is handled automatically | ||
| 639 | * so just indicate DSR and CAR asserted | ||
| 640 | */ | ||
| 641 | return TIOCM_DSR | TIOCM_CAR; | ||
| 642 | } | ||
| 643 | |||
| 644 | static void max310x_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
| 645 | { | ||
| 646 | /* DCD and DSR are not wired and CTS/RTS is hadnled automatically | ||
| 647 | * so do nothing | ||
| 648 | */ | ||
| 649 | } | ||
| 650 | |||
| 651 | static void max310x_break_ctl(struct uart_port *port, int break_state) | ||
| 652 | { | ||
| 653 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
| 654 | |||
| 655 | mutex_lock(&s->max310x_mutex); | ||
| 656 | regmap_update_bits(s->regmap, MAX310X_LCR_REG, | ||
| 657 | MAX310X_LCR_TXBREAK_BIT, | ||
| 658 | break_state ? MAX310X_LCR_TXBREAK_BIT : 0); | ||
| 659 | mutex_unlock(&s->max310x_mutex); | ||
| 660 | } | ||
| 661 | |||
| 662 | static void max310x_set_termios(struct uart_port *port, | ||
| 663 | struct ktermios *termios, | ||
| 664 | struct ktermios *old) | ||
| 665 | { | ||
| 666 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
| 667 | unsigned int lcr, flow = 0; | ||
| 668 | int baud; | ||
| 669 | |||
| 670 | mutex_lock(&s->max310x_mutex); | ||
| 671 | |||
| 672 | /* Mask termios capabilities we don't support */ | ||
| 673 | termios->c_cflag &= ~CMSPAR; | ||
| 674 | termios->c_iflag &= ~IXANY; | ||
| 675 | |||
| 676 | /* Word size */ | ||
| 677 | switch (termios->c_cflag & CSIZE) { | ||
| 678 | case CS5: | ||
| 679 | lcr = MAX310X_LCR_WORD_LEN_5; | ||
| 680 | break; | ||
| 681 | case CS6: | ||
| 682 | lcr = MAX310X_LCR_WORD_LEN_6; | ||
| 683 | break; | ||
| 684 | case CS7: | ||
| 685 | lcr = MAX310X_LCR_WORD_LEN_7; | ||
| 686 | break; | ||
| 687 | case CS8: | ||
| 688 | default: | ||
| 689 | lcr = MAX310X_LCR_WORD_LEN_8; | ||
| 690 | break; | ||
| 691 | } | ||
| 692 | |||
| 693 | /* Parity */ | ||
| 694 | if (termios->c_cflag & PARENB) { | ||
| 695 | lcr |= MAX310X_LCR_PARITY_BIT; | ||
| 696 | if (!(termios->c_cflag & PARODD)) | ||
| 697 | lcr |= MAX310X_LCR_EVENPARITY_BIT; | ||
| 698 | } | ||
| 699 | |||
| 700 | /* Stop bits */ | ||
| 701 | if (termios->c_cflag & CSTOPB) | ||
| 702 | lcr |= MAX310X_LCR_STOPLEN_BIT; /* 2 stops */ | ||
| 703 | |||
| 704 | /* Update LCR register */ | ||
| 705 | regmap_write(s->regmap, MAX310X_LCR_REG, lcr); | ||
| 706 | |||
| 707 | /* Set read status mask */ | ||
| 708 | port->read_status_mask = MAX310X_LSR_RXOVR_BIT; | ||
| 709 | if (termios->c_iflag & INPCK) | ||
| 710 | port->read_status_mask |= MAX310X_LSR_RXPAR_BIT | | ||
| 711 | MAX310X_LSR_FRERR_BIT; | ||
| 712 | if (termios->c_iflag & (BRKINT | PARMRK)) | ||
| 713 | port->read_status_mask |= MAX310X_LSR_RXBRK_BIT; | ||
| 714 | |||
| 715 | /* Set status ignore mask */ | ||
| 716 | port->ignore_status_mask = 0; | ||
| 717 | if (termios->c_iflag & IGNBRK) | ||
| 718 | port->ignore_status_mask |= MAX310X_LSR_RXBRK_BIT; | ||
| 719 | if (!(termios->c_cflag & CREAD)) | ||
| 720 | port->ignore_status_mask |= MAX310X_LSR_RXPAR_BIT | | ||
| 721 | MAX310X_LSR_RXOVR_BIT | | ||
| 722 | MAX310X_LSR_FRERR_BIT | | ||
| 723 | MAX310X_LSR_RXBRK_BIT; | ||
| 724 | |||
| 725 | /* Configure flow control */ | ||
| 726 | regmap_write(s->regmap, MAX310X_XON1_REG, termios->c_cc[VSTART]); | ||
| 727 | regmap_write(s->regmap, MAX310X_XOFF1_REG, termios->c_cc[VSTOP]); | ||
| 728 | if (termios->c_cflag & CRTSCTS) | ||
| 729 | flow |= MAX310X_FLOWCTRL_AUTOCTS_BIT | | ||
| 730 | MAX310X_FLOWCTRL_AUTORTS_BIT; | ||
| 731 | if (termios->c_iflag & IXON) | ||
| 732 | flow |= MAX310X_FLOWCTRL_SWFLOW3_BIT | | ||
| 733 | MAX310X_FLOWCTRL_SWFLOWEN_BIT; | ||
| 734 | if (termios->c_iflag & IXOFF) | ||
| 735 | flow |= MAX310X_FLOWCTRL_SWFLOW1_BIT | | ||
| 736 | MAX310X_FLOWCTRL_SWFLOWEN_BIT; | ||
| 737 | regmap_write(s->regmap, MAX310X_FLOWCTRL_REG, flow); | ||
| 738 | |||
| 739 | /* Get baud rate generator configuration */ | ||
| 740 | baud = uart_get_baud_rate(port, termios, old, | ||
| 741 | port->uartclk / 16 / 0xffff, | ||
| 742 | port->uartclk / 4); | ||
| 743 | |||
| 744 | /* Setup baudrate generator */ | ||
| 745 | max310x_set_baud(s, baud); | ||
| 746 | |||
| 747 | /* Update timeout according to new baud rate */ | ||
| 748 | uart_update_timeout(port, termios->c_cflag, baud); | ||
| 749 | |||
| 750 | mutex_unlock(&s->max310x_mutex); | ||
| 751 | } | ||
| 752 | |||
| 753 | static int max310x_startup(struct uart_port *port) | ||
| 754 | { | ||
| 755 | unsigned int val, line = port->line; | ||
| 756 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
| 757 | |||
| 758 | if (s->pdata->suspend) | ||
| 759 | s->pdata->suspend(0); | ||
| 760 | |||
| 761 | mutex_lock(&s->max310x_mutex); | ||
| 762 | |||
| 763 | /* Configure baud rate, 9600 as default */ | ||
| 764 | max310x_set_baud(s, 9600); | ||
| 765 | |||
| 766 | /* Configure LCR register, 8N1 mode by default */ | ||
| 767 | val = MAX310X_LCR_WORD_LEN_8; | ||
| 768 | regmap_write(s->regmap, MAX310X_LCR_REG, val); | ||
| 769 | |||
| 770 | /* Configure MODE1 register */ | ||
| 771 | regmap_update_bits(s->regmap, MAX310X_MODE1_REG, | ||
| 772 | MAX310X_MODE1_TRNSCVCTRL_BIT, | ||
| 773 | (s->pdata->uart_flags[line] & MAX310X_AUTO_DIR_CTRL) | ||
| 774 | ? MAX310X_MODE1_TRNSCVCTRL_BIT : 0); | ||
| 775 | |||
| 776 | /* Configure MODE2 register */ | ||
| 777 | val = MAX310X_MODE2_RXEMPTINV_BIT; | ||
| 778 | if (s->pdata->uart_flags[line] & MAX310X_LOOPBACK) | ||
| 779 | val |= MAX310X_MODE2_LOOPBACK_BIT; | ||
| 780 | if (s->pdata->uart_flags[line] & MAX310X_ECHO_SUPRESS) | ||
| 781 | val |= MAX310X_MODE2_ECHOSUPR_BIT; | ||
| 782 | |||
| 783 | /* Reset FIFOs */ | ||
| 784 | val |= MAX310X_MODE2_FIFORST_BIT; | ||
| 785 | regmap_write(s->regmap, MAX310X_MODE2_REG, val); | ||
| 786 | |||
| 787 | /* Configure FIFO trigger level register */ | ||
| 788 | /* RX FIFO trigger for 16 words, TX FIFO trigger for 64 words */ | ||
| 789 | val = MAX310X_FIFOTRIGLVL_RX(16) | MAX310X_FIFOTRIGLVL_TX(64); | ||
| 790 | regmap_write(s->regmap, MAX310X_FIFOTRIGLVL_REG, val); | ||
| 791 | |||
| 792 | /* Configure flow control levels */ | ||
| 793 | /* Flow control halt level 96, resume level 48 */ | ||
| 794 | val = MAX310X_FLOWLVL_RES(48) | MAX310X_FLOWLVL_HALT(96); | ||
| 795 | regmap_write(s->regmap, MAX310X_FLOWLVL_REG, val); | ||
| 796 | |||
| 797 | /* Clear timeout register */ | ||
| 798 | regmap_write(s->regmap, MAX310X_RXTO_REG, 0); | ||
| 799 | |||
| 800 | /* Configure LSR interrupt enable register */ | ||
| 801 | /* Enable RX timeout interrupt */ | ||
| 802 | val = MAX310X_LSR_RXTO_BIT; | ||
| 803 | regmap_write(s->regmap, MAX310X_LSR_IRQEN_REG, val); | ||
| 804 | |||
| 805 | /* Clear FIFO reset */ | ||
| 806 | regmap_update_bits(s->regmap, MAX310X_MODE2_REG, | ||
| 807 | MAX310X_MODE2_FIFORST_BIT, 0); | ||
| 808 | |||
| 809 | /* Clear IRQ status register by reading it */ | ||
| 810 | regmap_read(s->regmap, MAX310X_IRQSTS_REG, &val); | ||
| 811 | |||
| 812 | /* Configure interrupt enable register */ | ||
| 813 | /* Enable CTS change interrupt */ | ||
| 814 | val = MAX310X_IRQ_CTS_BIT; | ||
| 815 | /* Enable RX, TX interrupts */ | ||
| 816 | val |= MAX310X_IRQ_RX | MAX310X_IRQ_TX; | ||
| 817 | regmap_write(s->regmap, MAX310X_IRQEN_REG, val); | ||
| 818 | |||
| 819 | mutex_unlock(&s->max310x_mutex); | ||
| 820 | |||
| 821 | return 0; | ||
| 822 | } | ||
| 823 | |||
| 824 | static void max310x_shutdown(struct uart_port *port) | ||
| 825 | { | ||
| 826 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
| 827 | |||
| 828 | /* Disable all interrupts */ | ||
| 829 | mutex_lock(&s->max310x_mutex); | ||
| 830 | regmap_write(s->regmap, MAX310X_IRQEN_REG, 0); | ||
| 831 | mutex_unlock(&s->max310x_mutex); | ||
| 832 | |||
| 833 | if (s->pdata->suspend) | ||
| 834 | s->pdata->suspend(1); | ||
| 835 | } | ||
| 836 | |||
| 837 | static const char *max310x_type(struct uart_port *port) | ||
| 838 | { | ||
| 839 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
| 840 | |||
| 841 | return (port->type == PORT_MAX310X) ? s->name : NULL; | ||
| 842 | } | ||
| 843 | |||
| 844 | static int max310x_request_port(struct uart_port *port) | ||
| 845 | { | ||
| 846 | /* Do nothing */ | ||
| 847 | return 0; | ||
| 848 | } | ||
| 849 | |||
| 850 | static void max310x_release_port(struct uart_port *port) | ||
| 851 | { | ||
| 852 | /* Do nothing */ | ||
| 853 | } | ||
| 854 | |||
| 855 | static void max310x_config_port(struct uart_port *port, int flags) | ||
| 856 | { | ||
| 857 | if (flags & UART_CONFIG_TYPE) | ||
| 858 | port->type = PORT_MAX310X; | ||
| 859 | } | ||
| 860 | |||
| 861 | static int max310x_verify_port(struct uart_port *port, struct serial_struct *ser) | ||
| 862 | { | ||
| 863 | if ((ser->type == PORT_UNKNOWN) || (ser->type == PORT_MAX310X)) | ||
| 864 | return 0; | ||
| 865 | if (ser->irq == port->irq) | ||
| 866 | return 0; | ||
| 867 | |||
| 868 | return -EINVAL; | ||
| 869 | } | ||
| 870 | |||
| 871 | static struct uart_ops max310x_ops = { | ||
| 872 | .tx_empty = max310x_tx_empty, | ||
| 873 | .set_mctrl = max310x_set_mctrl, | ||
| 874 | .get_mctrl = max310x_get_mctrl, | ||
| 875 | .stop_tx = max310x_stop_tx, | ||
| 876 | .start_tx = max310x_start_tx, | ||
| 877 | .stop_rx = max310x_stop_rx, | ||
| 878 | .enable_ms = max310x_enable_ms, | ||
| 879 | .break_ctl = max310x_break_ctl, | ||
| 880 | .startup = max310x_startup, | ||
| 881 | .shutdown = max310x_shutdown, | ||
| 882 | .set_termios = max310x_set_termios, | ||
| 883 | .type = max310x_type, | ||
| 884 | .request_port = max310x_request_port, | ||
| 885 | .release_port = max310x_release_port, | ||
| 886 | .config_port = max310x_config_port, | ||
| 887 | .verify_port = max310x_verify_port, | ||
| 888 | }; | ||
| 889 | |||
| 890 | static int max310x_suspend(struct spi_device *spi, pm_message_t state) | ||
| 891 | { | ||
| 892 | int ret; | ||
| 893 | struct max310x_port *s = dev_get_drvdata(&spi->dev); | ||
| 894 | |||
| 895 | dev_dbg(&spi->dev, "Suspend\n"); | ||
| 896 | |||
| 897 | ret = uart_suspend_port(&s->uart, &s->port); | ||
| 898 | |||
| 899 | mutex_lock(&s->max310x_mutex); | ||
| 900 | |||
| 901 | /* Enable sleep mode */ | ||
| 902 | regmap_update_bits(s->regmap, MAX310X_MODE1_REG, | ||
| 903 | MAX310X_MODE1_FORCESLEEP_BIT, | ||
| 904 | MAX310X_MODE1_FORCESLEEP_BIT); | ||
| 905 | |||
| 906 | mutex_unlock(&s->max310x_mutex); | ||
| 907 | |||
| 908 | if (s->pdata->suspend) | ||
| 909 | s->pdata->suspend(1); | ||
| 910 | |||
| 911 | return ret; | ||
| 912 | } | ||
| 913 | |||
| 914 | static int max310x_resume(struct spi_device *spi) | ||
| 915 | { | ||
| 916 | struct max310x_port *s = dev_get_drvdata(&spi->dev); | ||
| 917 | |||
| 918 | dev_dbg(&spi->dev, "Resume\n"); | ||
| 919 | |||
| 920 | if (s->pdata->suspend) | ||
| 921 | s->pdata->suspend(0); | ||
| 922 | |||
| 923 | mutex_lock(&s->max310x_mutex); | ||
| 924 | |||
| 925 | /* Disable sleep mode */ | ||
| 926 | regmap_update_bits(s->regmap, MAX310X_MODE1_REG, | ||
| 927 | MAX310X_MODE1_FORCESLEEP_BIT, | ||
| 928 | 0); | ||
| 929 | |||
| 930 | max310x_wait_pll(s); | ||
| 931 | |||
| 932 | mutex_unlock(&s->max310x_mutex); | ||
| 933 | |||
| 934 | return uart_resume_port(&s->uart, &s->port); | ||
| 935 | } | ||
| 936 | |||
| 937 | #ifdef CONFIG_GPIOLIB | ||
| 938 | static int max310x_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
| 939 | { | ||
| 940 | unsigned int val = 0; | ||
| 941 | struct max310x_port *s = container_of(chip, struct max310x_port, gpio); | ||
| 942 | |||
| 943 | mutex_lock(&s->max310x_mutex); | ||
| 944 | regmap_read(s->regmap, MAX310X_GPIODATA_REG, &val); | ||
| 945 | mutex_unlock(&s->max310x_mutex); | ||
| 946 | |||
| 947 | return !!((val >> 4) & (1 << offset)); | ||
| 948 | } | ||
| 949 | |||
| 950 | static void max310x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 951 | { | ||
| 952 | struct max310x_port *s = container_of(chip, struct max310x_port, gpio); | ||
| 953 | |||
| 954 | mutex_lock(&s->max310x_mutex); | ||
| 955 | regmap_update_bits(s->regmap, MAX310X_GPIODATA_REG, 1 << offset, value ? | ||
| 956 | 1 << offset : 0); | ||
| 957 | mutex_unlock(&s->max310x_mutex); | ||
| 958 | } | ||
| 959 | |||
| 960 | static int max310x_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
| 961 | { | ||
| 962 | struct max310x_port *s = container_of(chip, struct max310x_port, gpio); | ||
| 963 | |||
| 964 | mutex_lock(&s->max310x_mutex); | ||
| 965 | |||
| 966 | regmap_update_bits(s->regmap, MAX310X_GPIOCFG_REG, 1 << offset, 0); | ||
| 967 | |||
| 968 | mutex_unlock(&s->max310x_mutex); | ||
| 969 | |||
| 970 | return 0; | ||
| 971 | } | ||
| 972 | |||
| 973 | static int max310x_gpio_direction_output(struct gpio_chip *chip, | ||
| 974 | unsigned offset, int value) | ||
| 975 | { | ||
| 976 | struct max310x_port *s = container_of(chip, struct max310x_port, gpio); | ||
| 977 | |||
| 978 | mutex_lock(&s->max310x_mutex); | ||
| 979 | |||
| 980 | regmap_update_bits(s->regmap, MAX310X_GPIOCFG_REG, 1 << offset, | ||
| 981 | 1 << offset); | ||
| 982 | regmap_update_bits(s->regmap, MAX310X_GPIODATA_REG, 1 << offset, value ? | ||
| 983 | 1 << offset : 0); | ||
| 984 | |||
| 985 | mutex_unlock(&s->max310x_mutex); | ||
| 986 | |||
| 987 | return 0; | ||
| 988 | } | ||
| 989 | #endif | ||
| 990 | |||
| 991 | /* Generic platform data */ | ||
| 992 | static struct max310x_pdata generic_plat_data = { | ||
| 993 | .driver_flags = MAX310X_EXT_CLK, | ||
| 994 | .uart_flags[0] = MAX310X_ECHO_SUPRESS, | ||
| 995 | .frequency = 26000000, | ||
| 996 | }; | ||
| 997 | |||
| 998 | static int __devinit max310x_probe(struct spi_device *spi) | ||
| 999 | { | ||
| 1000 | struct max310x_port *s; | ||
| 1001 | struct device *dev = &spi->dev; | ||
| 1002 | int chiptype = spi_get_device_id(spi)->driver_data; | ||
| 1003 | struct max310x_pdata *pdata = dev->platform_data; | ||
| 1004 | unsigned int val = 0; | ||
| 1005 | int ret; | ||
| 1006 | |||
| 1007 | /* Check for IRQ */ | ||
| 1008 | if (spi->irq <= 0) { | ||
| 1009 | dev_err(dev, "No IRQ specified\n"); | ||
| 1010 | return -ENOTSUPP; | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | /* Alloc port structure */ | ||
| 1014 | s = devm_kzalloc(dev, sizeof(struct max310x_port), GFP_KERNEL); | ||
| 1015 | if (!s) { | ||
| 1016 | dev_err(dev, "Error allocating port structure\n"); | ||
| 1017 | return -ENOMEM; | ||
| 1018 | } | ||
| 1019 | dev_set_drvdata(dev, s); | ||
| 1020 | |||
| 1021 | if (!pdata) { | ||
| 1022 | dev_warn(dev, "No platform data supplied, using defaults\n"); | ||
| 1023 | pdata = &generic_plat_data; | ||
| 1024 | } | ||
| 1025 | s->pdata = pdata; | ||
| 1026 | |||
| 1027 | /* Individual chip settings */ | ||
| 1028 | switch (chiptype) { | ||
| 1029 | case MAX310X_TYPE_MAX3107: | ||
| 1030 | s->name = "MAX3107"; | ||
| 1031 | s->nr_gpio = 4; | ||
| 1032 | s->uart.nr = 1; | ||
| 1033 | s->regcfg.max_register = 0x1f; | ||
| 1034 | break; | ||
| 1035 | case MAX310X_TYPE_MAX3108: | ||
| 1036 | s->name = "MAX3108"; | ||
| 1037 | s->nr_gpio = 4; | ||
| 1038 | s->uart.nr = 1; | ||
| 1039 | s->regcfg.max_register = 0x1e; | ||
| 1040 | break; | ||
| 1041 | default: | ||
| 1042 | dev_err(dev, "Unsupported chip type %i\n", chiptype); | ||
| 1043 | return -ENOTSUPP; | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | /* Check input frequency */ | ||
| 1047 | if ((pdata->driver_flags & MAX310X_EXT_CLK) && | ||
| 1048 | ((pdata->frequency < 500000) || (pdata->frequency > 35000000))) | ||
| 1049 | goto err_freq; | ||
| 1050 | /* Check frequency for quartz */ | ||
| 1051 | if (!(pdata->driver_flags & MAX310X_EXT_CLK) && | ||
| 1052 | ((pdata->frequency < 1000000) || (pdata->frequency > 4000000))) | ||
| 1053 | goto err_freq; | ||
| 1054 | |||
| 1055 | mutex_init(&s->max310x_mutex); | ||
| 1056 | |||
| 1057 | /* Setup SPI bus */ | ||
| 1058 | spi->mode = SPI_MODE_0; | ||
| 1059 | spi->bits_per_word = 8; | ||
| 1060 | spi->max_speed_hz = 26000000; | ||
| 1061 | spi_setup(spi); | ||
| 1062 | |||
| 1063 | /* Setup regmap */ | ||
| 1064 | s->regcfg.reg_bits = 8; | ||
| 1065 | s->regcfg.val_bits = 8; | ||
| 1066 | s->regcfg.read_flag_mask = 0x00; | ||
| 1067 | s->regcfg.write_flag_mask = 0x80; | ||
| 1068 | s->regcfg.cache_type = REGCACHE_RBTREE; | ||
| 1069 | s->regcfg.writeable_reg = max3107_8_reg_writeable; | ||
| 1070 | s->regcfg.volatile_reg = max310x_reg_volatile; | ||
| 1071 | s->regcfg.precious_reg = max310x_reg_precious; | ||
| 1072 | s->regmap = devm_regmap_init_spi(spi, &s->regcfg); | ||
| 1073 | if (IS_ERR(s->regmap)) { | ||
| 1074 | ret = PTR_ERR(s->regmap); | ||
| 1075 | dev_err(dev, "Failed to initialize register map\n"); | ||
| 1076 | goto err_out; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | /* Reset chip & check SPI function */ | ||
| 1080 | ret = regmap_write(s->regmap, MAX310X_MODE2_REG, MAX310X_MODE2_RST_BIT); | ||
| 1081 | if (ret) { | ||
| 1082 | dev_err(dev, "SPI transfer failed\n"); | ||
| 1083 | goto err_out; | ||
| 1084 | } | ||
| 1085 | /* Clear chip reset */ | ||
| 1086 | regmap_write(s->regmap, MAX310X_MODE2_REG, 0); | ||
| 1087 | |||
| 1088 | switch (chiptype) { | ||
| 1089 | case MAX310X_TYPE_MAX3107: | ||
| 1090 | /* Check REV ID to ensure we are talking to what we expect */ | ||
| 1091 | regmap_read(s->regmap, MAX3107_REVID_REG, &val); | ||
| 1092 | if (((val & MAX3107_REV_MASK) != MAX3107_REV_ID)) { | ||
| 1093 | dev_err(dev, "%s ID 0x%02x does not match\n", | ||
| 1094 | s->name, val); | ||
| 1095 | ret = -ENODEV; | ||
| 1096 | goto err_out; | ||
| 1097 | } | ||
| 1098 | break; | ||
| 1099 | case MAX310X_TYPE_MAX3108: | ||
| 1100 | /* MAX3108 have not REV ID register, we just check default value | ||
| 1101 | * from clocksource register to make sure everything works. | ||
| 1102 | */ | ||
| 1103 | regmap_read(s->regmap, MAX310X_CLKSRC_REG, &val); | ||
| 1104 | if (val != (MAX310X_CLKSRC_EXTCLK_BIT | | ||
| 1105 | MAX310X_CLKSRC_PLLBYP_BIT)) { | ||
| 1106 | dev_err(dev, "%s not present\n", s->name); | ||
| 1107 | ret = -ENODEV; | ||
| 1108 | goto err_out; | ||
| 1109 | } | ||
| 1110 | break; | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | /* Board specific configure */ | ||
| 1114 | if (pdata->init) | ||
| 1115 | pdata->init(); | ||
| 1116 | if (pdata->suspend) | ||
| 1117 | pdata->suspend(0); | ||
| 1118 | |||
| 1119 | /* Calculate referecne clock */ | ||
| 1120 | s->uartclk = max310x_set_ref_clk(s); | ||
| 1121 | |||
| 1122 | /* Disable all interrupts */ | ||
| 1123 | regmap_write(s->regmap, MAX310X_IRQEN_REG, 0); | ||
| 1124 | |||
| 1125 | /* Setup MODE1 register */ | ||
| 1126 | val = MAX310X_MODE1_IRQSEL_BIT; /* Enable IRQ pin */ | ||
| 1127 | if (pdata->driver_flags & MAX310X_AUTOSLEEP) | ||
| 1128 | val = MAX310X_MODE1_AUTOSLEEP_BIT; | ||
| 1129 | regmap_write(s->regmap, MAX310X_MODE1_REG, val); | ||
| 1130 | |||
| 1131 | /* Setup interrupt */ | ||
| 1132 | ret = devm_request_threaded_irq(dev, spi->irq, NULL, max310x_ist, | ||
| 1133 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
| 1134 | dev_name(dev), s); | ||
| 1135 | if (ret) { | ||
| 1136 | dev_err(dev, "Unable to reguest IRQ %i\n", spi->irq); | ||
| 1137 | goto err_out; | ||
| 1138 | } | ||
| 1139 | |||
| 1140 | /* Register UART driver */ | ||
| 1141 | s->uart.owner = THIS_MODULE; | ||
| 1142 | s->uart.driver_name = dev_name(dev); | ||
| 1143 | s->uart.dev_name = "ttyMAX"; | ||
| 1144 | s->uart.major = MAX310X_MAJOR; | ||
| 1145 | s->uart.minor = MAX310X_MINOR; | ||
| 1146 | ret = uart_register_driver(&s->uart); | ||
| 1147 | if (ret) { | ||
| 1148 | dev_err(dev, "Registering UART driver failed\n"); | ||
| 1149 | goto err_out; | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | /* Initialize workqueue for start TX */ | ||
| 1153 | s->wq = create_freezable_workqueue(dev_name(dev)); | ||
| 1154 | INIT_WORK(&s->tx_work, max310x_wq_proc); | ||
| 1155 | |||
| 1156 | /* Initialize UART port data */ | ||
| 1157 | s->port.line = 0; | ||
| 1158 | s->port.dev = dev; | ||
| 1159 | s->port.irq = spi->irq; | ||
| 1160 | s->port.type = PORT_MAX310X; | ||
| 1161 | s->port.fifosize = MAX310X_FIFO_SIZE; | ||
| 1162 | s->port.flags = UPF_SKIP_TEST | UPF_FIXED_TYPE; | ||
| 1163 | s->port.iotype = UPIO_PORT; | ||
| 1164 | s->port.membase = (void __iomem *)0xffffffff; /* Bogus value */ | ||
| 1165 | s->port.uartclk = s->uartclk; | ||
| 1166 | s->port.ops = &max310x_ops; | ||
| 1167 | uart_add_one_port(&s->uart, &s->port); | ||
| 1168 | |||
| 1169 | #ifdef CONFIG_GPIOLIB | ||
| 1170 | /* Setup GPIO cotroller */ | ||
| 1171 | if (pdata->gpio_base) { | ||
| 1172 | s->gpio.owner = THIS_MODULE; | ||
| 1173 | s->gpio.dev = dev; | ||
| 1174 | s->gpio.label = dev_name(dev); | ||
| 1175 | s->gpio.direction_input = max310x_gpio_direction_input; | ||
| 1176 | s->gpio.get = max310x_gpio_get; | ||
| 1177 | s->gpio.direction_output= max310x_gpio_direction_output; | ||
| 1178 | s->gpio.set = max310x_gpio_set; | ||
| 1179 | s->gpio.base = pdata->gpio_base; | ||
| 1180 | s->gpio.ngpio = s->nr_gpio; | ||
| 1181 | if (gpiochip_add(&s->gpio)) { | ||
| 1182 | /* Indicate that we should not call gpiochip_remove */ | ||
| 1183 | s->gpio.base = 0; | ||
| 1184 | } | ||
| 1185 | } else | ||
| 1186 | dev_info(dev, "GPIO support not enabled\n"); | ||
| 1187 | #endif | ||
| 1188 | |||
| 1189 | /* Go to suspend mode */ | ||
| 1190 | if (pdata->suspend) | ||
| 1191 | pdata->suspend(1); | ||
| 1192 | |||
| 1193 | return 0; | ||
| 1194 | |||
| 1195 | err_freq: | ||
| 1196 | dev_err(dev, "Frequency parameter incorrect\n"); | ||
| 1197 | ret = -EINVAL; | ||
| 1198 | |||
| 1199 | err_out: | ||
| 1200 | dev_set_drvdata(dev, NULL); | ||
| 1201 | |||
| 1202 | return ret; | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | static int __devexit max310x_remove(struct spi_device *spi) | ||
| 1206 | { | ||
| 1207 | struct device *dev = &spi->dev; | ||
| 1208 | struct max310x_port *s = dev_get_drvdata(dev); | ||
| 1209 | int ret = 0; | ||
| 1210 | |||
| 1211 | dev_dbg(dev, "Removing port\n"); | ||
| 1212 | |||
| 1213 | devm_free_irq(dev, s->port.irq, s); | ||
| 1214 | |||
| 1215 | destroy_workqueue(s->wq); | ||
| 1216 | |||
| 1217 | uart_remove_one_port(&s->uart, &s->port); | ||
| 1218 | |||
| 1219 | uart_unregister_driver(&s->uart); | ||
| 1220 | |||
| 1221 | #ifdef CONFIG_GPIOLIB | ||
| 1222 | if (s->pdata->gpio_base) { | ||
| 1223 | ret = gpiochip_remove(&s->gpio); | ||
| 1224 | if (ret) | ||
| 1225 | dev_err(dev, "Failed to remove gpio chip: %d\n", ret); | ||
| 1226 | } | ||
| 1227 | #endif | ||
| 1228 | |||
| 1229 | dev_set_drvdata(dev, NULL); | ||
| 1230 | |||
| 1231 | if (s->pdata->suspend) | ||
| 1232 | s->pdata->suspend(1); | ||
| 1233 | if (s->pdata->exit) | ||
| 1234 | s->pdata->exit(); | ||
| 1235 | |||
| 1236 | return ret; | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | static const struct spi_device_id max310x_id_table[] = { | ||
| 1240 | { "max3107", MAX310X_TYPE_MAX3107 }, | ||
| 1241 | { "max3108", MAX310X_TYPE_MAX3108 }, | ||
| 1242 | }; | ||
| 1243 | MODULE_DEVICE_TABLE(spi, max310x_id_table); | ||
| 1244 | |||
| 1245 | static struct spi_driver max310x_driver = { | ||
| 1246 | .driver = { | ||
| 1247 | .name = "max310x", | ||
| 1248 | .owner = THIS_MODULE, | ||
| 1249 | }, | ||
| 1250 | .probe = max310x_probe, | ||
| 1251 | .remove = __devexit_p(max310x_remove), | ||
| 1252 | .suspend = max310x_suspend, | ||
| 1253 | .resume = max310x_resume, | ||
| 1254 | .id_table = max310x_id_table, | ||
| 1255 | }; | ||
| 1256 | module_spi_driver(max310x_driver); | ||
| 1257 | |||
| 1258 | MODULE_LICENSE("GPL v2"); | ||
| 1259 | MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); | ||
| 1260 | MODULE_DESCRIPTION("MAX310X serial driver"); | ||
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index bedac0d4c9ce..f19d04ed8586 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c | |||
| @@ -775,11 +775,15 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
| 775 | } | 775 | } |
| 776 | 776 | ||
| 777 | if (new->c_cflag & PARENB) { | 777 | if (new->c_cflag & PARENB) { |
| 778 | if (new->c_cflag & CMSPAR) | ||
| 779 | mr1 |= MPC52xx_PSC_MODE_PARFORCE; | ||
| 780 | |||
| 781 | /* With CMSPAR, PARODD also means high parity (same as termios) */ | ||
| 778 | mr1 |= (new->c_cflag & PARODD) ? | 782 | mr1 |= (new->c_cflag & PARODD) ? |
| 779 | MPC52xx_PSC_MODE_PARODD : MPC52xx_PSC_MODE_PAREVEN; | 783 | MPC52xx_PSC_MODE_PARODD : MPC52xx_PSC_MODE_PAREVEN; |
| 780 | } else | 784 | } else { |
| 781 | mr1 |= MPC52xx_PSC_MODE_PARNONE; | 785 | mr1 |= MPC52xx_PSC_MODE_PARNONE; |
| 782 | 786 | } | |
| 783 | 787 | ||
| 784 | mr2 = 0; | 788 | mr2 = 0; |
| 785 | 789 | ||
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 8131e2c28015..033e0bc9ebab 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c | |||
| @@ -896,7 +896,7 @@ static int __init msm_serial_probe(struct platform_device *pdev) | |||
| 896 | return PTR_ERR(msm_port->clk); | 896 | return PTR_ERR(msm_port->clk); |
| 897 | 897 | ||
| 898 | if (msm_port->is_uartdm) | 898 | if (msm_port->is_uartdm) |
| 899 | clk_set_rate(msm_port->clk, 7372800); | 899 | clk_set_rate(msm_port->clk, 1843200); |
| 900 | 900 | ||
| 901 | port->uartclk = clk_get_rate(msm_port->clk); | 901 | port->uartclk = clk_get_rate(msm_port->clk); |
| 902 | printk(KERN_INFO "uartclk = %d\n", port->uartclk); | 902 | printk(KERN_INFO "uartclk = %d\n", port->uartclk); |
diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c index b25e6ee71443..925d1fa153db 100644 --- a/drivers/tty/serial/msm_smd_tty.c +++ b/drivers/tty/serial/msm_smd_tty.c | |||
| @@ -223,9 +223,11 @@ static int __init smd_tty_init(void) | |||
| 223 | return ret; | 223 | return ret; |
| 224 | 224 | ||
| 225 | for (i = 0; i < smd_tty_channels_len; i++) { | 225 | for (i = 0; i < smd_tty_channels_len; i++) { |
| 226 | tty_port_init(&smd_tty[smd_tty_channels[i].id].port); | 226 | struct tty_port *port = &smd_tty[smd_tty_channels[i].id].port; |
| 227 | smd_tty[smd_tty_channels[i].id].port.ops = &smd_tty_port_ops; | 227 | tty_port_init(port); |
| 228 | tty_register_device(smd_tty_driver, smd_tty_channels[i].id, 0); | 228 | port->ops = &smd_tty_port_ops; |
| 229 | tty_port_register_device(port, smd_tty_driver, | ||
| 230 | smd_tty_channels[i].id, NULL); | ||
| 229 | } | 231 | } |
| 230 | 232 | ||
| 231 | return 0; | 233 | return 0; |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 3a667eed63d6..6db3baa39a97 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
| @@ -262,7 +262,7 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) | |||
| 262 | 262 | ||
| 263 | ctrl &= ~AUART_CTRL2_RTSEN; | 263 | ctrl &= ~AUART_CTRL2_RTSEN; |
| 264 | if (mctrl & TIOCM_RTS) { | 264 | if (mctrl & TIOCM_RTS) { |
| 265 | if (u->state->port.flags & ASYNC_CTS_FLOW) | 265 | if (tty_port_cts_enabled(&u->state->port)) |
| 266 | ctrl |= AUART_CTRL2_RTSEN; | 266 | ctrl |= AUART_CTRL2_RTSEN; |
| 267 | } | 267 | } |
| 268 | 268 | ||
| @@ -457,11 +457,11 @@ static void mxs_auart_shutdown(struct uart_port *u) | |||
| 457 | 457 | ||
| 458 | writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR); | 458 | writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR); |
| 459 | 459 | ||
| 460 | writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET); | ||
| 461 | |||
| 462 | writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, | 460 | writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, |
| 463 | u->membase + AUART_INTR_CLR); | 461 | u->membase + AUART_INTR_CLR); |
| 464 | 462 | ||
| 463 | writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET); | ||
| 464 | |||
| 465 | clk_disable_unprepare(s->clk); | 465 | clk_disable_unprepare(s->clk); |
| 466 | } | 466 | } |
| 467 | 467 | ||
| @@ -781,6 +781,7 @@ out_free_irq: | |||
| 781 | auart_port[pdev->id] = NULL; | 781 | auart_port[pdev->id] = NULL; |
| 782 | free_irq(s->irq, s); | 782 | free_irq(s->irq, s); |
| 783 | out_free_clk: | 783 | out_free_clk: |
| 784 | put_device(s->dev); | ||
| 784 | clk_put(s->clk); | 785 | clk_put(s->clk); |
| 785 | out_free: | 786 | out_free: |
| 786 | kfree(s); | 787 | kfree(s); |
| @@ -796,6 +797,7 @@ static int __devexit mxs_auart_remove(struct platform_device *pdev) | |||
| 796 | 797 | ||
| 797 | auart_port[pdev->id] = NULL; | 798 | auart_port[pdev->id] = NULL; |
| 798 | 799 | ||
| 800 | put_device(s->dev); | ||
| 799 | clk_put(s->clk); | 801 | clk_put(s->clk); |
| 800 | free_irq(s->irq, s); | 802 | free_irq(s->irq, s); |
| 801 | kfree(s); | 803 | kfree(s); |
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 34e71874a892..df443b908ca3 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c | |||
| @@ -105,6 +105,10 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, | |||
| 105 | port->uartclk = clk; | 105 | port->uartclk = clk; |
| 106 | port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | 106 | port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP |
| 107 | | UPF_FIXED_PORT | UPF_FIXED_TYPE; | 107 | | UPF_FIXED_PORT | UPF_FIXED_TYPE; |
| 108 | |||
| 109 | if (of_find_property(np, "no-loopback-test", NULL)) | ||
| 110 | port->flags |= UPF_SKIP_TEST; | ||
| 111 | |||
| 108 | port->dev = &ofdev->dev; | 112 | port->dev = &ofdev->dev; |
| 109 | 113 | ||
| 110 | if (type == PORT_TEGRA) | 114 | if (type == PORT_TEGRA) |
| @@ -144,8 +148,15 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev) | |||
| 144 | switch (port_type) { | 148 | switch (port_type) { |
| 145 | #ifdef CONFIG_SERIAL_8250 | 149 | #ifdef CONFIG_SERIAL_8250 |
| 146 | case PORT_8250 ... PORT_MAX_8250: | 150 | case PORT_8250 ... PORT_MAX_8250: |
| 147 | ret = serial8250_register_port(&port); | 151 | { |
| 152 | /* For now the of bindings don't support the extra | ||
| 153 | 8250 specific bits */ | ||
| 154 | struct uart_8250_port port8250; | ||
| 155 | memset(&port8250, 0, sizeof(port8250)); | ||
| 156 | port8250.port = port; | ||
| 157 | ret = serial8250_register_8250_port(&port8250); | ||
| 148 | break; | 158 | break; |
| 159 | } | ||
| 149 | #endif | 160 | #endif |
| 150 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL | 161 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL |
| 151 | case PORT_NWPSERIAL: | 162 | case PORT_NWPSERIAL: |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index d3cda0cb2df0..ccc2f35adff1 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
| @@ -32,16 +32,16 @@ | |||
| 32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 33 | #include <linux/tty.h> | 33 | #include <linux/tty.h> |
| 34 | #include <linux/tty_flip.h> | 34 | #include <linux/tty_flip.h> |
| 35 | #include <linux/platform_device.h> | ||
| 35 | #include <linux/io.h> | 36 | #include <linux/io.h> |
| 36 | #include <linux/dma-mapping.h> | ||
| 37 | #include <linux/clk.h> | 37 | #include <linux/clk.h> |
| 38 | #include <linux/serial_core.h> | 38 | #include <linux/serial_core.h> |
| 39 | #include <linux/irq.h> | 39 | #include <linux/irq.h> |
| 40 | #include <linux/pm_runtime.h> | 40 | #include <linux/pm_runtime.h> |
| 41 | #include <linux/of.h> | 41 | #include <linux/of.h> |
| 42 | #include <linux/gpio.h> | ||
| 43 | #include <linux/pinctrl/consumer.h> | ||
| 42 | 44 | ||
| 43 | #include <plat/dma.h> | ||
| 44 | #include <plat/dmtimer.h> | ||
| 45 | #include <plat/omap-serial.h> | 45 | #include <plat/omap-serial.h> |
| 46 | 46 | ||
| 47 | #define UART_BUILD_REVISION(x, y) (((x) << 8) | (y)) | 47 | #define UART_BUILD_REVISION(x, y) (((x) << 8) | (y)) |
| @@ -57,8 +57,8 @@ | |||
| 57 | #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) | 57 | #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) |
| 58 | 58 | ||
| 59 | /* FCR register bitmasks */ | 59 | /* FCR register bitmasks */ |
| 60 | #define OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT 6 | ||
| 61 | #define OMAP_UART_FCR_RX_FIFO_TRIG_MASK (0x3 << 6) | 60 | #define OMAP_UART_FCR_RX_FIFO_TRIG_MASK (0x3 << 6) |
| 61 | #define OMAP_UART_FCR_TX_FIFO_TRIG_MASK (0x3 << 4) | ||
| 62 | 62 | ||
| 63 | /* MVR register bitmasks */ | 63 | /* MVR register bitmasks */ |
| 64 | #define OMAP_UART_MVR_SCHEME_SHIFT 30 | 64 | #define OMAP_UART_MVR_SCHEME_SHIFT 30 |
| @@ -71,12 +71,52 @@ | |||
| 71 | #define OMAP_UART_MVR_MAJ_SHIFT 8 | 71 | #define OMAP_UART_MVR_MAJ_SHIFT 8 |
| 72 | #define OMAP_UART_MVR_MIN_MASK 0x3f | 72 | #define OMAP_UART_MVR_MIN_MASK 0x3f |
| 73 | 73 | ||
| 74 | struct uart_omap_port { | ||
| 75 | struct uart_port port; | ||
| 76 | struct uart_omap_dma uart_dma; | ||
| 77 | struct device *dev; | ||
| 78 | |||
| 79 | unsigned char ier; | ||
| 80 | unsigned char lcr; | ||
| 81 | unsigned char mcr; | ||
| 82 | unsigned char fcr; | ||
| 83 | unsigned char efr; | ||
| 84 | unsigned char dll; | ||
| 85 | unsigned char dlh; | ||
| 86 | unsigned char mdr1; | ||
| 87 | unsigned char scr; | ||
| 88 | |||
| 89 | int use_dma; | ||
| 90 | /* | ||
| 91 | * Some bits in registers are cleared on a read, so they must | ||
| 92 | * be saved whenever the register is read but the bits will not | ||
| 93 | * be immediately processed. | ||
| 94 | */ | ||
| 95 | unsigned int lsr_break_flag; | ||
| 96 | unsigned char msr_saved_flags; | ||
| 97 | char name[20]; | ||
| 98 | unsigned long port_activity; | ||
| 99 | u32 context_loss_cnt; | ||
| 100 | u32 errata; | ||
| 101 | u8 wakeups_enabled; | ||
| 102 | unsigned int irq_pending:1; | ||
| 103 | |||
| 104 | int DTR_gpio; | ||
| 105 | int DTR_inverted; | ||
| 106 | int DTR_active; | ||
| 107 | |||
| 108 | struct pm_qos_request pm_qos_request; | ||
| 109 | u32 latency; | ||
| 110 | u32 calc_latency; | ||
| 111 | struct work_struct qos_work; | ||
| 112 | struct pinctrl *pins; | ||
| 113 | }; | ||
| 114 | |||
| 115 | #define to_uart_omap_port(p) ((container_of((p), struct uart_omap_port, port))) | ||
| 116 | |||
| 74 | static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; | 117 | static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; |
| 75 | 118 | ||
| 76 | /* Forward declaration of functions */ | 119 | /* Forward declaration of functions */ |
| 77 | static void uart_tx_dma_callback(int lch, u16 ch_status, void *data); | ||
| 78 | static void serial_omap_rxdma_poll(unsigned long uart_no); | ||
| 79 | static int serial_omap_start_rxdma(struct uart_omap_port *up); | ||
| 80 | static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1); | 120 | static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1); |
| 81 | 121 | ||
| 82 | static struct workqueue_struct *serial_omap_uart_wq; | 122 | static struct workqueue_struct *serial_omap_uart_wq; |
| @@ -101,6 +141,46 @@ static inline void serial_omap_clear_fifos(struct uart_omap_port *up) | |||
| 101 | serial_out(up, UART_FCR, 0); | 141 | serial_out(up, UART_FCR, 0); |
| 102 | } | 142 | } |
| 103 | 143 | ||
| 144 | static int serial_omap_get_context_loss_count(struct uart_omap_port *up) | ||
| 145 | { | ||
| 146 | struct omap_uart_port_info *pdata = up->dev->platform_data; | ||
| 147 | |||
| 148 | if (!pdata || !pdata->get_context_loss_count) | ||
| 149 | return 0; | ||
| 150 | |||
| 151 | return pdata->get_context_loss_count(up->dev); | ||
| 152 | } | ||
| 153 | |||
| 154 | static void serial_omap_set_forceidle(struct uart_omap_port *up) | ||
| 155 | { | ||
| 156 | struct omap_uart_port_info *pdata = up->dev->platform_data; | ||
| 157 | |||
| 158 | if (!pdata || !pdata->set_forceidle) | ||
| 159 | return; | ||
| 160 | |||
| 161 | pdata->set_forceidle(up->dev); | ||
| 162 | } | ||
| 163 | |||
| 164 | static void serial_omap_set_noidle(struct uart_omap_port *up) | ||
| 165 | { | ||
| 166 | struct omap_uart_port_info *pdata = up->dev->platform_data; | ||
| 167 | |||
| 168 | if (!pdata || !pdata->set_noidle) | ||
| 169 | return; | ||
| 170 | |||
| 171 | pdata->set_noidle(up->dev); | ||
| 172 | } | ||
| 173 | |||
| 174 | static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) | ||
| 175 | { | ||
| 176 | struct omap_uart_port_info *pdata = up->dev->platform_data; | ||
| 177 | |||
| 178 | if (!pdata || !pdata->enable_wakeup) | ||
| 179 | return; | ||
| 180 | |||
| 181 | pdata->enable_wakeup(up->dev, enable); | ||
| 182 | } | ||
| 183 | |||
| 104 | /* | 184 | /* |
| 105 | * serial_omap_get_divisor - calculate divisor value | 185 | * serial_omap_get_divisor - calculate divisor value |
| 106 | * @port: uart port info | 186 | * @port: uart port info |
| @@ -126,151 +206,55 @@ serial_omap_get_divisor(struct uart_port *port, unsigned int baud) | |||
| 126 | return port->uartclk/(baud * divisor); | 206 | return port->uartclk/(baud * divisor); |
| 127 | } | 207 | } |
| 128 | 208 | ||
| 129 | static void serial_omap_stop_rxdma(struct uart_omap_port *up) | ||
| 130 | { | ||
| 131 | if (up->uart_dma.rx_dma_used) { | ||
| 132 | del_timer(&up->uart_dma.rx_timer); | ||
| 133 | omap_stop_dma(up->uart_dma.rx_dma_channel); | ||
| 134 | omap_free_dma(up->uart_dma.rx_dma_channel); | ||
| 135 | up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; | ||
| 136 | up->uart_dma.rx_dma_used = false; | ||
| 137 | pm_runtime_mark_last_busy(&up->pdev->dev); | ||
| 138 | pm_runtime_put_autosuspend(&up->pdev->dev); | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | static void serial_omap_enable_ms(struct uart_port *port) | 209 | static void serial_omap_enable_ms(struct uart_port *port) |
| 143 | { | 210 | { |
| 144 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 211 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 145 | 212 | ||
| 146 | dev_dbg(up->port.dev, "serial_omap_enable_ms+%d\n", up->port.line); | 213 | dev_dbg(up->port.dev, "serial_omap_enable_ms+%d\n", up->port.line); |
| 147 | 214 | ||
| 148 | pm_runtime_get_sync(&up->pdev->dev); | 215 | pm_runtime_get_sync(up->dev); |
| 149 | up->ier |= UART_IER_MSI; | 216 | up->ier |= UART_IER_MSI; |
| 150 | serial_out(up, UART_IER, up->ier); | 217 | serial_out(up, UART_IER, up->ier); |
| 151 | pm_runtime_put(&up->pdev->dev); | 218 | pm_runtime_mark_last_busy(up->dev); |
| 219 | pm_runtime_put_autosuspend(up->dev); | ||
| 152 | } | 220 | } |
| 153 | 221 | ||
| 154 | static void serial_omap_stop_tx(struct uart_port *port) | 222 | static void serial_omap_stop_tx(struct uart_port *port) |
| 155 | { | 223 | { |
| 156 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 224 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 157 | struct omap_uart_port_info *pdata = up->pdev->dev.platform_data; | ||
| 158 | |||
| 159 | if (up->use_dma && | ||
| 160 | up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE) { | ||
| 161 | /* | ||
| 162 | * Check if dma is still active. If yes do nothing, | ||
| 163 | * return. Else stop dma | ||
| 164 | */ | ||
| 165 | if (omap_get_dma_active_status(up->uart_dma.tx_dma_channel)) | ||
| 166 | return; | ||
| 167 | omap_stop_dma(up->uart_dma.tx_dma_channel); | ||
| 168 | omap_free_dma(up->uart_dma.tx_dma_channel); | ||
| 169 | up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; | ||
| 170 | pm_runtime_mark_last_busy(&up->pdev->dev); | ||
| 171 | pm_runtime_put_autosuspend(&up->pdev->dev); | ||
| 172 | } | ||
| 173 | 225 | ||
| 174 | pm_runtime_get_sync(&up->pdev->dev); | 226 | pm_runtime_get_sync(up->dev); |
| 175 | if (up->ier & UART_IER_THRI) { | 227 | if (up->ier & UART_IER_THRI) { |
| 176 | up->ier &= ~UART_IER_THRI; | 228 | up->ier &= ~UART_IER_THRI; |
| 177 | serial_out(up, UART_IER, up->ier); | 229 | serial_out(up, UART_IER, up->ier); |
| 178 | } | 230 | } |
| 179 | 231 | ||
| 180 | if (!up->use_dma && pdata && pdata->set_forceidle) | 232 | serial_omap_set_forceidle(up); |
| 181 | pdata->set_forceidle(up->pdev); | ||
| 182 | 233 | ||
| 183 | pm_runtime_mark_last_busy(&up->pdev->dev); | 234 | pm_runtime_mark_last_busy(up->dev); |
| 184 | pm_runtime_put_autosuspend(&up->pdev->dev); | 235 | pm_runtime_put_autosuspend(up->dev); |
| 185 | } | 236 | } |
| 186 | 237 | ||
| 187 | static void serial_omap_stop_rx(struct uart_port *port) | 238 | static void serial_omap_stop_rx(struct uart_port *port) |
| 188 | { | 239 | { |
| 189 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 240 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 190 | 241 | ||
| 191 | pm_runtime_get_sync(&up->pdev->dev); | 242 | pm_runtime_get_sync(up->dev); |
| 192 | if (up->use_dma) | ||
| 193 | serial_omap_stop_rxdma(up); | ||
| 194 | up->ier &= ~UART_IER_RLSI; | 243 | up->ier &= ~UART_IER_RLSI; |
| 195 | up->port.read_status_mask &= ~UART_LSR_DR; | 244 | up->port.read_status_mask &= ~UART_LSR_DR; |
| 196 | serial_out(up, UART_IER, up->ier); | 245 | serial_out(up, UART_IER, up->ier); |
| 197 | pm_runtime_mark_last_busy(&up->pdev->dev); | 246 | pm_runtime_mark_last_busy(up->dev); |
| 198 | pm_runtime_put_autosuspend(&up->pdev->dev); | 247 | pm_runtime_put_autosuspend(up->dev); |
| 199 | } | ||
| 200 | |||
| 201 | static inline void receive_chars(struct uart_omap_port *up, | ||
| 202 | unsigned int *status) | ||
| 203 | { | ||
| 204 | struct tty_struct *tty = up->port.state->port.tty; | ||
| 205 | unsigned int flag, lsr = *status; | ||
| 206 | unsigned char ch = 0; | ||
| 207 | int max_count = 256; | ||
| 208 | |||
| 209 | do { | ||
| 210 | if (likely(lsr & UART_LSR_DR)) | ||
| 211 | ch = serial_in(up, UART_RX); | ||
| 212 | flag = TTY_NORMAL; | ||
| 213 | up->port.icount.rx++; | ||
| 214 | |||
| 215 | if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { | ||
| 216 | /* | ||
| 217 | * For statistics only | ||
| 218 | */ | ||
| 219 | if (lsr & UART_LSR_BI) { | ||
| 220 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); | ||
| 221 | up->port.icount.brk++; | ||
| 222 | /* | ||
| 223 | * We do the SysRQ and SAK checking | ||
| 224 | * here because otherwise the break | ||
| 225 | * may get masked by ignore_status_mask | ||
| 226 | * or read_status_mask. | ||
| 227 | */ | ||
| 228 | if (uart_handle_break(&up->port)) | ||
| 229 | goto ignore_char; | ||
| 230 | } else if (lsr & UART_LSR_PE) { | ||
| 231 | up->port.icount.parity++; | ||
| 232 | } else if (lsr & UART_LSR_FE) { | ||
| 233 | up->port.icount.frame++; | ||
| 234 | } | ||
| 235 | |||
| 236 | if (lsr & UART_LSR_OE) | ||
| 237 | up->port.icount.overrun++; | ||
| 238 | |||
| 239 | /* | ||
| 240 | * Mask off conditions which should be ignored. | ||
| 241 | */ | ||
| 242 | lsr &= up->port.read_status_mask; | ||
| 243 | |||
| 244 | #ifdef CONFIG_SERIAL_OMAP_CONSOLE | ||
| 245 | if (up->port.line == up->port.cons->index) { | ||
| 246 | /* Recover the break flag from console xmit */ | ||
| 247 | lsr |= up->lsr_break_flag; | ||
| 248 | } | ||
| 249 | #endif | ||
| 250 | if (lsr & UART_LSR_BI) | ||
| 251 | flag = TTY_BREAK; | ||
| 252 | else if (lsr & UART_LSR_PE) | ||
| 253 | flag = TTY_PARITY; | ||
| 254 | else if (lsr & UART_LSR_FE) | ||
| 255 | flag = TTY_FRAME; | ||
| 256 | } | ||
| 257 | |||
| 258 | if (uart_handle_sysrq_char(&up->port, ch)) | ||
| 259 | goto ignore_char; | ||
| 260 | uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); | ||
| 261 | ignore_char: | ||
| 262 | lsr = serial_in(up, UART_LSR); | ||
| 263 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); | ||
| 264 | spin_unlock(&up->port.lock); | ||
| 265 | tty_flip_buffer_push(tty); | ||
| 266 | spin_lock(&up->port.lock); | ||
| 267 | } | 248 | } |
| 268 | 249 | ||
| 269 | static void transmit_chars(struct uart_omap_port *up) | 250 | static void transmit_chars(struct uart_omap_port *up, unsigned int lsr) |
| 270 | { | 251 | { |
| 271 | struct circ_buf *xmit = &up->port.state->xmit; | 252 | struct circ_buf *xmit = &up->port.state->xmit; |
| 272 | int count; | 253 | int count; |
| 273 | 254 | ||
| 255 | if (!(lsr & UART_LSR_THRE)) | ||
| 256 | return; | ||
| 257 | |||
| 274 | if (up->port.x_char) { | 258 | if (up->port.x_char) { |
| 275 | serial_out(up, UART_TX, up->port.x_char); | 259 | serial_out(up, UART_TX, up->port.x_char); |
| 276 | up->port.icount.tx++; | 260 | up->port.icount.tx++; |
| @@ -290,8 +274,11 @@ static void transmit_chars(struct uart_omap_port *up) | |||
| 290 | break; | 274 | break; |
| 291 | } while (--count > 0); | 275 | } while (--count > 0); |
| 292 | 276 | ||
| 293 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 277 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) { |
| 278 | spin_unlock(&up->port.lock); | ||
| 294 | uart_write_wakeup(&up->port); | 279 | uart_write_wakeup(&up->port); |
| 280 | spin_lock(&up->port.lock); | ||
| 281 | } | ||
| 295 | 282 | ||
| 296 | if (uart_circ_empty(xmit)) | 283 | if (uart_circ_empty(xmit)) |
| 297 | serial_omap_stop_tx(&up->port); | 284 | serial_omap_stop_tx(&up->port); |
| @@ -307,70 +294,13 @@ static inline void serial_omap_enable_ier_thri(struct uart_omap_port *up) | |||
| 307 | 294 | ||
| 308 | static void serial_omap_start_tx(struct uart_port *port) | 295 | static void serial_omap_start_tx(struct uart_port *port) |
| 309 | { | 296 | { |
| 310 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 297 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 311 | struct omap_uart_port_info *pdata = up->pdev->dev.platform_data; | ||
| 312 | struct circ_buf *xmit; | ||
| 313 | unsigned int start; | ||
| 314 | int ret = 0; | ||
| 315 | |||
| 316 | if (!up->use_dma) { | ||
| 317 | pm_runtime_get_sync(&up->pdev->dev); | ||
| 318 | serial_omap_enable_ier_thri(up); | ||
| 319 | if (pdata && pdata->set_noidle) | ||
| 320 | pdata->set_noidle(up->pdev); | ||
| 321 | pm_runtime_mark_last_busy(&up->pdev->dev); | ||
| 322 | pm_runtime_put_autosuspend(&up->pdev->dev); | ||
| 323 | return; | ||
| 324 | } | ||
| 325 | |||
| 326 | if (up->uart_dma.tx_dma_used) | ||
| 327 | return; | ||
| 328 | |||
| 329 | xmit = &up->port.state->xmit; | ||
| 330 | |||
| 331 | if (up->uart_dma.tx_dma_channel == OMAP_UART_DMA_CH_FREE) { | ||
| 332 | pm_runtime_get_sync(&up->pdev->dev); | ||
| 333 | ret = omap_request_dma(up->uart_dma.uart_dma_tx, | ||
| 334 | "UART Tx DMA", | ||
| 335 | (void *)uart_tx_dma_callback, up, | ||
| 336 | &(up->uart_dma.tx_dma_channel)); | ||
| 337 | |||
| 338 | if (ret < 0) { | ||
| 339 | serial_omap_enable_ier_thri(up); | ||
| 340 | return; | ||
| 341 | } | ||
| 342 | } | ||
| 343 | spin_lock(&(up->uart_dma.tx_lock)); | ||
| 344 | up->uart_dma.tx_dma_used = true; | ||
| 345 | spin_unlock(&(up->uart_dma.tx_lock)); | ||
| 346 | 298 | ||
| 347 | start = up->uart_dma.tx_buf_dma_phys + | 299 | pm_runtime_get_sync(up->dev); |
| 348 | (xmit->tail & (UART_XMIT_SIZE - 1)); | 300 | serial_omap_enable_ier_thri(up); |
| 349 | 301 | serial_omap_set_noidle(up); | |
| 350 | up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit); | 302 | pm_runtime_mark_last_busy(up->dev); |
| 351 | /* | 303 | pm_runtime_put_autosuspend(up->dev); |
| 352 | * It is a circular buffer. See if the buffer has wounded back. | ||
| 353 | * If yes it will have to be transferred in two separate dma | ||
| 354 | * transfers | ||
| 355 | */ | ||
| 356 | if (start + up->uart_dma.tx_buf_size >= | ||
| 357 | up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) | ||
| 358 | up->uart_dma.tx_buf_size = | ||
| 359 | (up->uart_dma.tx_buf_dma_phys + | ||
| 360 | UART_XMIT_SIZE) - start; | ||
| 361 | |||
| 362 | omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0, | ||
| 363 | OMAP_DMA_AMODE_CONSTANT, | ||
| 364 | up->uart_dma.uart_base, 0, 0); | ||
| 365 | omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0, | ||
| 366 | OMAP_DMA_AMODE_POST_INC, start, 0, 0); | ||
| 367 | omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel, | ||
| 368 | OMAP_DMA_DATA_TYPE_S8, | ||
| 369 | up->uart_dma.tx_buf_size, 1, | ||
| 370 | OMAP_DMA_SYNC_ELEMENT, | ||
| 371 | up->uart_dma.uart_dma_tx, 0); | ||
| 372 | /* FIXME: Cache maintenance needed here? */ | ||
| 373 | omap_start_dma(up->uart_dma.tx_dma_channel); | ||
| 374 | } | 304 | } |
| 375 | 305 | ||
| 376 | static unsigned int check_modem_status(struct uart_omap_port *up) | 306 | static unsigned int check_modem_status(struct uart_omap_port *up) |
| @@ -401,76 +331,162 @@ static unsigned int check_modem_status(struct uart_omap_port *up) | |||
| 401 | return status; | 331 | return status; |
| 402 | } | 332 | } |
| 403 | 333 | ||
| 334 | static void serial_omap_rlsi(struct uart_omap_port *up, unsigned int lsr) | ||
| 335 | { | ||
| 336 | unsigned int flag; | ||
| 337 | unsigned char ch = 0; | ||
| 338 | |||
| 339 | if (likely(lsr & UART_LSR_DR)) | ||
| 340 | ch = serial_in(up, UART_RX); | ||
| 341 | |||
| 342 | up->port.icount.rx++; | ||
| 343 | flag = TTY_NORMAL; | ||
| 344 | |||
| 345 | if (lsr & UART_LSR_BI) { | ||
| 346 | flag = TTY_BREAK; | ||
| 347 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); | ||
| 348 | up->port.icount.brk++; | ||
| 349 | /* | ||
| 350 | * We do the SysRQ and SAK checking | ||
| 351 | * here because otherwise the break | ||
| 352 | * may get masked by ignore_status_mask | ||
| 353 | * or read_status_mask. | ||
| 354 | */ | ||
| 355 | if (uart_handle_break(&up->port)) | ||
| 356 | return; | ||
| 357 | |||
| 358 | } | ||
| 359 | |||
| 360 | if (lsr & UART_LSR_PE) { | ||
| 361 | flag = TTY_PARITY; | ||
| 362 | up->port.icount.parity++; | ||
| 363 | } | ||
| 364 | |||
| 365 | if (lsr & UART_LSR_FE) { | ||
| 366 | flag = TTY_FRAME; | ||
| 367 | up->port.icount.frame++; | ||
| 368 | } | ||
| 369 | |||
| 370 | if (lsr & UART_LSR_OE) | ||
| 371 | up->port.icount.overrun++; | ||
| 372 | |||
| 373 | #ifdef CONFIG_SERIAL_OMAP_CONSOLE | ||
| 374 | if (up->port.line == up->port.cons->index) { | ||
| 375 | /* Recover the break flag from console xmit */ | ||
| 376 | lsr |= up->lsr_break_flag; | ||
| 377 | } | ||
| 378 | #endif | ||
| 379 | uart_insert_char(&up->port, lsr, UART_LSR_OE, 0, flag); | ||
| 380 | } | ||
| 381 | |||
| 382 | static void serial_omap_rdi(struct uart_omap_port *up, unsigned int lsr) | ||
| 383 | { | ||
| 384 | unsigned char ch = 0; | ||
| 385 | unsigned int flag; | ||
| 386 | |||
| 387 | if (!(lsr & UART_LSR_DR)) | ||
| 388 | return; | ||
| 389 | |||
| 390 | ch = serial_in(up, UART_RX); | ||
| 391 | flag = TTY_NORMAL; | ||
| 392 | up->port.icount.rx++; | ||
| 393 | |||
| 394 | if (uart_handle_sysrq_char(&up->port, ch)) | ||
| 395 | return; | ||
| 396 | |||
| 397 | uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); | ||
| 398 | } | ||
| 399 | |||
| 404 | /** | 400 | /** |
| 405 | * serial_omap_irq() - This handles the interrupt from one port | 401 | * serial_omap_irq() - This handles the interrupt from one port |
| 406 | * @irq: uart port irq number | 402 | * @irq: uart port irq number |
| 407 | * @dev_id: uart port info | 403 | * @dev_id: uart port info |
| 408 | */ | 404 | */ |
| 409 | static inline irqreturn_t serial_omap_irq(int irq, void *dev_id) | 405 | static irqreturn_t serial_omap_irq(int irq, void *dev_id) |
| 410 | { | 406 | { |
| 411 | struct uart_omap_port *up = dev_id; | 407 | struct uart_omap_port *up = dev_id; |
| 408 | struct tty_struct *tty = up->port.state->port.tty; | ||
| 412 | unsigned int iir, lsr; | 409 | unsigned int iir, lsr; |
| 413 | unsigned long flags; | 410 | unsigned int type; |
| 411 | irqreturn_t ret = IRQ_NONE; | ||
| 412 | int max_count = 256; | ||
| 414 | 413 | ||
| 415 | pm_runtime_get_sync(&up->pdev->dev); | 414 | spin_lock(&up->port.lock); |
| 416 | iir = serial_in(up, UART_IIR); | 415 | pm_runtime_get_sync(up->dev); |
| 417 | if (iir & UART_IIR_NO_INT) { | ||
| 418 | pm_runtime_mark_last_busy(&up->pdev->dev); | ||
| 419 | pm_runtime_put_autosuspend(&up->pdev->dev); | ||
| 420 | return IRQ_NONE; | ||
| 421 | } | ||
| 422 | 416 | ||
| 423 | spin_lock_irqsave(&up->port.lock, flags); | 417 | do { |
| 424 | lsr = serial_in(up, UART_LSR); | 418 | iir = serial_in(up, UART_IIR); |
| 425 | if (iir & UART_IIR_RLSI) { | 419 | if (iir & UART_IIR_NO_INT) |
| 426 | if (!up->use_dma) { | 420 | break; |
| 427 | if (lsr & UART_LSR_DR) | 421 | |
| 428 | receive_chars(up, &lsr); | 422 | ret = IRQ_HANDLED; |
| 429 | } else { | 423 | lsr = serial_in(up, UART_LSR); |
| 430 | up->ier &= ~(UART_IER_RDI | UART_IER_RLSI); | 424 | |
| 431 | serial_out(up, UART_IER, up->ier); | 425 | /* extract IRQ type from IIR register */ |
| 432 | if ((serial_omap_start_rxdma(up) != 0) && | 426 | type = iir & 0x3e; |
| 433 | (lsr & UART_LSR_DR)) | 427 | |
| 434 | receive_chars(up, &lsr); | 428 | switch (type) { |
| 429 | case UART_IIR_MSI: | ||
| 430 | check_modem_status(up); | ||
| 431 | break; | ||
| 432 | case UART_IIR_THRI: | ||
| 433 | transmit_chars(up, lsr); | ||
| 434 | break; | ||
| 435 | case UART_IIR_RX_TIMEOUT: | ||
| 436 | /* FALLTHROUGH */ | ||
| 437 | case UART_IIR_RDI: | ||
| 438 | serial_omap_rdi(up, lsr); | ||
| 439 | break; | ||
| 440 | case UART_IIR_RLSI: | ||
| 441 | serial_omap_rlsi(up, lsr); | ||
| 442 | break; | ||
| 443 | case UART_IIR_CTS_RTS_DSR: | ||
| 444 | /* simply try again */ | ||
| 445 | break; | ||
| 446 | case UART_IIR_XOFF: | ||
| 447 | /* FALLTHROUGH */ | ||
| 448 | default: | ||
| 449 | break; | ||
| 435 | } | 450 | } |
| 436 | } | 451 | } while (!(iir & UART_IIR_NO_INT) && max_count--); |
| 437 | 452 | ||
| 438 | check_modem_status(up); | 453 | spin_unlock(&up->port.lock); |
| 439 | if ((lsr & UART_LSR_THRE) && (iir & UART_IIR_THRI)) | ||
| 440 | transmit_chars(up); | ||
| 441 | 454 | ||
| 442 | spin_unlock_irqrestore(&up->port.lock, flags); | 455 | tty_flip_buffer_push(tty); |
| 443 | pm_runtime_mark_last_busy(&up->pdev->dev); | ||
| 444 | pm_runtime_put_autosuspend(&up->pdev->dev); | ||
| 445 | 456 | ||
| 457 | pm_runtime_mark_last_busy(up->dev); | ||
| 458 | pm_runtime_put_autosuspend(up->dev); | ||
| 446 | up->port_activity = jiffies; | 459 | up->port_activity = jiffies; |
| 447 | return IRQ_HANDLED; | 460 | |
| 461 | return ret; | ||
| 448 | } | 462 | } |
| 449 | 463 | ||
| 450 | static unsigned int serial_omap_tx_empty(struct uart_port *port) | 464 | static unsigned int serial_omap_tx_empty(struct uart_port *port) |
| 451 | { | 465 | { |
| 452 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 466 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 453 | unsigned long flags = 0; | 467 | unsigned long flags = 0; |
| 454 | unsigned int ret = 0; | 468 | unsigned int ret = 0; |
| 455 | 469 | ||
| 456 | pm_runtime_get_sync(&up->pdev->dev); | 470 | pm_runtime_get_sync(up->dev); |
| 457 | dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->port.line); | 471 | dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->port.line); |
| 458 | spin_lock_irqsave(&up->port.lock, flags); | 472 | spin_lock_irqsave(&up->port.lock, flags); |
| 459 | ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; | 473 | ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; |
| 460 | spin_unlock_irqrestore(&up->port.lock, flags); | 474 | spin_unlock_irqrestore(&up->port.lock, flags); |
| 461 | pm_runtime_put(&up->pdev->dev); | 475 | pm_runtime_mark_last_busy(up->dev); |
| 476 | pm_runtime_put_autosuspend(up->dev); | ||
| 462 | return ret; | 477 | return ret; |
| 463 | } | 478 | } |
| 464 | 479 | ||
| 465 | static unsigned int serial_omap_get_mctrl(struct uart_port *port) | 480 | static unsigned int serial_omap_get_mctrl(struct uart_port *port) |
| 466 | { | 481 | { |
| 467 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 482 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 468 | unsigned int status; | 483 | unsigned int status; |
| 469 | unsigned int ret = 0; | 484 | unsigned int ret = 0; |
| 470 | 485 | ||
| 471 | pm_runtime_get_sync(&up->pdev->dev); | 486 | pm_runtime_get_sync(up->dev); |
| 472 | status = check_modem_status(up); | 487 | status = check_modem_status(up); |
| 473 | pm_runtime_put(&up->pdev->dev); | 488 | pm_runtime_mark_last_busy(up->dev); |
| 489 | pm_runtime_put_autosuspend(up->dev); | ||
| 474 | 490 | ||
| 475 | dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->port.line); | 491 | dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->port.line); |
| 476 | 492 | ||
| @@ -487,7 +503,7 @@ static unsigned int serial_omap_get_mctrl(struct uart_port *port) | |||
| 487 | 503 | ||
| 488 | static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) | 504 | static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) |
| 489 | { | 505 | { |
| 490 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 506 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 491 | unsigned char mcr = 0; | 507 | unsigned char mcr = 0; |
| 492 | 508 | ||
| 493 | dev_dbg(up->port.dev, "serial_omap_set_mctrl+%d\n", up->port.line); | 509 | dev_dbg(up->port.dev, "serial_omap_set_mctrl+%d\n", up->port.line); |
| @@ -502,20 +518,31 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
| 502 | if (mctrl & TIOCM_LOOP) | 518 | if (mctrl & TIOCM_LOOP) |
| 503 | mcr |= UART_MCR_LOOP; | 519 | mcr |= UART_MCR_LOOP; |
| 504 | 520 | ||
| 505 | pm_runtime_get_sync(&up->pdev->dev); | 521 | pm_runtime_get_sync(up->dev); |
| 506 | up->mcr = serial_in(up, UART_MCR); | 522 | up->mcr = serial_in(up, UART_MCR); |
| 507 | up->mcr |= mcr; | 523 | up->mcr |= mcr; |
| 508 | serial_out(up, UART_MCR, up->mcr); | 524 | serial_out(up, UART_MCR, up->mcr); |
| 509 | pm_runtime_put(&up->pdev->dev); | 525 | pm_runtime_mark_last_busy(up->dev); |
| 526 | pm_runtime_put_autosuspend(up->dev); | ||
| 527 | |||
| 528 | if (gpio_is_valid(up->DTR_gpio) && | ||
| 529 | !!(mctrl & TIOCM_DTR) != up->DTR_active) { | ||
| 530 | up->DTR_active = !up->DTR_active; | ||
| 531 | if (gpio_cansleep(up->DTR_gpio)) | ||
| 532 | schedule_work(&up->qos_work); | ||
| 533 | else | ||
| 534 | gpio_set_value(up->DTR_gpio, | ||
| 535 | up->DTR_active != up->DTR_inverted); | ||
| 536 | } | ||
| 510 | } | 537 | } |
| 511 | 538 | ||
| 512 | static void serial_omap_break_ctl(struct uart_port *port, int break_state) | 539 | static void serial_omap_break_ctl(struct uart_port *port, int break_state) |
| 513 | { | 540 | { |
| 514 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 541 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 515 | unsigned long flags = 0; | 542 | unsigned long flags = 0; |
| 516 | 543 | ||
| 517 | dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->port.line); | 544 | dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->port.line); |
| 518 | pm_runtime_get_sync(&up->pdev->dev); | 545 | pm_runtime_get_sync(up->dev); |
| 519 | spin_lock_irqsave(&up->port.lock, flags); | 546 | spin_lock_irqsave(&up->port.lock, flags); |
| 520 | if (break_state == -1) | 547 | if (break_state == -1) |
| 521 | up->lcr |= UART_LCR_SBC; | 548 | up->lcr |= UART_LCR_SBC; |
| @@ -523,12 +550,13 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state) | |||
| 523 | up->lcr &= ~UART_LCR_SBC; | 550 | up->lcr &= ~UART_LCR_SBC; |
| 524 | serial_out(up, UART_LCR, up->lcr); | 551 | serial_out(up, UART_LCR, up->lcr); |
| 525 | spin_unlock_irqrestore(&up->port.lock, flags); | 552 | spin_unlock_irqrestore(&up->port.lock, flags); |
| 526 | pm_runtime_put(&up->pdev->dev); | 553 | pm_runtime_mark_last_busy(up->dev); |
| 554 | pm_runtime_put_autosuspend(up->dev); | ||
| 527 | } | 555 | } |
| 528 | 556 | ||
| 529 | static int serial_omap_startup(struct uart_port *port) | 557 | static int serial_omap_startup(struct uart_port *port) |
| 530 | { | 558 | { |
| 531 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 559 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 532 | unsigned long flags = 0; | 560 | unsigned long flags = 0; |
| 533 | int retval; | 561 | int retval; |
| 534 | 562 | ||
| @@ -542,7 +570,7 @@ static int serial_omap_startup(struct uart_port *port) | |||
| 542 | 570 | ||
| 543 | dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->port.line); | 571 | dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->port.line); |
| 544 | 572 | ||
| 545 | pm_runtime_get_sync(&up->pdev->dev); | 573 | pm_runtime_get_sync(up->dev); |
| 546 | /* | 574 | /* |
| 547 | * Clear the FIFO buffers and disable them. | 575 | * Clear the FIFO buffers and disable them. |
| 548 | * (they will be reenabled in set_termios()) | 576 | * (they will be reenabled in set_termios()) |
| @@ -573,20 +601,6 @@ static int serial_omap_startup(struct uart_port *port) | |||
| 573 | spin_unlock_irqrestore(&up->port.lock, flags); | 601 | spin_unlock_irqrestore(&up->port.lock, flags); |
| 574 | 602 | ||
| 575 | up->msr_saved_flags = 0; | 603 | up->msr_saved_flags = 0; |
| 576 | if (up->use_dma) { | ||
| 577 | free_page((unsigned long)up->port.state->xmit.buf); | ||
| 578 | up->port.state->xmit.buf = dma_alloc_coherent(NULL, | ||
| 579 | UART_XMIT_SIZE, | ||
| 580 | (dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys), | ||
| 581 | 0); | ||
| 582 | init_timer(&(up->uart_dma.rx_timer)); | ||
| 583 | up->uart_dma.rx_timer.function = serial_omap_rxdma_poll; | ||
| 584 | up->uart_dma.rx_timer.data = up->port.line; | ||
| 585 | /* Currently the buffer size is 4KB. Can increase it */ | ||
| 586 | up->uart_dma.rx_buf = dma_alloc_coherent(NULL, | ||
| 587 | up->uart_dma.rx_buf_size, | ||
| 588 | (dma_addr_t *)&(up->uart_dma.rx_buf_dma_phys), 0); | ||
| 589 | } | ||
| 590 | /* | 604 | /* |
| 591 | * Finally, enable interrupts. Note: Modem status interrupts | 605 | * Finally, enable interrupts. Note: Modem status interrupts |
| 592 | * are set via set_termios(), which will be occurring imminently | 606 | * are set via set_termios(), which will be occurring imminently |
| @@ -598,20 +612,20 @@ static int serial_omap_startup(struct uart_port *port) | |||
| 598 | /* Enable module level wake up */ | 612 | /* Enable module level wake up */ |
| 599 | serial_out(up, UART_OMAP_WER, OMAP_UART_WER_MOD_WKUP); | 613 | serial_out(up, UART_OMAP_WER, OMAP_UART_WER_MOD_WKUP); |
| 600 | 614 | ||
| 601 | pm_runtime_mark_last_busy(&up->pdev->dev); | 615 | pm_runtime_mark_last_busy(up->dev); |
| 602 | pm_runtime_put_autosuspend(&up->pdev->dev); | 616 | pm_runtime_put_autosuspend(up->dev); |
| 603 | up->port_activity = jiffies; | 617 | up->port_activity = jiffies; |
| 604 | return 0; | 618 | return 0; |
| 605 | } | 619 | } |
| 606 | 620 | ||
| 607 | static void serial_omap_shutdown(struct uart_port *port) | 621 | static void serial_omap_shutdown(struct uart_port *port) |
| 608 | { | 622 | { |
| 609 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 623 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 610 | unsigned long flags = 0; | 624 | unsigned long flags = 0; |
| 611 | 625 | ||
| 612 | dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->port.line); | 626 | dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->port.line); |
| 613 | 627 | ||
| 614 | pm_runtime_get_sync(&up->pdev->dev); | 628 | pm_runtime_get_sync(up->dev); |
| 615 | /* | 629 | /* |
| 616 | * Disable interrupts from this port | 630 | * Disable interrupts from this port |
| 617 | */ | 631 | */ |
| @@ -634,19 +648,9 @@ static void serial_omap_shutdown(struct uart_port *port) | |||
| 634 | */ | 648 | */ |
| 635 | if (serial_in(up, UART_LSR) & UART_LSR_DR) | 649 | if (serial_in(up, UART_LSR) & UART_LSR_DR) |
| 636 | (void) serial_in(up, UART_RX); | 650 | (void) serial_in(up, UART_RX); |
| 637 | if (up->use_dma) { | ||
| 638 | dma_free_coherent(up->port.dev, | ||
| 639 | UART_XMIT_SIZE, up->port.state->xmit.buf, | ||
| 640 | up->uart_dma.tx_buf_dma_phys); | ||
| 641 | up->port.state->xmit.buf = NULL; | ||
| 642 | serial_omap_stop_rx(port); | ||
| 643 | dma_free_coherent(up->port.dev, | ||
| 644 | up->uart_dma.rx_buf_size, up->uart_dma.rx_buf, | ||
| 645 | up->uart_dma.rx_buf_dma_phys); | ||
| 646 | up->uart_dma.rx_buf = NULL; | ||
| 647 | } | ||
| 648 | 651 | ||
| 649 | pm_runtime_put(&up->pdev->dev); | 652 | pm_runtime_mark_last_busy(up->dev); |
| 653 | pm_runtime_put_autosuspend(up->dev); | ||
| 650 | free_irq(up->port.irq, up); | 654 | free_irq(up->port.irq, up); |
| 651 | } | 655 | } |
| 652 | 656 | ||
| @@ -667,19 +671,19 @@ serial_omap_configure_xonxoff | |||
| 667 | 671 | ||
| 668 | /* | 672 | /* |
| 669 | * IXON Flag: | 673 | * IXON Flag: |
| 670 | * Enable XON/XOFF flow control on output. | 674 | * Flow control for OMAP.TX |
| 671 | * Transmit XON1, XOFF1 | 675 | * OMAP.RX should listen for XON/XOFF |
| 672 | */ | 676 | */ |
| 673 | if (termios->c_iflag & IXON) | 677 | if (termios->c_iflag & IXON) |
| 674 | up->efr |= OMAP_UART_SW_TX; | 678 | up->efr |= OMAP_UART_SW_RX; |
| 675 | 679 | ||
| 676 | /* | 680 | /* |
| 677 | * IXOFF Flag: | 681 | * IXOFF Flag: |
| 678 | * Enable XON/XOFF flow control on input. | 682 | * Flow control for OMAP.RX |
| 679 | * Receiver compares XON1, XOFF1. | 683 | * OMAP.TX should send XON/XOFF |
| 680 | */ | 684 | */ |
| 681 | if (termios->c_iflag & IXOFF) | 685 | if (termios->c_iflag & IXOFF) |
| 682 | up->efr |= OMAP_UART_SW_RX; | 686 | up->efr |= OMAP_UART_SW_TX; |
| 683 | 687 | ||
| 684 | serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); | 688 | serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); |
| 685 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | 689 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
| @@ -715,13 +719,16 @@ static void serial_omap_uart_qos_work(struct work_struct *work) | |||
| 715 | qos_work); | 719 | qos_work); |
| 716 | 720 | ||
| 717 | pm_qos_update_request(&up->pm_qos_request, up->latency); | 721 | pm_qos_update_request(&up->pm_qos_request, up->latency); |
| 722 | if (gpio_is_valid(up->DTR_gpio)) | ||
| 723 | gpio_set_value_cansleep(up->DTR_gpio, | ||
| 724 | up->DTR_active != up->DTR_inverted); | ||
| 718 | } | 725 | } |
| 719 | 726 | ||
| 720 | static void | 727 | static void |
| 721 | serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | 728 | serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, |
| 722 | struct ktermios *old) | 729 | struct ktermios *old) |
| 723 | { | 730 | { |
| 724 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 731 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 725 | unsigned char cval = 0; | 732 | unsigned char cval = 0; |
| 726 | unsigned char efr = 0; | 733 | unsigned char efr = 0; |
| 727 | unsigned long flags = 0; | 734 | unsigned long flags = 0; |
| @@ -768,14 +775,12 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 768 | 775 | ||
| 769 | up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 | | 776 | up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 | |
| 770 | UART_FCR_ENABLE_FIFO; | 777 | UART_FCR_ENABLE_FIFO; |
| 771 | if (up->use_dma) | ||
| 772 | up->fcr |= UART_FCR_DMA_SELECT; | ||
| 773 | 778 | ||
| 774 | /* | 779 | /* |
| 775 | * Ok, we're now changing the port state. Do it with | 780 | * Ok, we're now changing the port state. Do it with |
| 776 | * interrupts disabled. | 781 | * interrupts disabled. |
| 777 | */ | 782 | */ |
| 778 | pm_runtime_get_sync(&up->pdev->dev); | 783 | pm_runtime_get_sync(up->dev); |
| 779 | spin_lock_irqsave(&up->port.lock, flags); | 784 | spin_lock_irqsave(&up->port.lock, flags); |
| 780 | 785 | ||
| 781 | /* | 786 | /* |
| @@ -845,14 +850,13 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 845 | 850 | ||
| 846 | up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK; | 851 | up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK; |
| 847 | 852 | ||
| 848 | if (up->use_dma) { | 853 | /* Set receive FIFO threshold to 16 characters and |
| 849 | serial_out(up, UART_TI752_TLR, 0); | 854 | * transmit FIFO threshold to 16 spaces |
| 850 | up->scr |= UART_FCR_TRIGGER_4; | 855 | */ |
| 851 | } else { | 856 | up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK; |
| 852 | /* Set receive FIFO threshold to 1 byte */ | 857 | up->fcr &= ~OMAP_UART_FCR_TX_FIFO_TRIG_MASK; |
| 853 | up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK; | 858 | up->fcr |= UART_FCR6_R_TRIGGER_16 | UART_FCR6_T_TRIGGER_24 | |
| 854 | up->fcr |= (0x1 << OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT); | 859 | UART_FCR_ENABLE_FIFO; |
| 855 | } | ||
| 856 | 860 | ||
| 857 | serial_out(up, UART_FCR, up->fcr); | 861 | serial_out(up, UART_FCR, up->fcr); |
| 858 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 862 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| @@ -924,20 +928,30 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 924 | serial_omap_configure_xonxoff(up, termios); | 928 | serial_omap_configure_xonxoff(up, termios); |
| 925 | 929 | ||
| 926 | spin_unlock_irqrestore(&up->port.lock, flags); | 930 | spin_unlock_irqrestore(&up->port.lock, flags); |
| 927 | pm_runtime_put(&up->pdev->dev); | 931 | pm_runtime_mark_last_busy(up->dev); |
| 932 | pm_runtime_put_autosuspend(up->dev); | ||
| 928 | dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->port.line); | 933 | dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->port.line); |
| 929 | } | 934 | } |
| 930 | 935 | ||
| 936 | static int serial_omap_set_wake(struct uart_port *port, unsigned int state) | ||
| 937 | { | ||
| 938 | struct uart_omap_port *up = to_uart_omap_port(port); | ||
| 939 | |||
| 940 | serial_omap_enable_wakeup(up, state); | ||
| 941 | |||
| 942 | return 0; | ||
| 943 | } | ||
| 944 | |||
| 931 | static void | 945 | static void |
| 932 | serial_omap_pm(struct uart_port *port, unsigned int state, | 946 | serial_omap_pm(struct uart_port *port, unsigned int state, |
| 933 | unsigned int oldstate) | 947 | unsigned int oldstate) |
| 934 | { | 948 | { |
| 935 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 949 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 936 | unsigned char efr; | 950 | unsigned char efr; |
| 937 | 951 | ||
| 938 | dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->port.line); | 952 | dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->port.line); |
| 939 | 953 | ||
| 940 | pm_runtime_get_sync(&up->pdev->dev); | 954 | pm_runtime_get_sync(up->dev); |
| 941 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 955 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| 942 | efr = serial_in(up, UART_EFR); | 956 | efr = serial_in(up, UART_EFR); |
| 943 | serial_out(up, UART_EFR, efr | UART_EFR_ECB); | 957 | serial_out(up, UART_EFR, efr | UART_EFR_ECB); |
| @@ -948,14 +962,15 @@ serial_omap_pm(struct uart_port *port, unsigned int state, | |||
| 948 | serial_out(up, UART_EFR, efr); | 962 | serial_out(up, UART_EFR, efr); |
| 949 | serial_out(up, UART_LCR, 0); | 963 | serial_out(up, UART_LCR, 0); |
| 950 | 964 | ||
| 951 | if (!device_may_wakeup(&up->pdev->dev)) { | 965 | if (!device_may_wakeup(up->dev)) { |
| 952 | if (!state) | 966 | if (!state) |
| 953 | pm_runtime_forbid(&up->pdev->dev); | 967 | pm_runtime_forbid(up->dev); |
| 954 | else | 968 | else |
| 955 | pm_runtime_allow(&up->pdev->dev); | 969 | pm_runtime_allow(up->dev); |
| 956 | } | 970 | } |
| 957 | 971 | ||
| 958 | pm_runtime_put(&up->pdev->dev); | 972 | pm_runtime_mark_last_busy(up->dev); |
| 973 | pm_runtime_put_autosuspend(up->dev); | ||
| 959 | } | 974 | } |
| 960 | 975 | ||
| 961 | static void serial_omap_release_port(struct uart_port *port) | 976 | static void serial_omap_release_port(struct uart_port *port) |
| @@ -971,7 +986,7 @@ static int serial_omap_request_port(struct uart_port *port) | |||
| 971 | 986 | ||
| 972 | static void serial_omap_config_port(struct uart_port *port, int flags) | 987 | static void serial_omap_config_port(struct uart_port *port, int flags) |
| 973 | { | 988 | { |
| 974 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 989 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 975 | 990 | ||
| 976 | dev_dbg(up->port.dev, "serial_omap_config_port+%d\n", | 991 | dev_dbg(up->port.dev, "serial_omap_config_port+%d\n", |
| 977 | up->port.line); | 992 | up->port.line); |
| @@ -989,7 +1004,7 @@ serial_omap_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
| 989 | static const char * | 1004 | static const char * |
| 990 | serial_omap_type(struct uart_port *port) | 1005 | serial_omap_type(struct uart_port *port) |
| 991 | { | 1006 | { |
| 992 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 1007 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 993 | 1008 | ||
| 994 | dev_dbg(up->port.dev, "serial_omap_type+%d\n", up->port.line); | 1009 | dev_dbg(up->port.dev, "serial_omap_type+%d\n", up->port.line); |
| 995 | return up->name; | 1010 | return up->name; |
| @@ -1032,26 +1047,33 @@ static inline void wait_for_xmitr(struct uart_omap_port *up) | |||
| 1032 | 1047 | ||
| 1033 | static void serial_omap_poll_put_char(struct uart_port *port, unsigned char ch) | 1048 | static void serial_omap_poll_put_char(struct uart_port *port, unsigned char ch) |
| 1034 | { | 1049 | { |
| 1035 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 1050 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 1036 | 1051 | ||
| 1037 | pm_runtime_get_sync(&up->pdev->dev); | 1052 | pm_runtime_get_sync(up->dev); |
| 1038 | wait_for_xmitr(up); | 1053 | wait_for_xmitr(up); |
| 1039 | serial_out(up, UART_TX, ch); | 1054 | serial_out(up, UART_TX, ch); |
| 1040 | pm_runtime_put(&up->pdev->dev); | 1055 | pm_runtime_mark_last_busy(up->dev); |
| 1056 | pm_runtime_put_autosuspend(up->dev); | ||
| 1041 | } | 1057 | } |
| 1042 | 1058 | ||
| 1043 | static int serial_omap_poll_get_char(struct uart_port *port) | 1059 | static int serial_omap_poll_get_char(struct uart_port *port) |
| 1044 | { | 1060 | { |
| 1045 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 1061 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 1046 | unsigned int status; | 1062 | unsigned int status; |
| 1047 | 1063 | ||
| 1048 | pm_runtime_get_sync(&up->pdev->dev); | 1064 | pm_runtime_get_sync(up->dev); |
| 1049 | status = serial_in(up, UART_LSR); | 1065 | status = serial_in(up, UART_LSR); |
| 1050 | if (!(status & UART_LSR_DR)) | 1066 | if (!(status & UART_LSR_DR)) { |
| 1051 | return NO_POLL_CHAR; | 1067 | status = NO_POLL_CHAR; |
| 1068 | goto out; | ||
| 1069 | } | ||
| 1052 | 1070 | ||
| 1053 | status = serial_in(up, UART_RX); | 1071 | status = serial_in(up, UART_RX); |
| 1054 | pm_runtime_put(&up->pdev->dev); | 1072 | |
| 1073 | out: | ||
| 1074 | pm_runtime_mark_last_busy(up->dev); | ||
| 1075 | pm_runtime_put_autosuspend(up->dev); | ||
| 1076 | |||
| 1055 | return status; | 1077 | return status; |
| 1056 | } | 1078 | } |
| 1057 | 1079 | ||
| @@ -1065,7 +1087,7 @@ static struct uart_driver serial_omap_reg; | |||
| 1065 | 1087 | ||
| 1066 | static void serial_omap_console_putchar(struct uart_port *port, int ch) | 1088 | static void serial_omap_console_putchar(struct uart_port *port, int ch) |
| 1067 | { | 1089 | { |
| 1068 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 1090 | struct uart_omap_port *up = to_uart_omap_port(port); |
| 1069 | 1091 | ||
| 1070 | wait_for_xmitr(up); | 1092 | wait_for_xmitr(up); |
| 1071 | serial_out(up, UART_TX, ch); | 1093 | serial_out(up, UART_TX, ch); |
| @@ -1080,7 +1102,7 @@ serial_omap_console_write(struct console *co, const char *s, | |||
| 1080 | unsigned int ier; | 1102 | unsigned int ier; |
| 1081 | int locked = 1; | 1103 | int locked = 1; |
| 1082 | 1104 | ||
| 1083 | pm_runtime_get_sync(&up->pdev->dev); | 1105 | pm_runtime_get_sync(up->dev); |
| 1084 | 1106 | ||
| 1085 | local_irq_save(flags); | 1107 | local_irq_save(flags); |
| 1086 | if (up->port.sysrq) | 1108 | if (up->port.sysrq) |
| @@ -1114,8 +1136,8 @@ serial_omap_console_write(struct console *co, const char *s, | |||
| 1114 | if (up->msr_saved_flags) | 1136 | if (up->msr_saved_flags) |
| 1115 | check_modem_status(up); | 1137 | check_modem_status(up); |
| 1116 | 1138 | ||
| 1117 | pm_runtime_mark_last_busy(&up->pdev->dev); | 1139 | pm_runtime_mark_last_busy(up->dev); |
| 1118 | pm_runtime_put_autosuspend(&up->pdev->dev); | 1140 | pm_runtime_put_autosuspend(up->dev); |
| 1119 | if (locked) | 1141 | if (locked) |
| 1120 | spin_unlock(&up->port.lock); | 1142 | spin_unlock(&up->port.lock); |
| 1121 | local_irq_restore(flags); | 1143 | local_irq_restore(flags); |
| @@ -1179,6 +1201,7 @@ static struct uart_ops serial_omap_pops = { | |||
| 1179 | .shutdown = serial_omap_shutdown, | 1201 | .shutdown = serial_omap_shutdown, |
| 1180 | .set_termios = serial_omap_set_termios, | 1202 | .set_termios = serial_omap_set_termios, |
| 1181 | .pm = serial_omap_pm, | 1203 | .pm = serial_omap_pm, |
| 1204 | .set_wake = serial_omap_set_wake, | ||
| 1182 | .type = serial_omap_type, | 1205 | .type = serial_omap_type, |
| 1183 | .release_port = serial_omap_release_port, | 1206 | .release_port = serial_omap_release_port, |
| 1184 | .request_port = serial_omap_request_port, | 1207 | .request_port = serial_omap_request_port, |
| @@ -1203,10 +1226,8 @@ static int serial_omap_suspend(struct device *dev) | |||
| 1203 | { | 1226 | { |
| 1204 | struct uart_omap_port *up = dev_get_drvdata(dev); | 1227 | struct uart_omap_port *up = dev_get_drvdata(dev); |
| 1205 | 1228 | ||
| 1206 | if (up) { | 1229 | uart_suspend_port(&serial_omap_reg, &up->port); |
| 1207 | uart_suspend_port(&serial_omap_reg, &up->port); | 1230 | flush_work_sync(&up->qos_work); |
| 1208 | flush_work_sync(&up->qos_work); | ||
| 1209 | } | ||
| 1210 | 1231 | ||
| 1211 | return 0; | 1232 | return 0; |
| 1212 | } | 1233 | } |
| @@ -1215,156 +1236,13 @@ static int serial_omap_resume(struct device *dev) | |||
| 1215 | { | 1236 | { |
| 1216 | struct uart_omap_port *up = dev_get_drvdata(dev); | 1237 | struct uart_omap_port *up = dev_get_drvdata(dev); |
| 1217 | 1238 | ||
| 1218 | if (up) | 1239 | uart_resume_port(&serial_omap_reg, &up->port); |
| 1219 | uart_resume_port(&serial_omap_reg, &up->port); | 1240 | |
| 1220 | return 0; | 1241 | return 0; |
| 1221 | } | 1242 | } |
| 1222 | #endif | 1243 | #endif |
| 1223 | 1244 | ||
| 1224 | static void serial_omap_rxdma_poll(unsigned long uart_no) | 1245 | static void __devinit omap_serial_fill_features_erratas(struct uart_omap_port *up) |
| 1225 | { | ||
| 1226 | struct uart_omap_port *up = ui[uart_no]; | ||
| 1227 | unsigned int curr_dma_pos, curr_transmitted_size; | ||
| 1228 | int ret = 0; | ||
| 1229 | |||
| 1230 | curr_dma_pos = omap_get_dma_dst_pos(up->uart_dma.rx_dma_channel); | ||
| 1231 | if ((curr_dma_pos == up->uart_dma.prev_rx_dma_pos) || | ||
| 1232 | (curr_dma_pos == 0)) { | ||
| 1233 | if (jiffies_to_msecs(jiffies - up->port_activity) < | ||
| 1234 | up->uart_dma.rx_timeout) { | ||
| 1235 | mod_timer(&up->uart_dma.rx_timer, jiffies + | ||
| 1236 | usecs_to_jiffies(up->uart_dma.rx_poll_rate)); | ||
| 1237 | } else { | ||
| 1238 | serial_omap_stop_rxdma(up); | ||
| 1239 | up->ier |= (UART_IER_RDI | UART_IER_RLSI); | ||
| 1240 | serial_out(up, UART_IER, up->ier); | ||
| 1241 | } | ||
| 1242 | return; | ||
| 1243 | } | ||
| 1244 | |||
| 1245 | curr_transmitted_size = curr_dma_pos - | ||
| 1246 | up->uart_dma.prev_rx_dma_pos; | ||
| 1247 | up->port.icount.rx += curr_transmitted_size; | ||
| 1248 | tty_insert_flip_string(up->port.state->port.tty, | ||
| 1249 | up->uart_dma.rx_buf + | ||
| 1250 | (up->uart_dma.prev_rx_dma_pos - | ||
| 1251 | up->uart_dma.rx_buf_dma_phys), | ||
| 1252 | curr_transmitted_size); | ||
| 1253 | tty_flip_buffer_push(up->port.state->port.tty); | ||
| 1254 | up->uart_dma.prev_rx_dma_pos = curr_dma_pos; | ||
| 1255 | if (up->uart_dma.rx_buf_size + | ||
| 1256 | up->uart_dma.rx_buf_dma_phys == curr_dma_pos) { | ||
| 1257 | ret = serial_omap_start_rxdma(up); | ||
| 1258 | if (ret < 0) { | ||
| 1259 | serial_omap_stop_rxdma(up); | ||
| 1260 | up->ier |= (UART_IER_RDI | UART_IER_RLSI); | ||
| 1261 | serial_out(up, UART_IER, up->ier); | ||
| 1262 | } | ||
| 1263 | } else { | ||
| 1264 | mod_timer(&up->uart_dma.rx_timer, jiffies + | ||
| 1265 | usecs_to_jiffies(up->uart_dma.rx_poll_rate)); | ||
| 1266 | } | ||
| 1267 | up->port_activity = jiffies; | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | static void uart_rx_dma_callback(int lch, u16 ch_status, void *data) | ||
| 1271 | { | ||
| 1272 | return; | ||
| 1273 | } | ||
| 1274 | |||
| 1275 | static int serial_omap_start_rxdma(struct uart_omap_port *up) | ||
| 1276 | { | ||
| 1277 | int ret = 0; | ||
| 1278 | |||
| 1279 | if (up->uart_dma.rx_dma_channel == -1) { | ||
| 1280 | pm_runtime_get_sync(&up->pdev->dev); | ||
| 1281 | ret = omap_request_dma(up->uart_dma.uart_dma_rx, | ||
| 1282 | "UART Rx DMA", | ||
| 1283 | (void *)uart_rx_dma_callback, up, | ||
| 1284 | &(up->uart_dma.rx_dma_channel)); | ||
| 1285 | if (ret < 0) | ||
| 1286 | return ret; | ||
| 1287 | |||
| 1288 | omap_set_dma_src_params(up->uart_dma.rx_dma_channel, 0, | ||
| 1289 | OMAP_DMA_AMODE_CONSTANT, | ||
| 1290 | up->uart_dma.uart_base, 0, 0); | ||
| 1291 | omap_set_dma_dest_params(up->uart_dma.rx_dma_channel, 0, | ||
| 1292 | OMAP_DMA_AMODE_POST_INC, | ||
| 1293 | up->uart_dma.rx_buf_dma_phys, 0, 0); | ||
| 1294 | omap_set_dma_transfer_params(up->uart_dma.rx_dma_channel, | ||
| 1295 | OMAP_DMA_DATA_TYPE_S8, | ||
| 1296 | up->uart_dma.rx_buf_size, 1, | ||
| 1297 | OMAP_DMA_SYNC_ELEMENT, | ||
| 1298 | up->uart_dma.uart_dma_rx, 0); | ||
| 1299 | } | ||
| 1300 | up->uart_dma.prev_rx_dma_pos = up->uart_dma.rx_buf_dma_phys; | ||
| 1301 | /* FIXME: Cache maintenance needed here? */ | ||
| 1302 | omap_start_dma(up->uart_dma.rx_dma_channel); | ||
| 1303 | mod_timer(&up->uart_dma.rx_timer, jiffies + | ||
| 1304 | usecs_to_jiffies(up->uart_dma.rx_poll_rate)); | ||
| 1305 | up->uart_dma.rx_dma_used = true; | ||
| 1306 | return ret; | ||
| 1307 | } | ||
| 1308 | |||
| 1309 | static void serial_omap_continue_tx(struct uart_omap_port *up) | ||
| 1310 | { | ||
| 1311 | struct circ_buf *xmit = &up->port.state->xmit; | ||
| 1312 | unsigned int start = up->uart_dma.tx_buf_dma_phys | ||
| 1313 | + (xmit->tail & (UART_XMIT_SIZE - 1)); | ||
| 1314 | |||
| 1315 | if (uart_circ_empty(xmit)) | ||
| 1316 | return; | ||
| 1317 | |||
| 1318 | up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit); | ||
| 1319 | /* | ||
| 1320 | * It is a circular buffer. See if the buffer has wounded back. | ||
| 1321 | * If yes it will have to be transferred in two separate dma | ||
| 1322 | * transfers | ||
| 1323 | */ | ||
| 1324 | if (start + up->uart_dma.tx_buf_size >= | ||
| 1325 | up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) | ||
| 1326 | up->uart_dma.tx_buf_size = | ||
| 1327 | (up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) - start; | ||
| 1328 | omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0, | ||
| 1329 | OMAP_DMA_AMODE_CONSTANT, | ||
| 1330 | up->uart_dma.uart_base, 0, 0); | ||
| 1331 | omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0, | ||
| 1332 | OMAP_DMA_AMODE_POST_INC, start, 0, 0); | ||
| 1333 | omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel, | ||
| 1334 | OMAP_DMA_DATA_TYPE_S8, | ||
| 1335 | up->uart_dma.tx_buf_size, 1, | ||
| 1336 | OMAP_DMA_SYNC_ELEMENT, | ||
| 1337 | up->uart_dma.uart_dma_tx, 0); | ||
| 1338 | /* FIXME: Cache maintenance needed here? */ | ||
| 1339 | omap_start_dma(up->uart_dma.tx_dma_channel); | ||
| 1340 | } | ||
| 1341 | |||
| 1342 | static void uart_tx_dma_callback(int lch, u16 ch_status, void *data) | ||
| 1343 | { | ||
| 1344 | struct uart_omap_port *up = (struct uart_omap_port *)data; | ||
| 1345 | struct circ_buf *xmit = &up->port.state->xmit; | ||
| 1346 | |||
| 1347 | xmit->tail = (xmit->tail + up->uart_dma.tx_buf_size) & \ | ||
| 1348 | (UART_XMIT_SIZE - 1); | ||
| 1349 | up->port.icount.tx += up->uart_dma.tx_buf_size; | ||
| 1350 | |||
| 1351 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
| 1352 | uart_write_wakeup(&up->port); | ||
| 1353 | |||
| 1354 | if (uart_circ_empty(xmit)) { | ||
| 1355 | spin_lock(&(up->uart_dma.tx_lock)); | ||
| 1356 | serial_omap_stop_tx(&up->port); | ||
| 1357 | up->uart_dma.tx_dma_used = false; | ||
| 1358 | spin_unlock(&(up->uart_dma.tx_lock)); | ||
| 1359 | } else { | ||
| 1360 | omap_stop_dma(up->uart_dma.tx_dma_channel); | ||
| 1361 | serial_omap_continue_tx(up); | ||
| 1362 | } | ||
| 1363 | up->port_activity = jiffies; | ||
| 1364 | return; | ||
| 1365 | } | ||
| 1366 | |||
| 1367 | static void omap_serial_fill_features_erratas(struct uart_omap_port *up) | ||
| 1368 | { | 1246 | { |
| 1369 | u32 mvr, scheme; | 1247 | u32 mvr, scheme; |
| 1370 | u16 revision, major, minor; | 1248 | u16 revision, major, minor; |
| @@ -1389,7 +1267,7 @@ static void omap_serial_fill_features_erratas(struct uart_omap_port *up) | |||
| 1389 | minor = (mvr & OMAP_UART_MVR_MIN_MASK); | 1267 | minor = (mvr & OMAP_UART_MVR_MIN_MASK); |
| 1390 | break; | 1268 | break; |
| 1391 | default: | 1269 | default: |
| 1392 | dev_warn(&up->pdev->dev, | 1270 | dev_warn(up->dev, |
| 1393 | "Unknown %s revision, defaulting to highest\n", | 1271 | "Unknown %s revision, defaulting to highest\n", |
| 1394 | up->name); | 1272 | up->name); |
| 1395 | /* highest possible revision */ | 1273 | /* highest possible revision */ |
| @@ -1417,7 +1295,7 @@ static void omap_serial_fill_features_erratas(struct uart_omap_port *up) | |||
| 1417 | } | 1295 | } |
| 1418 | } | 1296 | } |
| 1419 | 1297 | ||
| 1420 | static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) | 1298 | static __devinit struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) |
| 1421 | { | 1299 | { |
| 1422 | struct omap_uart_port_info *omap_up_info; | 1300 | struct omap_uart_port_info *omap_up_info; |
| 1423 | 1301 | ||
| @@ -1430,12 +1308,12 @@ static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) | |||
| 1430 | return omap_up_info; | 1308 | return omap_up_info; |
| 1431 | } | 1309 | } |
| 1432 | 1310 | ||
| 1433 | static int serial_omap_probe(struct platform_device *pdev) | 1311 | static int __devinit serial_omap_probe(struct platform_device *pdev) |
| 1434 | { | 1312 | { |
| 1435 | struct uart_omap_port *up; | 1313 | struct uart_omap_port *up; |
| 1436 | struct resource *mem, *irq, *dma_tx, *dma_rx; | 1314 | struct resource *mem, *irq; |
| 1437 | struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data; | 1315 | struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data; |
| 1438 | int ret = -ENOSPC; | 1316 | int ret; |
| 1439 | 1317 | ||
| 1440 | if (pdev->dev.of_node) | 1318 | if (pdev->dev.of_node) |
| 1441 | omap_up_info = of_get_uart_port_info(&pdev->dev); | 1319 | omap_up_info = of_get_uart_port_info(&pdev->dev); |
| @@ -1458,19 +1336,30 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
| 1458 | return -EBUSY; | 1336 | return -EBUSY; |
| 1459 | } | 1337 | } |
| 1460 | 1338 | ||
| 1461 | dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); | 1339 | if (gpio_is_valid(omap_up_info->DTR_gpio) && |
| 1462 | if (!dma_rx) | 1340 | omap_up_info->DTR_present) { |
| 1463 | return -ENXIO; | 1341 | ret = gpio_request(omap_up_info->DTR_gpio, "omap-serial"); |
| 1464 | 1342 | if (ret < 0) | |
| 1465 | dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); | 1343 | return ret; |
| 1466 | if (!dma_tx) | 1344 | ret = gpio_direction_output(omap_up_info->DTR_gpio, |
| 1467 | return -ENXIO; | 1345 | omap_up_info->DTR_inverted); |
| 1346 | if (ret < 0) | ||
| 1347 | return ret; | ||
| 1348 | } | ||
| 1468 | 1349 | ||
| 1469 | up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL); | 1350 | up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL); |
| 1470 | if (!up) | 1351 | if (!up) |
| 1471 | return -ENOMEM; | 1352 | return -ENOMEM; |
| 1472 | 1353 | ||
| 1473 | up->pdev = pdev; | 1354 | if (gpio_is_valid(omap_up_info->DTR_gpio) && |
| 1355 | omap_up_info->DTR_present) { | ||
| 1356 | up->DTR_gpio = omap_up_info->DTR_gpio; | ||
| 1357 | up->DTR_inverted = omap_up_info->DTR_inverted; | ||
| 1358 | } else | ||
| 1359 | up->DTR_gpio = -EINVAL; | ||
| 1360 | up->DTR_active = 0; | ||
| 1361 | |||
| 1362 | up->dev = &pdev->dev; | ||
| 1474 | up->port.dev = &pdev->dev; | 1363 | up->port.dev = &pdev->dev; |
| 1475 | up->port.type = PORT_OMAP; | 1364 | up->port.type = PORT_OMAP; |
| 1476 | up->port.iotype = UPIO_MEM; | 1365 | up->port.iotype = UPIO_MEM; |
| @@ -1492,6 +1381,13 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
| 1492 | goto err_port_line; | 1381 | goto err_port_line; |
| 1493 | } | 1382 | } |
| 1494 | 1383 | ||
| 1384 | up->pins = devm_pinctrl_get_select_default(&pdev->dev); | ||
| 1385 | if (IS_ERR(up->pins)) { | ||
| 1386 | dev_warn(&pdev->dev, "did not get pins for uart%i error: %li\n", | ||
| 1387 | up->port.line, PTR_ERR(up->pins)); | ||
| 1388 | up->pins = NULL; | ||
| 1389 | } | ||
| 1390 | |||
| 1495 | sprintf(up->name, "OMAP UART%d", up->port.line); | 1391 | sprintf(up->name, "OMAP UART%d", up->port.line); |
| 1496 | up->port.mapbase = mem->start; | 1392 | up->port.mapbase = mem->start; |
| 1497 | up->port.membase = devm_ioremap(&pdev->dev, mem->start, | 1393 | up->port.membase = devm_ioremap(&pdev->dev, mem->start, |
| @@ -1509,20 +1405,6 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
| 1509 | dev_warn(&pdev->dev, "No clock speed specified: using default:" | 1405 | dev_warn(&pdev->dev, "No clock speed specified: using default:" |
| 1510 | "%d\n", DEFAULT_CLK_SPEED); | 1406 | "%d\n", DEFAULT_CLK_SPEED); |
| 1511 | } | 1407 | } |
| 1512 | up->uart_dma.uart_base = mem->start; | ||
| 1513 | |||
| 1514 | if (omap_up_info->dma_enabled) { | ||
| 1515 | up->uart_dma.uart_dma_tx = dma_tx->start; | ||
| 1516 | up->uart_dma.uart_dma_rx = dma_rx->start; | ||
| 1517 | up->use_dma = 1; | ||
| 1518 | up->uart_dma.rx_buf_size = omap_up_info->dma_rx_buf_size; | ||
| 1519 | up->uart_dma.rx_timeout = omap_up_info->dma_rx_timeout; | ||
| 1520 | up->uart_dma.rx_poll_rate = omap_up_info->dma_rx_poll_rate; | ||
| 1521 | spin_lock_init(&(up->uart_dma.tx_lock)); | ||
| 1522 | spin_lock_init(&(up->uart_dma.rx_lock)); | ||
| 1523 | up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; | ||
| 1524 | up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; | ||
| 1525 | } | ||
| 1526 | 1408 | ||
| 1527 | up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | 1409 | up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; |
| 1528 | up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | 1410 | up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; |
| @@ -1531,12 +1413,13 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
| 1531 | serial_omap_uart_wq = create_singlethread_workqueue(up->name); | 1413 | serial_omap_uart_wq = create_singlethread_workqueue(up->name); |
| 1532 | INIT_WORK(&up->qos_work, serial_omap_uart_qos_work); | 1414 | INIT_WORK(&up->qos_work, serial_omap_uart_qos_work); |
| 1533 | 1415 | ||
| 1416 | platform_set_drvdata(pdev, up); | ||
| 1417 | pm_runtime_enable(&pdev->dev); | ||
| 1534 | pm_runtime_use_autosuspend(&pdev->dev); | 1418 | pm_runtime_use_autosuspend(&pdev->dev); |
| 1535 | pm_runtime_set_autosuspend_delay(&pdev->dev, | 1419 | pm_runtime_set_autosuspend_delay(&pdev->dev, |
| 1536 | omap_up_info->autosuspend_timeout); | 1420 | omap_up_info->autosuspend_timeout); |
| 1537 | 1421 | ||
| 1538 | pm_runtime_irq_safe(&pdev->dev); | 1422 | pm_runtime_irq_safe(&pdev->dev); |
| 1539 | pm_runtime_enable(&pdev->dev); | ||
| 1540 | pm_runtime_get_sync(&pdev->dev); | 1423 | pm_runtime_get_sync(&pdev->dev); |
| 1541 | 1424 | ||
| 1542 | omap_serial_fill_features_erratas(up); | 1425 | omap_serial_fill_features_erratas(up); |
| @@ -1548,8 +1431,8 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
| 1548 | if (ret != 0) | 1431 | if (ret != 0) |
| 1549 | goto err_add_port; | 1432 | goto err_add_port; |
| 1550 | 1433 | ||
| 1551 | pm_runtime_put(&pdev->dev); | 1434 | pm_runtime_mark_last_busy(up->dev); |
| 1552 | platform_set_drvdata(pdev, up); | 1435 | pm_runtime_put_autosuspend(up->dev); |
| 1553 | return 0; | 1436 | return 0; |
| 1554 | 1437 | ||
| 1555 | err_add_port: | 1438 | err_add_port: |
| @@ -1562,17 +1445,15 @@ err_port_line: | |||
| 1562 | return ret; | 1445 | return ret; |
| 1563 | } | 1446 | } |
| 1564 | 1447 | ||
| 1565 | static int serial_omap_remove(struct platform_device *dev) | 1448 | static int __devexit serial_omap_remove(struct platform_device *dev) |
| 1566 | { | 1449 | { |
| 1567 | struct uart_omap_port *up = platform_get_drvdata(dev); | 1450 | struct uart_omap_port *up = platform_get_drvdata(dev); |
| 1568 | 1451 | ||
| 1569 | if (up) { | 1452 | pm_runtime_put_sync(up->dev); |
| 1570 | pm_runtime_disable(&up->pdev->dev); | 1453 | pm_runtime_disable(up->dev); |
| 1571 | uart_remove_one_port(&serial_omap_reg, &up->port); | 1454 | uart_remove_one_port(&serial_omap_reg, &up->port); |
| 1572 | pm_qos_remove_request(&up->pm_qos_request); | 1455 | pm_qos_remove_request(&up->pm_qos_request); |
| 1573 | } | ||
| 1574 | 1456 | ||
| 1575 | platform_set_drvdata(dev, NULL); | ||
| 1576 | return 0; | 1457 | return 0; |
| 1577 | } | 1458 | } |
| 1578 | 1459 | ||
| @@ -1602,7 +1483,7 @@ static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1) | |||
| 1602 | timeout--; | 1483 | timeout--; |
| 1603 | if (!timeout) { | 1484 | if (!timeout) { |
| 1604 | /* Should *never* happen. we warn and carry on */ | 1485 | /* Should *never* happen. we warn and carry on */ |
| 1605 | dev_crit(&up->pdev->dev, "Errata i202: timedout %x\n", | 1486 | dev_crit(up->dev, "Errata i202: timedout %x\n", |
| 1606 | serial_in(up, UART_LSR)); | 1487 | serial_in(up, UART_LSR)); |
| 1607 | break; | 1488 | break; |
| 1608 | } | 1489 | } |
| @@ -1648,29 +1529,23 @@ static int serial_omap_runtime_suspend(struct device *dev) | |||
| 1648 | if (!up) | 1529 | if (!up) |
| 1649 | return -EINVAL; | 1530 | return -EINVAL; |
| 1650 | 1531 | ||
| 1651 | if (!pdata || !pdata->enable_wakeup) | 1532 | if (!pdata) |
| 1652 | return 0; | 1533 | return 0; |
| 1653 | 1534 | ||
| 1654 | if (pdata->get_context_loss_count) | 1535 | up->context_loss_cnt = serial_omap_get_context_loss_count(up); |
| 1655 | up->context_loss_cnt = pdata->get_context_loss_count(dev); | ||
| 1656 | 1536 | ||
| 1657 | if (device_may_wakeup(dev)) { | 1537 | if (device_may_wakeup(dev)) { |
| 1658 | if (!up->wakeups_enabled) { | 1538 | if (!up->wakeups_enabled) { |
| 1659 | pdata->enable_wakeup(up->pdev, true); | 1539 | serial_omap_enable_wakeup(up, true); |
| 1660 | up->wakeups_enabled = true; | 1540 | up->wakeups_enabled = true; |
| 1661 | } | 1541 | } |
| 1662 | } else { | 1542 | } else { |
| 1663 | if (up->wakeups_enabled) { | 1543 | if (up->wakeups_enabled) { |
| 1664 | pdata->enable_wakeup(up->pdev, false); | 1544 | serial_omap_enable_wakeup(up, false); |
| 1665 | up->wakeups_enabled = false; | 1545 | up->wakeups_enabled = false; |
| 1666 | } | 1546 | } |
| 1667 | } | 1547 | } |
| 1668 | 1548 | ||
| 1669 | /* Errata i291 */ | ||
| 1670 | if (up->use_dma && pdata->set_forceidle && | ||
| 1671 | (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) | ||
| 1672 | pdata->set_forceidle(up->pdev); | ||
| 1673 | |||
| 1674 | up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | 1549 | up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; |
| 1675 | schedule_work(&up->qos_work); | 1550 | schedule_work(&up->qos_work); |
| 1676 | 1551 | ||
| @@ -1680,24 +1555,14 @@ static int serial_omap_runtime_suspend(struct device *dev) | |||
| 1680 | static int serial_omap_runtime_resume(struct device *dev) | 1555 | static int serial_omap_runtime_resume(struct device *dev) |
| 1681 | { | 1556 | { |
| 1682 | struct uart_omap_port *up = dev_get_drvdata(dev); | 1557 | struct uart_omap_port *up = dev_get_drvdata(dev); |
| 1683 | struct omap_uart_port_info *pdata = dev->platform_data; | ||
| 1684 | |||
| 1685 | if (up && pdata) { | ||
| 1686 | if (pdata->get_context_loss_count) { | ||
| 1687 | u32 loss_cnt = pdata->get_context_loss_count(dev); | ||
| 1688 | 1558 | ||
| 1689 | if (up->context_loss_cnt != loss_cnt) | 1559 | u32 loss_cnt = serial_omap_get_context_loss_count(up); |
| 1690 | serial_omap_restore_context(up); | ||
| 1691 | } | ||
| 1692 | 1560 | ||
| 1693 | /* Errata i291 */ | 1561 | if (up->context_loss_cnt != loss_cnt) |
| 1694 | if (up->use_dma && pdata->set_noidle && | 1562 | serial_omap_restore_context(up); |
| 1695 | (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) | ||
| 1696 | pdata->set_noidle(up->pdev); | ||
| 1697 | 1563 | ||
| 1698 | up->latency = up->calc_latency; | 1564 | up->latency = up->calc_latency; |
| 1699 | schedule_work(&up->qos_work); | 1565 | schedule_work(&up->qos_work); |
| 1700 | } | ||
| 1701 | 1566 | ||
| 1702 | return 0; | 1567 | return 0; |
| 1703 | } | 1568 | } |
| @@ -1721,7 +1586,7 @@ MODULE_DEVICE_TABLE(of, omap_serial_of_match); | |||
| 1721 | 1586 | ||
| 1722 | static struct platform_driver serial_omap_driver = { | 1587 | static struct platform_driver serial_omap_driver = { |
| 1723 | .probe = serial_omap_probe, | 1588 | .probe = serial_omap_probe, |
| 1724 | .remove = serial_omap_remove, | 1589 | .remove = __devexit_p(serial_omap_remove), |
| 1725 | .driver = { | 1590 | .driver = { |
| 1726 | .name = DRIVER_NAME, | 1591 | .name = DRIVER_NAME, |
| 1727 | .pm = &serial_omap_dev_pm_ops, | 1592 | .pm = &serial_omap_dev_pm_ops, |
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 558ce8509a9a..4cd6c2381528 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c | |||
| @@ -979,6 +979,10 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) | |||
| 979 | priv->tx_dma_use = 1; | 979 | priv->tx_dma_use = 1; |
| 980 | 980 | ||
| 981 | priv->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); | 981 | priv->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); |
| 982 | if (!priv->sg_tx_p) { | ||
| 983 | dev_err(priv->port.dev, "%s:kzalloc Failed\n", __func__); | ||
| 984 | return 0; | ||
| 985 | } | ||
| 982 | 986 | ||
| 983 | sg_init_table(priv->sg_tx_p, num); /* Initialize SG table */ | 987 | sg_init_table(priv->sg_tx_p, num); /* Initialize SG table */ |
| 984 | sg = priv->sg_tx_p; | 988 | sg = priv->sg_tx_p; |
diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 5847a4b855f7..9033fc6e0e4e 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c | |||
| @@ -670,9 +670,19 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
| 670 | { | 670 | { |
| 671 | struct uart_pxa_port *up = serial_pxa_ports[co->index]; | 671 | struct uart_pxa_port *up = serial_pxa_ports[co->index]; |
| 672 | unsigned int ier; | 672 | unsigned int ier; |
| 673 | unsigned long flags; | ||
| 674 | int locked = 1; | ||
| 673 | 675 | ||
| 674 | clk_prepare_enable(up->clk); | 676 | clk_prepare_enable(up->clk); |
| 675 | 677 | ||
| 678 | local_irq_save(flags); | ||
| 679 | if (up->port.sysrq) | ||
| 680 | locked = 0; | ||
| 681 | else if (oops_in_progress) | ||
| 682 | locked = spin_trylock(&up->port.lock); | ||
| 683 | else | ||
| 684 | spin_lock(&up->port.lock); | ||
| 685 | |||
| 676 | /* | 686 | /* |
| 677 | * First save the IER then disable the interrupts | 687 | * First save the IER then disable the interrupts |
| 678 | */ | 688 | */ |
| @@ -688,6 +698,10 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
| 688 | wait_for_xmitr(up); | 698 | wait_for_xmitr(up); |
| 689 | serial_out(up, UART_IER, ier); | 699 | serial_out(up, UART_IER, ier); |
| 690 | 700 | ||
| 701 | if (locked) | ||
| 702 | spin_unlock(&up->port.lock); | ||
| 703 | local_irq_restore(flags); | ||
| 704 | |||
| 691 | clk_disable_unprepare(up->clk); | 705 | clk_disable_unprepare(up->clk); |
| 692 | } | 706 | } |
| 693 | 707 | ||
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 02d07bfcfa8a..7f04717176aa 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
| @@ -82,7 +82,7 @@ static inline const char *s3c24xx_serial_portname(struct uart_port *port) | |||
| 82 | 82 | ||
| 83 | static int s3c24xx_serial_txempty_nofifo(struct uart_port *port) | 83 | static int s3c24xx_serial_txempty_nofifo(struct uart_port *port) |
| 84 | { | 84 | { |
| 85 | return (rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE); | 85 | return rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | /* | 88 | /* |
| @@ -268,7 +268,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) | |||
| 268 | dbg("break!\n"); | 268 | dbg("break!\n"); |
| 269 | port->icount.brk++; | 269 | port->icount.brk++; |
| 270 | if (uart_handle_break(port)) | 270 | if (uart_handle_break(port)) |
| 271 | goto ignore_char; | 271 | goto ignore_char; |
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | if (uerstat & S3C2410_UERSTAT_FRAME) | 274 | if (uerstat & S3C2410_UERSTAT_FRAME) |
| @@ -459,7 +459,7 @@ static int s3c24xx_serial_startup(struct uart_port *port) | |||
| 459 | s3c24xx_serial_portname(port), ourport); | 459 | s3c24xx_serial_portname(port), ourport); |
| 460 | 460 | ||
| 461 | if (ret != 0) { | 461 | if (ret != 0) { |
| 462 | printk(KERN_ERR "cannot get irq %d\n", ourport->rx_irq); | 462 | dev_err(port->dev, "cannot get irq %d\n", ourport->rx_irq); |
| 463 | return ret; | 463 | return ret; |
| 464 | } | 464 | } |
| 465 | 465 | ||
| @@ -473,7 +473,7 @@ static int s3c24xx_serial_startup(struct uart_port *port) | |||
| 473 | s3c24xx_serial_portname(port), ourport); | 473 | s3c24xx_serial_portname(port), ourport); |
| 474 | 474 | ||
| 475 | if (ret) { | 475 | if (ret) { |
| 476 | printk(KERN_ERR "cannot get irq %d\n", ourport->tx_irq); | 476 | dev_err(port->dev, "cannot get irq %d\n", ourport->tx_irq); |
| 477 | goto err; | 477 | goto err; |
| 478 | } | 478 | } |
| 479 | 479 | ||
| @@ -502,7 +502,7 @@ static int s3c64xx_serial_startup(struct uart_port *port) | |||
| 502 | ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED, | 502 | ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED, |
| 503 | s3c24xx_serial_portname(port), ourport); | 503 | s3c24xx_serial_portname(port), ourport); |
| 504 | if (ret) { | 504 | if (ret) { |
| 505 | printk(KERN_ERR "cannot get irq %d\n", port->irq); | 505 | dev_err(port->dev, "cannot get irq %d\n", port->irq); |
| 506 | return ret; | 506 | return ret; |
| 507 | } | 507 | } |
| 508 | 508 | ||
| @@ -529,7 +529,7 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, | |||
| 529 | 529 | ||
| 530 | switch (level) { | 530 | switch (level) { |
| 531 | case 3: | 531 | case 3: |
| 532 | if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL) | 532 | if (!IS_ERR(ourport->baudclk)) |
| 533 | clk_disable(ourport->baudclk); | 533 | clk_disable(ourport->baudclk); |
| 534 | 534 | ||
| 535 | clk_disable(ourport->clk); | 535 | clk_disable(ourport->clk); |
| @@ -538,12 +538,12 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, | |||
| 538 | case 0: | 538 | case 0: |
| 539 | clk_enable(ourport->clk); | 539 | clk_enable(ourport->clk); |
| 540 | 540 | ||
| 541 | if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL) | 541 | if (!IS_ERR(ourport->baudclk)) |
| 542 | clk_enable(ourport->baudclk); | 542 | clk_enable(ourport->baudclk); |
| 543 | 543 | ||
| 544 | break; | 544 | break; |
| 545 | default: | 545 | default: |
| 546 | printk(KERN_ERR "s3c24xx_serial: unknown pm %d\n", level); | 546 | dev_err(port->dev, "s3c24xx_serial: unknown pm %d\n", level); |
| 547 | } | 547 | } |
| 548 | } | 548 | } |
| 549 | 549 | ||
| @@ -604,7 +604,6 @@ static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport, | |||
| 604 | char clkname[MAX_CLK_NAME_LENGTH]; | 604 | char clkname[MAX_CLK_NAME_LENGTH]; |
| 605 | int calc_deviation, deviation = (1 << 30) - 1; | 605 | int calc_deviation, deviation = (1 << 30) - 1; |
| 606 | 606 | ||
| 607 | *best_clk = NULL; | ||
| 608 | clk_sel = (ourport->cfg->clk_sel) ? ourport->cfg->clk_sel : | 607 | clk_sel = (ourport->cfg->clk_sel) ? ourport->cfg->clk_sel : |
| 609 | ourport->info->def_clk_sel; | 608 | ourport->info->def_clk_sel; |
| 610 | for (cnt = 0; cnt < info->num_clks; cnt++) { | 609 | for (cnt = 0; cnt < info->num_clks; cnt++) { |
| @@ -613,7 +612,7 @@ static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport, | |||
| 613 | 612 | ||
| 614 | sprintf(clkname, "clk_uart_baud%d", cnt); | 613 | sprintf(clkname, "clk_uart_baud%d", cnt); |
| 615 | clk = clk_get(ourport->port.dev, clkname); | 614 | clk = clk_get(ourport->port.dev, clkname); |
| 616 | if (IS_ERR_OR_NULL(clk)) | 615 | if (IS_ERR(clk)) |
| 617 | continue; | 616 | continue; |
| 618 | 617 | ||
| 619 | rate = clk_get_rate(clk); | 618 | rate = clk_get_rate(clk); |
| @@ -684,7 +683,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, | |||
| 684 | { | 683 | { |
| 685 | struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); | 684 | struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); |
| 686 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 685 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
| 687 | struct clk *clk = NULL; | 686 | struct clk *clk = ERR_PTR(-EINVAL); |
| 688 | unsigned long flags; | 687 | unsigned long flags; |
| 689 | unsigned int baud, quot, clk_sel = 0; | 688 | unsigned int baud, quot, clk_sel = 0; |
| 690 | unsigned int ulcon; | 689 | unsigned int ulcon; |
| @@ -705,7 +704,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, | |||
| 705 | quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel); | 704 | quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel); |
| 706 | if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) | 705 | if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) |
| 707 | quot = port->custom_divisor; | 706 | quot = port->custom_divisor; |
| 708 | if (!clk) | 707 | if (IS_ERR(clk)) |
| 709 | return; | 708 | return; |
| 710 | 709 | ||
| 711 | /* check to see if we need to change clock source */ | 710 | /* check to see if we need to change clock source */ |
| @@ -713,9 +712,9 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, | |||
| 713 | if (ourport->baudclk != clk) { | 712 | if (ourport->baudclk != clk) { |
| 714 | s3c24xx_serial_setsource(port, clk_sel); | 713 | s3c24xx_serial_setsource(port, clk_sel); |
| 715 | 714 | ||
| 716 | if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) { | 715 | if (!IS_ERR(ourport->baudclk)) { |
| 717 | clk_disable(ourport->baudclk); | 716 | clk_disable(ourport->baudclk); |
| 718 | ourport->baudclk = NULL; | 717 | ourport->baudclk = ERR_PTR(-EINVAL); |
| 719 | } | 718 | } |
| 720 | 719 | ||
| 721 | clk_enable(clk); | 720 | clk_enable(clk); |
| @@ -877,11 +876,24 @@ s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
| 877 | 876 | ||
| 878 | static struct console s3c24xx_serial_console; | 877 | static struct console s3c24xx_serial_console; |
| 879 | 878 | ||
| 879 | static int __init s3c24xx_serial_console_init(void) | ||
| 880 | { | ||
| 881 | register_console(&s3c24xx_serial_console); | ||
| 882 | return 0; | ||
| 883 | } | ||
| 884 | console_initcall(s3c24xx_serial_console_init); | ||
| 885 | |||
| 880 | #define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console | 886 | #define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console |
| 881 | #else | 887 | #else |
| 882 | #define S3C24XX_SERIAL_CONSOLE NULL | 888 | #define S3C24XX_SERIAL_CONSOLE NULL |
| 883 | #endif | 889 | #endif |
| 884 | 890 | ||
| 891 | #ifdef CONFIG_CONSOLE_POLL | ||
| 892 | static int s3c24xx_serial_get_poll_char(struct uart_port *port); | ||
| 893 | static void s3c24xx_serial_put_poll_char(struct uart_port *port, | ||
| 894 | unsigned char c); | ||
| 895 | #endif | ||
| 896 | |||
| 885 | static struct uart_ops s3c24xx_serial_ops = { | 897 | static struct uart_ops s3c24xx_serial_ops = { |
| 886 | .pm = s3c24xx_serial_pm, | 898 | .pm = s3c24xx_serial_pm, |
| 887 | .tx_empty = s3c24xx_serial_tx_empty, | 899 | .tx_empty = s3c24xx_serial_tx_empty, |
| @@ -900,6 +912,10 @@ static struct uart_ops s3c24xx_serial_ops = { | |||
| 900 | .request_port = s3c24xx_serial_request_port, | 912 | .request_port = s3c24xx_serial_request_port, |
| 901 | .config_port = s3c24xx_serial_config_port, | 913 | .config_port = s3c24xx_serial_config_port, |
| 902 | .verify_port = s3c24xx_serial_verify_port, | 914 | .verify_port = s3c24xx_serial_verify_port, |
| 915 | #ifdef CONFIG_CONSOLE_POLL | ||
| 916 | .poll_get_char = s3c24xx_serial_get_poll_char, | ||
| 917 | .poll_put_char = s3c24xx_serial_put_poll_char, | ||
| 918 | #endif | ||
| 903 | }; | 919 | }; |
| 904 | 920 | ||
| 905 | static struct uart_driver s3c24xx_uart_drv = { | 921 | static struct uart_driver s3c24xx_uart_drv = { |
| @@ -1036,10 +1052,10 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, | |||
| 1036 | if (tty == NULL) | 1052 | if (tty == NULL) |
| 1037 | goto exit; | 1053 | goto exit; |
| 1038 | 1054 | ||
| 1039 | termios = tty->termios; | 1055 | termios = &tty->termios; |
| 1040 | 1056 | ||
| 1041 | if (termios == NULL) { | 1057 | if (termios == NULL) { |
| 1042 | printk(KERN_WARNING "%s: no termios?\n", __func__); | 1058 | dev_warn(uport->dev, "%s: no termios?\n", __func__); |
| 1043 | goto exit; | 1059 | goto exit; |
| 1044 | } | 1060 | } |
| 1045 | 1061 | ||
| @@ -1114,7 +1130,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
| 1114 | 1130 | ||
| 1115 | res = platform_get_resource(platdev, IORESOURCE_MEM, 0); | 1131 | res = platform_get_resource(platdev, IORESOURCE_MEM, 0); |
| 1116 | if (res == NULL) { | 1132 | if (res == NULL) { |
| 1117 | printk(KERN_ERR "failed to find memory resource for uart\n"); | 1133 | dev_err(port->dev, "failed to find memory resource for uart\n"); |
| 1118 | return -EINVAL; | 1134 | return -EINVAL; |
| 1119 | } | 1135 | } |
| 1120 | 1136 | ||
| @@ -1130,7 +1146,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
| 1130 | ourport->rx_irq = ret; | 1146 | ourport->rx_irq = ret; |
| 1131 | ourport->tx_irq = ret + 1; | 1147 | ourport->tx_irq = ret + 1; |
| 1132 | } | 1148 | } |
| 1133 | 1149 | ||
| 1134 | ret = platform_get_irq(platdev, 1); | 1150 | ret = platform_get_irq(platdev, 1); |
| 1135 | if (ret > 0) | 1151 | if (ret > 0) |
| 1136 | ourport->tx_irq = ret; | 1152 | ourport->tx_irq = ret; |
| @@ -1160,7 +1176,11 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev, | |||
| 1160 | struct uart_port *port = s3c24xx_dev_to_port(dev); | 1176 | struct uart_port *port = s3c24xx_dev_to_port(dev); |
| 1161 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 1177 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
| 1162 | 1178 | ||
| 1163 | return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->baudclk->name); | 1179 | if (IS_ERR(ourport->baudclk)) |
| 1180 | return -EINVAL; | ||
| 1181 | |||
| 1182 | return snprintf(buf, PAGE_SIZE, "* %s\n", | ||
| 1183 | ourport->baudclk->name ?: "(null)"); | ||
| 1164 | } | 1184 | } |
| 1165 | 1185 | ||
| 1166 | static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); | 1186 | static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); |
| @@ -1200,6 +1220,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) | |||
| 1200 | return -ENODEV; | 1220 | return -ENODEV; |
| 1201 | } | 1221 | } |
| 1202 | 1222 | ||
| 1223 | ourport->baudclk = ERR_PTR(-EINVAL); | ||
| 1203 | ourport->info = ourport->drv_data->info; | 1224 | ourport->info = ourport->drv_data->info; |
| 1204 | ourport->cfg = (pdev->dev.platform_data) ? | 1225 | ourport->cfg = (pdev->dev.platform_data) ? |
| 1205 | (struct s3c2410_uartcfg *)pdev->dev.platform_data : | 1226 | (struct s3c2410_uartcfg *)pdev->dev.platform_data : |
| @@ -1312,6 +1333,36 @@ s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon) | |||
| 1312 | return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0; | 1333 | return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0; |
| 1313 | } | 1334 | } |
| 1314 | 1335 | ||
| 1336 | #ifdef CONFIG_CONSOLE_POLL | ||
| 1337 | /* | ||
| 1338 | * Console polling routines for writing and reading from the uart while | ||
| 1339 | * in an interrupt or debug context. | ||
| 1340 | */ | ||
| 1341 | |||
| 1342 | static int s3c24xx_serial_get_poll_char(struct uart_port *port) | ||
| 1343 | { | ||
| 1344 | struct s3c24xx_uart_port *ourport = to_ourport(port); | ||
| 1345 | unsigned int ufstat; | ||
| 1346 | |||
| 1347 | ufstat = rd_regl(port, S3C2410_UFSTAT); | ||
| 1348 | if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) | ||
| 1349 | return NO_POLL_CHAR; | ||
| 1350 | |||
| 1351 | return rd_regb(port, S3C2410_URXH); | ||
| 1352 | } | ||
| 1353 | |||
| 1354 | static void s3c24xx_serial_put_poll_char(struct uart_port *port, | ||
| 1355 | unsigned char c) | ||
| 1356 | { | ||
| 1357 | unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); | ||
| 1358 | |||
| 1359 | while (!s3c24xx_serial_console_txrdy(port, ufcon)) | ||
| 1360 | cpu_relax(); | ||
| 1361 | wr_regb(cons_uart, S3C2410_UTXH, c); | ||
| 1362 | } | ||
| 1363 | |||
| 1364 | #endif /* CONFIG_CONSOLE_POLL */ | ||
| 1365 | |||
| 1315 | static void | 1366 | static void |
| 1316 | s3c24xx_serial_console_putchar(struct uart_port *port, int ch) | 1367 | s3c24xx_serial_console_putchar(struct uart_port *port, int ch) |
| 1317 | { | 1368 | { |
| @@ -1387,7 +1438,7 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud, | |||
| 1387 | sprintf(clk_name, "clk_uart_baud%d", clk_sel); | 1438 | sprintf(clk_name, "clk_uart_baud%d", clk_sel); |
| 1388 | 1439 | ||
| 1389 | clk = clk_get(port->dev, clk_name); | 1440 | clk = clk_get(port->dev, clk_name); |
| 1390 | if (!IS_ERR(clk) && clk != NULL) | 1441 | if (!IS_ERR(clk)) |
| 1391 | rate = clk_get_rate(clk); | 1442 | rate = clk_get_rate(clk); |
| 1392 | else | 1443 | else |
| 1393 | rate = 1; | 1444 | rate = 1; |
| @@ -1679,8 +1730,8 @@ static int __init s3c24xx_serial_modinit(void) | |||
| 1679 | 1730 | ||
| 1680 | ret = uart_register_driver(&s3c24xx_uart_drv); | 1731 | ret = uart_register_driver(&s3c24xx_uart_drv); |
| 1681 | if (ret < 0) { | 1732 | if (ret < 0) { |
| 1682 | printk(KERN_ERR "failed to register UART driver\n"); | 1733 | pr_err("Failed to register Samsung UART driver\n"); |
| 1683 | return -1; | 1734 | return ret; |
| 1684 | } | 1735 | } |
| 1685 | 1736 | ||
| 1686 | return platform_driver_register(&samsung_serial_driver); | 1737 | return platform_driver_register(&samsung_serial_driver); |
diff --git a/drivers/tty/serial/sc26xx.c b/drivers/tty/serial/sc26xx.c index e0b4b0a30a5a..9d664242b312 100644 --- a/drivers/tty/serial/sc26xx.c +++ b/drivers/tty/serial/sc26xx.c | |||
| @@ -20,6 +20,10 @@ | |||
| 20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
| 23 | #include <linux/io.h> | ||
| 24 | |||
| 25 | #warning "Please try migrate to use new driver SCCNXP and report the status" \ | ||
| 26 | "in the linux-serial mailing list." | ||
| 23 | 27 | ||
| 24 | #if defined(CONFIG_MAGIC_SYSRQ) | 28 | #if defined(CONFIG_MAGIC_SYSRQ) |
| 25 | #define SUPPORT_SYSRQ | 29 | #define SUPPORT_SYSRQ |
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c new file mode 100644 index 000000000000..b7086d004f5f --- /dev/null +++ b/drivers/tty/serial/sccnxp.c | |||
| @@ -0,0 +1,990 @@ | |||
| 1 | /* | ||
| 2 | * NXP (Philips) SCC+++(SCN+++) serial driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> | ||
| 5 | * | ||
| 6 | * Based on sc26xx.c, by Thomas Bogendörfer (tsbogend@alpha.franken.de) | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #if defined(CONFIG_SERIAL_SCCNXP_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
| 15 | #define SUPPORT_SYSRQ | ||
| 16 | #endif | ||
| 17 | |||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/device.h> | ||
| 20 | #include <linux/console.h> | ||
| 21 | #include <linux/serial_core.h> | ||
| 22 | #include <linux/serial.h> | ||
| 23 | #include <linux/io.h> | ||
| 24 | #include <linux/tty.h> | ||
| 25 | #include <linux/tty_flip.h> | ||
| 26 | #include <linux/platform_device.h> | ||
| 27 | #include <linux/platform_data/sccnxp.h> | ||
| 28 | |||
| 29 | #define SCCNXP_NAME "uart-sccnxp" | ||
| 30 | #define SCCNXP_MAJOR 204 | ||
| 31 | #define SCCNXP_MINOR 205 | ||
| 32 | |||
| 33 | #define SCCNXP_MR_REG (0x00) | ||
| 34 | # define MR0_BAUD_NORMAL (0 << 0) | ||
| 35 | # define MR0_BAUD_EXT1 (1 << 0) | ||
| 36 | # define MR0_BAUD_EXT2 (5 << 0) | ||
| 37 | # define MR0_FIFO (1 << 3) | ||
| 38 | # define MR0_TXLVL (1 << 4) | ||
| 39 | # define MR1_BITS_5 (0 << 0) | ||
| 40 | # define MR1_BITS_6 (1 << 0) | ||
| 41 | # define MR1_BITS_7 (2 << 0) | ||
| 42 | # define MR1_BITS_8 (3 << 0) | ||
| 43 | # define MR1_PAR_EVN (0 << 2) | ||
| 44 | # define MR1_PAR_ODD (1 << 2) | ||
| 45 | # define MR1_PAR_NO (4 << 2) | ||
| 46 | # define MR2_STOP1 (7 << 0) | ||
| 47 | # define MR2_STOP2 (0xf << 0) | ||
| 48 | #define SCCNXP_SR_REG (0x01) | ||
| 49 | #define SCCNXP_CSR_REG SCCNXP_SR_REG | ||
| 50 | # define SR_RXRDY (1 << 0) | ||
| 51 | # define SR_FULL (1 << 1) | ||
| 52 | # define SR_TXRDY (1 << 2) | ||
| 53 | # define SR_TXEMT (1 << 3) | ||
| 54 | # define SR_OVR (1 << 4) | ||
| 55 | # define SR_PE (1 << 5) | ||
| 56 | # define SR_FE (1 << 6) | ||
| 57 | # define SR_BRK (1 << 7) | ||
| 58 | #define SCCNXP_CR_REG (0x02) | ||
| 59 | # define CR_RX_ENABLE (1 << 0) | ||
| 60 | # define CR_RX_DISABLE (1 << 1) | ||
| 61 | # define CR_TX_ENABLE (1 << 2) | ||
| 62 | # define CR_TX_DISABLE (1 << 3) | ||
| 63 | # define CR_CMD_MRPTR1 (0x01 << 4) | ||
| 64 | # define CR_CMD_RX_RESET (0x02 << 4) | ||
| 65 | # define CR_CMD_TX_RESET (0x03 << 4) | ||
| 66 | # define CR_CMD_STATUS_RESET (0x04 << 4) | ||
| 67 | # define CR_CMD_BREAK_RESET (0x05 << 4) | ||
| 68 | # define CR_CMD_START_BREAK (0x06 << 4) | ||
| 69 | # define CR_CMD_STOP_BREAK (0x07 << 4) | ||
| 70 | # define CR_CMD_MRPTR0 (0x0b << 4) | ||
| 71 | #define SCCNXP_RHR_REG (0x03) | ||
| 72 | #define SCCNXP_THR_REG SCCNXP_RHR_REG | ||
| 73 | #define SCCNXP_IPCR_REG (0x04) | ||
| 74 | #define SCCNXP_ACR_REG SCCNXP_IPCR_REG | ||
| 75 | # define ACR_BAUD0 (0 << 7) | ||
| 76 | # define ACR_BAUD1 (1 << 7) | ||
| 77 | # define ACR_TIMER_MODE (6 << 4) | ||
| 78 | #define SCCNXP_ISR_REG (0x05) | ||
| 79 | #define SCCNXP_IMR_REG SCCNXP_ISR_REG | ||
| 80 | # define IMR_TXRDY (1 << 0) | ||
| 81 | # define IMR_RXRDY (1 << 1) | ||
| 82 | # define ISR_TXRDY(x) (1 << ((x * 4) + 0)) | ||
| 83 | # define ISR_RXRDY(x) (1 << ((x * 4) + 1)) | ||
| 84 | #define SCCNXP_IPR_REG (0x0d) | ||
| 85 | #define SCCNXP_OPCR_REG SCCNXP_IPR_REG | ||
| 86 | #define SCCNXP_SOP_REG (0x0e) | ||
| 87 | #define SCCNXP_ROP_REG (0x0f) | ||
| 88 | |||
| 89 | /* Route helpers */ | ||
| 90 | #define MCTRL_MASK(sig) (0xf << (sig)) | ||
| 91 | #define MCTRL_IBIT(cfg, sig) ((((cfg) >> (sig)) & 0xf) - LINE_IP0) | ||
| 92 | #define MCTRL_OBIT(cfg, sig) ((((cfg) >> (sig)) & 0xf) - LINE_OP0) | ||
| 93 | |||
| 94 | /* Supported chip types */ | ||
| 95 | enum { | ||
| 96 | SCCNXP_TYPE_SC2681 = 2681, | ||
| 97 | SCCNXP_TYPE_SC2691 = 2691, | ||
| 98 | SCCNXP_TYPE_SC2692 = 2692, | ||
| 99 | SCCNXP_TYPE_SC2891 = 2891, | ||
| 100 | SCCNXP_TYPE_SC2892 = 2892, | ||
| 101 | SCCNXP_TYPE_SC28202 = 28202, | ||
| 102 | SCCNXP_TYPE_SC68681 = 68681, | ||
| 103 | SCCNXP_TYPE_SC68692 = 68692, | ||
| 104 | }; | ||
| 105 | |||
| 106 | struct sccnxp_port { | ||
| 107 | struct uart_driver uart; | ||
| 108 | struct uart_port port[SCCNXP_MAX_UARTS]; | ||
| 109 | |||
| 110 | const char *name; | ||
| 111 | int irq; | ||
| 112 | |||
| 113 | u8 imr; | ||
| 114 | u8 addr_mask; | ||
| 115 | int freq_std; | ||
| 116 | |||
| 117 | int flags; | ||
| 118 | #define SCCNXP_HAVE_IO 0x00000001 | ||
| 119 | #define SCCNXP_HAVE_MR0 0x00000002 | ||
| 120 | |||
| 121 | #ifdef CONFIG_SERIAL_SCCNXP_CONSOLE | ||
| 122 | struct console console; | ||
| 123 | #endif | ||
| 124 | |||
| 125 | struct mutex sccnxp_mutex; | ||
| 126 | |||
| 127 | struct sccnxp_pdata pdata; | ||
| 128 | }; | ||
| 129 | |||
| 130 | static inline u8 sccnxp_raw_read(void __iomem *base, u8 reg, u8 shift) | ||
| 131 | { | ||
| 132 | return readb(base + (reg << shift)); | ||
| 133 | } | ||
| 134 | |||
| 135 | static inline void sccnxp_raw_write(void __iomem *base, u8 reg, u8 shift, u8 v) | ||
| 136 | { | ||
| 137 | writeb(v, base + (reg << shift)); | ||
| 138 | } | ||
| 139 | |||
| 140 | static inline u8 sccnxp_read(struct uart_port *port, u8 reg) | ||
| 141 | { | ||
| 142 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 143 | |||
| 144 | return sccnxp_raw_read(port->membase, reg & s->addr_mask, | ||
| 145 | port->regshift); | ||
| 146 | } | ||
| 147 | |||
| 148 | static inline void sccnxp_write(struct uart_port *port, u8 reg, u8 v) | ||
| 149 | { | ||
| 150 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 151 | |||
| 152 | sccnxp_raw_write(port->membase, reg & s->addr_mask, port->regshift, v); | ||
| 153 | } | ||
| 154 | |||
| 155 | static inline u8 sccnxp_port_read(struct uart_port *port, u8 reg) | ||
| 156 | { | ||
| 157 | return sccnxp_read(port, (port->line << 3) + reg); | ||
| 158 | } | ||
| 159 | |||
| 160 | static inline void sccnxp_port_write(struct uart_port *port, u8 reg, u8 v) | ||
| 161 | { | ||
| 162 | sccnxp_write(port, (port->line << 3) + reg, v); | ||
| 163 | } | ||
| 164 | |||
| 165 | static int sccnxp_update_best_err(int a, int b, int *besterr) | ||
| 166 | { | ||
| 167 | int err = abs(a - b); | ||
| 168 | |||
| 169 | if ((*besterr < 0) || (*besterr > err)) { | ||
| 170 | *besterr = err; | ||
| 171 | return 0; | ||
| 172 | } | ||
| 173 | |||
| 174 | return 1; | ||
| 175 | } | ||
| 176 | |||
| 177 | struct baud_table { | ||
| 178 | u8 csr; | ||
| 179 | u8 acr; | ||
| 180 | u8 mr0; | ||
| 181 | int baud; | ||
| 182 | }; | ||
| 183 | |||
| 184 | const struct baud_table baud_std[] = { | ||
| 185 | { 0, ACR_BAUD0, MR0_BAUD_NORMAL, 50, }, | ||
| 186 | { 0, ACR_BAUD1, MR0_BAUD_NORMAL, 75, }, | ||
| 187 | { 1, ACR_BAUD0, MR0_BAUD_NORMAL, 110, }, | ||
| 188 | { 2, ACR_BAUD0, MR0_BAUD_NORMAL, 134, }, | ||
| 189 | { 3, ACR_BAUD1, MR0_BAUD_NORMAL, 150, }, | ||
| 190 | { 3, ACR_BAUD0, MR0_BAUD_NORMAL, 200, }, | ||
| 191 | { 4, ACR_BAUD0, MR0_BAUD_NORMAL, 300, }, | ||
| 192 | { 0, ACR_BAUD1, MR0_BAUD_EXT1, 450, }, | ||
| 193 | { 1, ACR_BAUD0, MR0_BAUD_EXT2, 880, }, | ||
| 194 | { 3, ACR_BAUD1, MR0_BAUD_EXT1, 900, }, | ||
| 195 | { 5, ACR_BAUD0, MR0_BAUD_NORMAL, 600, }, | ||
| 196 | { 7, ACR_BAUD0, MR0_BAUD_NORMAL, 1050, }, | ||
| 197 | { 2, ACR_BAUD0, MR0_BAUD_EXT2, 1076, }, | ||
| 198 | { 6, ACR_BAUD0, MR0_BAUD_NORMAL, 1200, }, | ||
| 199 | { 10, ACR_BAUD1, MR0_BAUD_NORMAL, 1800, }, | ||
| 200 | { 7, ACR_BAUD1, MR0_BAUD_NORMAL, 2000, }, | ||
| 201 | { 8, ACR_BAUD0, MR0_BAUD_NORMAL, 2400, }, | ||
| 202 | { 5, ACR_BAUD1, MR0_BAUD_EXT1, 3600, }, | ||
| 203 | { 9, ACR_BAUD0, MR0_BAUD_NORMAL, 4800, }, | ||
| 204 | { 10, ACR_BAUD0, MR0_BAUD_NORMAL, 7200, }, | ||
| 205 | { 11, ACR_BAUD0, MR0_BAUD_NORMAL, 9600, }, | ||
| 206 | { 8, ACR_BAUD0, MR0_BAUD_EXT1, 14400, }, | ||
| 207 | { 12, ACR_BAUD1, MR0_BAUD_NORMAL, 19200, }, | ||
| 208 | { 9, ACR_BAUD0, MR0_BAUD_EXT1, 28800, }, | ||
| 209 | { 12, ACR_BAUD0, MR0_BAUD_NORMAL, 38400, }, | ||
| 210 | { 11, ACR_BAUD0, MR0_BAUD_EXT1, 57600, }, | ||
| 211 | { 12, ACR_BAUD1, MR0_BAUD_EXT1, 115200, }, | ||
| 212 | { 12, ACR_BAUD0, MR0_BAUD_EXT1, 230400, }, | ||
| 213 | { 0, 0, 0, 0 } | ||
| 214 | }; | ||
| 215 | |||
| 216 | static int sccnxp_set_baud(struct uart_port *port, int baud) | ||
| 217 | { | ||
| 218 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 219 | int div_std, tmp_baud, bestbaud = baud, besterr = -1; | ||
| 220 | u8 i, acr = 0, csr = 0, mr0 = 0; | ||
| 221 | |||
| 222 | /* Find best baud from table */ | ||
| 223 | for (i = 0; baud_std[i].baud && besterr; i++) { | ||
| 224 | if (baud_std[i].mr0 && !(s->flags & SCCNXP_HAVE_MR0)) | ||
| 225 | continue; | ||
| 226 | div_std = DIV_ROUND_CLOSEST(s->freq_std, baud_std[i].baud); | ||
| 227 | tmp_baud = DIV_ROUND_CLOSEST(port->uartclk, div_std); | ||
| 228 | if (!sccnxp_update_best_err(baud, tmp_baud, &besterr)) { | ||
| 229 | acr = baud_std[i].acr; | ||
| 230 | csr = baud_std[i].csr; | ||
| 231 | mr0 = baud_std[i].mr0; | ||
| 232 | bestbaud = tmp_baud; | ||
| 233 | } | ||
| 234 | } | ||
| 235 | |||
| 236 | if (s->flags & SCCNXP_HAVE_MR0) { | ||
| 237 | /* Enable FIFO, set half level for TX */ | ||
| 238 | mr0 |= MR0_FIFO | MR0_TXLVL; | ||
| 239 | /* Update MR0 */ | ||
| 240 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_MRPTR0); | ||
| 241 | sccnxp_port_write(port, SCCNXP_MR_REG, mr0); | ||
| 242 | } | ||
| 243 | |||
| 244 | sccnxp_port_write(port, SCCNXP_ACR_REG, acr | ACR_TIMER_MODE); | ||
| 245 | sccnxp_port_write(port, SCCNXP_CSR_REG, (csr << 4) | csr); | ||
| 246 | |||
| 247 | if (baud != bestbaud) | ||
| 248 | dev_dbg(port->dev, "Baudrate desired: %i, calculated: %i\n", | ||
| 249 | baud, bestbaud); | ||
| 250 | |||
| 251 | return bestbaud; | ||
| 252 | } | ||
| 253 | |||
| 254 | static void sccnxp_enable_irq(struct uart_port *port, int mask) | ||
| 255 | { | ||
| 256 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 257 | |||
| 258 | s->imr |= mask << (port->line * 4); | ||
| 259 | sccnxp_write(port, SCCNXP_IMR_REG, s->imr); | ||
| 260 | } | ||
| 261 | |||
| 262 | static void sccnxp_disable_irq(struct uart_port *port, int mask) | ||
| 263 | { | ||
| 264 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 265 | |||
| 266 | s->imr &= ~(mask << (port->line * 4)); | ||
| 267 | sccnxp_write(port, SCCNXP_IMR_REG, s->imr); | ||
| 268 | } | ||
| 269 | |||
| 270 | static void sccnxp_set_bit(struct uart_port *port, int sig, int state) | ||
| 271 | { | ||
| 272 | u8 bitmask; | ||
| 273 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 274 | |||
| 275 | if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(sig)) { | ||
| 276 | bitmask = 1 << MCTRL_OBIT(s->pdata.mctrl_cfg[port->line], sig); | ||
| 277 | if (state) | ||
| 278 | sccnxp_write(port, SCCNXP_SOP_REG, bitmask); | ||
| 279 | else | ||
| 280 | sccnxp_write(port, SCCNXP_ROP_REG, bitmask); | ||
| 281 | } | ||
| 282 | } | ||
| 283 | |||
| 284 | static void sccnxp_handle_rx(struct uart_port *port) | ||
| 285 | { | ||
| 286 | u8 sr; | ||
| 287 | unsigned int ch, flag; | ||
| 288 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
| 289 | |||
| 290 | if (!tty) | ||
| 291 | return; | ||
| 292 | |||
| 293 | for (;;) { | ||
| 294 | sr = sccnxp_port_read(port, SCCNXP_SR_REG); | ||
| 295 | if (!(sr & SR_RXRDY)) | ||
| 296 | break; | ||
| 297 | sr &= SR_PE | SR_FE | SR_OVR | SR_BRK; | ||
| 298 | |||
| 299 | ch = sccnxp_port_read(port, SCCNXP_RHR_REG); | ||
| 300 | |||
| 301 | port->icount.rx++; | ||
| 302 | flag = TTY_NORMAL; | ||
| 303 | |||
| 304 | if (unlikely(sr)) { | ||
| 305 | if (sr & SR_BRK) { | ||
| 306 | port->icount.brk++; | ||
| 307 | if (uart_handle_break(port)) | ||
| 308 | continue; | ||
| 309 | } else if (sr & SR_PE) | ||
| 310 | port->icount.parity++; | ||
| 311 | else if (sr & SR_FE) | ||
| 312 | port->icount.frame++; | ||
| 313 | else if (sr & SR_OVR) | ||
| 314 | port->icount.overrun++; | ||
| 315 | |||
| 316 | sr &= port->read_status_mask; | ||
| 317 | if (sr & SR_BRK) | ||
| 318 | flag = TTY_BREAK; | ||
| 319 | else if (sr & SR_PE) | ||
| 320 | flag = TTY_PARITY; | ||
| 321 | else if (sr & SR_FE) | ||
| 322 | flag = TTY_FRAME; | ||
| 323 | else if (sr & SR_OVR) | ||
| 324 | flag = TTY_OVERRUN; | ||
| 325 | } | ||
| 326 | |||
| 327 | if (uart_handle_sysrq_char(port, ch)) | ||
| 328 | continue; | ||
| 329 | |||
| 330 | if (sr & port->ignore_status_mask) | ||
| 331 | continue; | ||
| 332 | |||
| 333 | uart_insert_char(port, sr, SR_OVR, ch, flag); | ||
| 334 | } | ||
| 335 | |||
| 336 | tty_flip_buffer_push(tty); | ||
| 337 | |||
| 338 | tty_kref_put(tty); | ||
| 339 | } | ||
| 340 | |||
| 341 | static void sccnxp_handle_tx(struct uart_port *port) | ||
| 342 | { | ||
| 343 | u8 sr; | ||
| 344 | struct circ_buf *xmit = &port->state->xmit; | ||
| 345 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 346 | |||
| 347 | if (unlikely(port->x_char)) { | ||
| 348 | sccnxp_port_write(port, SCCNXP_THR_REG, port->x_char); | ||
| 349 | port->icount.tx++; | ||
| 350 | port->x_char = 0; | ||
| 351 | return; | ||
| 352 | } | ||
| 353 | |||
| 354 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | ||
| 355 | /* Disable TX if FIFO is empty */ | ||
| 356 | if (sccnxp_port_read(port, SCCNXP_SR_REG) & SR_TXEMT) { | ||
| 357 | sccnxp_disable_irq(port, IMR_TXRDY); | ||
| 358 | |||
| 359 | /* Set direction to input */ | ||
| 360 | if (s->flags & SCCNXP_HAVE_IO) | ||
| 361 | sccnxp_set_bit(port, DIR_OP, 0); | ||
| 362 | } | ||
| 363 | return; | ||
| 364 | } | ||
| 365 | |||
| 366 | while (!uart_circ_empty(xmit)) { | ||
| 367 | sr = sccnxp_port_read(port, SCCNXP_SR_REG); | ||
| 368 | if (!(sr & SR_TXRDY)) | ||
| 369 | break; | ||
| 370 | |||
| 371 | sccnxp_port_write(port, SCCNXP_THR_REG, xmit->buf[xmit->tail]); | ||
| 372 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
| 373 | port->icount.tx++; | ||
| 374 | } | ||
| 375 | |||
| 376 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
| 377 | uart_write_wakeup(port); | ||
| 378 | } | ||
| 379 | |||
| 380 | static irqreturn_t sccnxp_ist(int irq, void *dev_id) | ||
| 381 | { | ||
| 382 | int i; | ||
| 383 | u8 isr; | ||
| 384 | struct sccnxp_port *s = (struct sccnxp_port *)dev_id; | ||
| 385 | |||
| 386 | mutex_lock(&s->sccnxp_mutex); | ||
| 387 | |||
| 388 | for (;;) { | ||
| 389 | isr = sccnxp_read(&s->port[0], SCCNXP_ISR_REG); | ||
| 390 | isr &= s->imr; | ||
| 391 | if (!isr) | ||
| 392 | break; | ||
| 393 | |||
| 394 | dev_dbg(s->port[0].dev, "IRQ status: 0x%02x\n", isr); | ||
| 395 | |||
| 396 | for (i = 0; i < s->uart.nr; i++) { | ||
| 397 | if (isr & ISR_RXRDY(i)) | ||
| 398 | sccnxp_handle_rx(&s->port[i]); | ||
| 399 | if (isr & ISR_TXRDY(i)) | ||
| 400 | sccnxp_handle_tx(&s->port[i]); | ||
| 401 | } | ||
| 402 | } | ||
| 403 | |||
| 404 | mutex_unlock(&s->sccnxp_mutex); | ||
| 405 | |||
| 406 | return IRQ_HANDLED; | ||
| 407 | } | ||
| 408 | |||
| 409 | static void sccnxp_start_tx(struct uart_port *port) | ||
| 410 | { | ||
| 411 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 412 | |||
| 413 | mutex_lock(&s->sccnxp_mutex); | ||
| 414 | |||
| 415 | /* Set direction to output */ | ||
| 416 | if (s->flags & SCCNXP_HAVE_IO) | ||
| 417 | sccnxp_set_bit(port, DIR_OP, 1); | ||
| 418 | |||
| 419 | sccnxp_enable_irq(port, IMR_TXRDY); | ||
| 420 | |||
| 421 | mutex_unlock(&s->sccnxp_mutex); | ||
| 422 | } | ||
| 423 | |||
| 424 | static void sccnxp_stop_tx(struct uart_port *port) | ||
| 425 | { | ||
| 426 | /* Do nothing */ | ||
| 427 | } | ||
| 428 | |||
| 429 | static void sccnxp_stop_rx(struct uart_port *port) | ||
| 430 | { | ||
| 431 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 432 | |||
| 433 | mutex_lock(&s->sccnxp_mutex); | ||
| 434 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_DISABLE); | ||
| 435 | mutex_unlock(&s->sccnxp_mutex); | ||
| 436 | } | ||
| 437 | |||
| 438 | static unsigned int sccnxp_tx_empty(struct uart_port *port) | ||
| 439 | { | ||
| 440 | u8 val; | ||
| 441 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 442 | |||
| 443 | mutex_lock(&s->sccnxp_mutex); | ||
| 444 | val = sccnxp_port_read(port, SCCNXP_SR_REG); | ||
| 445 | mutex_unlock(&s->sccnxp_mutex); | ||
| 446 | |||
| 447 | return (val & SR_TXEMT) ? TIOCSER_TEMT : 0; | ||
| 448 | } | ||
| 449 | |||
| 450 | static void sccnxp_enable_ms(struct uart_port *port) | ||
| 451 | { | ||
| 452 | /* Do nothing */ | ||
| 453 | } | ||
| 454 | |||
| 455 | static void sccnxp_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
| 456 | { | ||
| 457 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 458 | |||
| 459 | if (!(s->flags & SCCNXP_HAVE_IO)) | ||
| 460 | return; | ||
| 461 | |||
| 462 | mutex_lock(&s->sccnxp_mutex); | ||
| 463 | |||
| 464 | sccnxp_set_bit(port, DTR_OP, mctrl & TIOCM_DTR); | ||
| 465 | sccnxp_set_bit(port, RTS_OP, mctrl & TIOCM_RTS); | ||
| 466 | |||
| 467 | mutex_unlock(&s->sccnxp_mutex); | ||
| 468 | } | ||
| 469 | |||
| 470 | static unsigned int sccnxp_get_mctrl(struct uart_port *port) | ||
| 471 | { | ||
| 472 | u8 bitmask, ipr; | ||
| 473 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 474 | unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; | ||
| 475 | |||
| 476 | if (!(s->flags & SCCNXP_HAVE_IO)) | ||
| 477 | return mctrl; | ||
| 478 | |||
| 479 | mutex_lock(&s->sccnxp_mutex); | ||
| 480 | |||
| 481 | ipr = ~sccnxp_read(port, SCCNXP_IPCR_REG); | ||
| 482 | |||
| 483 | if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(DSR_IP)) { | ||
| 484 | bitmask = 1 << MCTRL_IBIT(s->pdata.mctrl_cfg[port->line], | ||
| 485 | DSR_IP); | ||
| 486 | mctrl &= ~TIOCM_DSR; | ||
| 487 | mctrl |= (ipr & bitmask) ? TIOCM_DSR : 0; | ||
| 488 | } | ||
| 489 | if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(CTS_IP)) { | ||
| 490 | bitmask = 1 << MCTRL_IBIT(s->pdata.mctrl_cfg[port->line], | ||
| 491 | CTS_IP); | ||
| 492 | mctrl &= ~TIOCM_CTS; | ||
| 493 | mctrl |= (ipr & bitmask) ? TIOCM_CTS : 0; | ||
| 494 | } | ||
| 495 | if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(DCD_IP)) { | ||
| 496 | bitmask = 1 << MCTRL_IBIT(s->pdata.mctrl_cfg[port->line], | ||
| 497 | DCD_IP); | ||
| 498 | mctrl &= ~TIOCM_CAR; | ||
| 499 | mctrl |= (ipr & bitmask) ? TIOCM_CAR : 0; | ||
| 500 | } | ||
| 501 | if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(RNG_IP)) { | ||
| 502 | bitmask = 1 << MCTRL_IBIT(s->pdata.mctrl_cfg[port->line], | ||
| 503 | RNG_IP); | ||
| 504 | mctrl &= ~TIOCM_RNG; | ||
| 505 | mctrl |= (ipr & bitmask) ? TIOCM_RNG : 0; | ||
| 506 | } | ||
| 507 | |||
| 508 | mutex_unlock(&s->sccnxp_mutex); | ||
| 509 | |||
| 510 | return mctrl; | ||
| 511 | } | ||
| 512 | |||
| 513 | static void sccnxp_break_ctl(struct uart_port *port, int break_state) | ||
| 514 | { | ||
| 515 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 516 | |||
| 517 | mutex_lock(&s->sccnxp_mutex); | ||
| 518 | sccnxp_port_write(port, SCCNXP_CR_REG, break_state ? | ||
| 519 | CR_CMD_START_BREAK : CR_CMD_STOP_BREAK); | ||
| 520 | mutex_unlock(&s->sccnxp_mutex); | ||
| 521 | } | ||
| 522 | |||
| 523 | static void sccnxp_set_termios(struct uart_port *port, | ||
| 524 | struct ktermios *termios, struct ktermios *old) | ||
| 525 | { | ||
| 526 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 527 | u8 mr1, mr2; | ||
| 528 | int baud; | ||
| 529 | |||
| 530 | mutex_lock(&s->sccnxp_mutex); | ||
| 531 | |||
| 532 | /* Mask termios capabilities we don't support */ | ||
| 533 | termios->c_cflag &= ~CMSPAR; | ||
| 534 | |||
| 535 | /* Disable RX & TX, reset break condition, status and FIFOs */ | ||
| 536 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_RX_RESET | | ||
| 537 | CR_RX_DISABLE | CR_TX_DISABLE); | ||
| 538 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_TX_RESET); | ||
| 539 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_STATUS_RESET); | ||
| 540 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_BREAK_RESET); | ||
| 541 | |||
| 542 | /* Word size */ | ||
| 543 | switch (termios->c_cflag & CSIZE) { | ||
| 544 | case CS5: | ||
| 545 | mr1 = MR1_BITS_5; | ||
| 546 | break; | ||
| 547 | case CS6: | ||
| 548 | mr1 = MR1_BITS_6; | ||
| 549 | break; | ||
| 550 | case CS7: | ||
| 551 | mr1 = MR1_BITS_7; | ||
| 552 | break; | ||
| 553 | case CS8: | ||
| 554 | default: | ||
| 555 | mr1 = MR1_BITS_8; | ||
| 556 | break; | ||
| 557 | } | ||
| 558 | |||
| 559 | /* Parity */ | ||
| 560 | if (termios->c_cflag & PARENB) { | ||
| 561 | if (termios->c_cflag & PARODD) | ||
| 562 | mr1 |= MR1_PAR_ODD; | ||
| 563 | } else | ||
| 564 | mr1 |= MR1_PAR_NO; | ||
| 565 | |||
| 566 | /* Stop bits */ | ||
| 567 | mr2 = (termios->c_cflag & CSTOPB) ? MR2_STOP2 : MR2_STOP1; | ||
| 568 | |||
| 569 | /* Update desired format */ | ||
| 570 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_MRPTR1); | ||
| 571 | sccnxp_port_write(port, SCCNXP_MR_REG, mr1); | ||
| 572 | sccnxp_port_write(port, SCCNXP_MR_REG, mr2); | ||
| 573 | |||
| 574 | /* Set read status mask */ | ||
| 575 | port->read_status_mask = SR_OVR; | ||
| 576 | if (termios->c_iflag & INPCK) | ||
| 577 | port->read_status_mask |= SR_PE | SR_FE; | ||
| 578 | if (termios->c_iflag & (BRKINT | PARMRK)) | ||
| 579 | port->read_status_mask |= SR_BRK; | ||
| 580 | |||
| 581 | /* Set status ignore mask */ | ||
| 582 | port->ignore_status_mask = 0; | ||
| 583 | if (termios->c_iflag & IGNBRK) | ||
| 584 | port->ignore_status_mask |= SR_BRK; | ||
| 585 | if (!(termios->c_cflag & CREAD)) | ||
| 586 | port->ignore_status_mask |= SR_PE | SR_OVR | SR_FE | SR_BRK; | ||
| 587 | |||
| 588 | /* Setup baudrate */ | ||
| 589 | baud = uart_get_baud_rate(port, termios, old, 50, | ||
| 590 | (s->flags & SCCNXP_HAVE_MR0) ? | ||
| 591 | 230400 : 38400); | ||
| 592 | baud = sccnxp_set_baud(port, baud); | ||
| 593 | |||
| 594 | /* Update timeout according to new baud rate */ | ||
| 595 | uart_update_timeout(port, termios->c_cflag, baud); | ||
| 596 | |||
| 597 | if (tty_termios_baud_rate(termios)) | ||
| 598 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
| 599 | |||
| 600 | /* Enable RX & TX */ | ||
| 601 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_ENABLE | CR_TX_ENABLE); | ||
| 602 | |||
| 603 | mutex_unlock(&s->sccnxp_mutex); | ||
| 604 | } | ||
| 605 | |||
| 606 | static int sccnxp_startup(struct uart_port *port) | ||
| 607 | { | ||
| 608 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 609 | |||
| 610 | mutex_lock(&s->sccnxp_mutex); | ||
| 611 | |||
| 612 | if (s->flags & SCCNXP_HAVE_IO) { | ||
| 613 | /* Outputs are controlled manually */ | ||
| 614 | sccnxp_write(port, SCCNXP_OPCR_REG, 0); | ||
| 615 | } | ||
| 616 | |||
| 617 | /* Reset break condition, status and FIFOs */ | ||
| 618 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_RX_RESET); | ||
| 619 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_TX_RESET); | ||
| 620 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_STATUS_RESET); | ||
| 621 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_BREAK_RESET); | ||
| 622 | |||
| 623 | /* Enable RX & TX */ | ||
| 624 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_ENABLE | CR_TX_ENABLE); | ||
| 625 | |||
| 626 | /* Enable RX interrupt */ | ||
| 627 | sccnxp_enable_irq(port, IMR_RXRDY); | ||
| 628 | |||
| 629 | mutex_unlock(&s->sccnxp_mutex); | ||
| 630 | |||
| 631 | return 0; | ||
| 632 | } | ||
| 633 | |||
| 634 | static void sccnxp_shutdown(struct uart_port *port) | ||
| 635 | { | ||
| 636 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 637 | |||
| 638 | mutex_lock(&s->sccnxp_mutex); | ||
| 639 | |||
| 640 | /* Disable interrupts */ | ||
| 641 | sccnxp_disable_irq(port, IMR_TXRDY | IMR_RXRDY); | ||
| 642 | |||
| 643 | /* Disable TX & RX */ | ||
| 644 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_DISABLE | CR_TX_DISABLE); | ||
| 645 | |||
| 646 | /* Leave direction to input */ | ||
| 647 | if (s->flags & SCCNXP_HAVE_IO) | ||
| 648 | sccnxp_set_bit(port, DIR_OP, 0); | ||
| 649 | |||
| 650 | mutex_unlock(&s->sccnxp_mutex); | ||
| 651 | } | ||
| 652 | |||
| 653 | static const char *sccnxp_type(struct uart_port *port) | ||
| 654 | { | ||
| 655 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
| 656 | |||
| 657 | return (port->type == PORT_SC26XX) ? s->name : NULL; | ||
| 658 | } | ||
| 659 | |||
| 660 | static void sccnxp_release_port(struct uart_port *port) | ||
| 661 | { | ||
| 662 | /* Do nothing */ | ||
| 663 | } | ||
| 664 | |||
| 665 | static int sccnxp_request_port(struct uart_port *port) | ||
| 666 | { | ||
| 667 | /* Do nothing */ | ||
| 668 | return 0; | ||
| 669 | } | ||
| 670 | |||
| 671 | static void sccnxp_config_port(struct uart_port *port, int flags) | ||
| 672 | { | ||
| 673 | if (flags & UART_CONFIG_TYPE) | ||
| 674 | port->type = PORT_SC26XX; | ||
| 675 | } | ||
| 676 | |||
| 677 | static int sccnxp_verify_port(struct uart_port *port, struct serial_struct *s) | ||
| 678 | { | ||
| 679 | if ((s->type == PORT_UNKNOWN) || (s->type == PORT_SC26XX)) | ||
| 680 | return 0; | ||
| 681 | if (s->irq == port->irq) | ||
| 682 | return 0; | ||
| 683 | |||
| 684 | return -EINVAL; | ||
| 685 | } | ||
| 686 | |||
| 687 | static const struct uart_ops sccnxp_ops = { | ||
| 688 | .tx_empty = sccnxp_tx_empty, | ||
| 689 | .set_mctrl = sccnxp_set_mctrl, | ||
| 690 | .get_mctrl = sccnxp_get_mctrl, | ||
| 691 | .stop_tx = sccnxp_stop_tx, | ||
| 692 | .start_tx = sccnxp_start_tx, | ||
| 693 | .stop_rx = sccnxp_stop_rx, | ||
| 694 | .enable_ms = sccnxp_enable_ms, | ||
| 695 | .break_ctl = sccnxp_break_ctl, | ||
| 696 | .startup = sccnxp_startup, | ||
| 697 | .shutdown = sccnxp_shutdown, | ||
| 698 | .set_termios = sccnxp_set_termios, | ||
| 699 | .type = sccnxp_type, | ||
| 700 | .release_port = sccnxp_release_port, | ||
| 701 | .request_port = sccnxp_request_port, | ||
| 702 | .config_port = sccnxp_config_port, | ||
| 703 | .verify_port = sccnxp_verify_port, | ||
| 704 | }; | ||
| 705 | |||
| 706 | #ifdef CONFIG_SERIAL_SCCNXP_CONSOLE | ||
| 707 | static void sccnxp_console_putchar(struct uart_port *port, int c) | ||
| 708 | { | ||
| 709 | int tryes = 100000; | ||
| 710 | |||
| 711 | while (tryes--) { | ||
| 712 | if (sccnxp_port_read(port, SCCNXP_SR_REG) & SR_TXRDY) { | ||
| 713 | sccnxp_port_write(port, SCCNXP_THR_REG, c); | ||
| 714 | break; | ||
| 715 | } | ||
| 716 | barrier(); | ||
| 717 | } | ||
| 718 | } | ||
| 719 | |||
| 720 | static void sccnxp_console_write(struct console *co, const char *c, unsigned n) | ||
| 721 | { | ||
| 722 | struct sccnxp_port *s = (struct sccnxp_port *)co->data; | ||
| 723 | struct uart_port *port = &s->port[co->index]; | ||
| 724 | |||
| 725 | mutex_lock(&s->sccnxp_mutex); | ||
| 726 | uart_console_write(port, c, n, sccnxp_console_putchar); | ||
| 727 | mutex_unlock(&s->sccnxp_mutex); | ||
| 728 | } | ||
| 729 | |||
| 730 | static int sccnxp_console_setup(struct console *co, char *options) | ||
| 731 | { | ||
| 732 | struct sccnxp_port *s = (struct sccnxp_port *)co->data; | ||
| 733 | struct uart_port *port = &s->port[(co->index > 0) ? co->index : 0]; | ||
| 734 | int baud = 9600, bits = 8, parity = 'n', flow = 'n'; | ||
| 735 | |||
| 736 | if (options) | ||
| 737 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
| 738 | |||
| 739 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
| 740 | } | ||
| 741 | #endif | ||
| 742 | |||
| 743 | static int __devinit sccnxp_probe(struct platform_device *pdev) | ||
| 744 | { | ||
| 745 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 746 | int chiptype = pdev->id_entry->driver_data; | ||
| 747 | struct sccnxp_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
| 748 | int i, ret, fifosize, freq_min, freq_max; | ||
| 749 | struct sccnxp_port *s; | ||
| 750 | void __iomem *membase; | ||
| 751 | |||
| 752 | if (!res) { | ||
| 753 | dev_err(&pdev->dev, "Missing memory resource data\n"); | ||
| 754 | return -EADDRNOTAVAIL; | ||
| 755 | } | ||
| 756 | |||
| 757 | dev_set_name(&pdev->dev, SCCNXP_NAME); | ||
| 758 | |||
| 759 | s = devm_kzalloc(&pdev->dev, sizeof(struct sccnxp_port), GFP_KERNEL); | ||
| 760 | if (!s) { | ||
| 761 | dev_err(&pdev->dev, "Error allocating port structure\n"); | ||
| 762 | return -ENOMEM; | ||
| 763 | } | ||
| 764 | platform_set_drvdata(pdev, s); | ||
| 765 | |||
| 766 | mutex_init(&s->sccnxp_mutex); | ||
| 767 | |||
| 768 | /* Individual chip settings */ | ||
| 769 | switch (chiptype) { | ||
| 770 | case SCCNXP_TYPE_SC2681: | ||
| 771 | s->name = "SC2681"; | ||
| 772 | s->uart.nr = 2; | ||
| 773 | s->freq_std = 3686400; | ||
| 774 | s->addr_mask = 0x0f; | ||
| 775 | s->flags = SCCNXP_HAVE_IO; | ||
| 776 | fifosize = 3; | ||
| 777 | freq_min = 1000000; | ||
| 778 | freq_max = 4000000; | ||
| 779 | break; | ||
| 780 | case SCCNXP_TYPE_SC2691: | ||
| 781 | s->name = "SC2691"; | ||
| 782 | s->uart.nr = 1; | ||
| 783 | s->freq_std = 3686400; | ||
| 784 | s->addr_mask = 0x07; | ||
| 785 | s->flags = 0; | ||
| 786 | fifosize = 3; | ||
| 787 | freq_min = 1000000; | ||
| 788 | freq_max = 4000000; | ||
| 789 | break; | ||
| 790 | case SCCNXP_TYPE_SC2692: | ||
| 791 | s->name = "SC2692"; | ||
| 792 | s->uart.nr = 2; | ||
| 793 | s->freq_std = 3686400; | ||
| 794 | s->addr_mask = 0x0f; | ||
| 795 | s->flags = SCCNXP_HAVE_IO; | ||
| 796 | fifosize = 3; | ||
| 797 | freq_min = 1000000; | ||
| 798 | freq_max = 4000000; | ||
| 799 | break; | ||
| 800 | case SCCNXP_TYPE_SC2891: | ||
| 801 | s->name = "SC2891"; | ||
| 802 | s->uart.nr = 1; | ||
| 803 | s->freq_std = 3686400; | ||
| 804 | s->addr_mask = 0x0f; | ||
| 805 | s->flags = SCCNXP_HAVE_IO | SCCNXP_HAVE_MR0; | ||
| 806 | fifosize = 16; | ||
| 807 | freq_min = 100000; | ||
| 808 | freq_max = 8000000; | ||
| 809 | break; | ||
| 810 | case SCCNXP_TYPE_SC2892: | ||
| 811 | s->name = "SC2892"; | ||
| 812 | s->uart.nr = 2; | ||
| 813 | s->freq_std = 3686400; | ||
| 814 | s->addr_mask = 0x0f; | ||
| 815 | s->flags = SCCNXP_HAVE_IO | SCCNXP_HAVE_MR0; | ||
| 816 | fifosize = 16; | ||
| 817 | freq_min = 100000; | ||
| 818 | freq_max = 8000000; | ||
| 819 | break; | ||
| 820 | case SCCNXP_TYPE_SC28202: | ||
| 821 | s->name = "SC28202"; | ||
| 822 | s->uart.nr = 2; | ||
| 823 | s->freq_std = 14745600; | ||
| 824 | s->addr_mask = 0x7f; | ||
| 825 | s->flags = SCCNXP_HAVE_IO | SCCNXP_HAVE_MR0; | ||
| 826 | fifosize = 256; | ||
| 827 | freq_min = 1000000; | ||
| 828 | freq_max = 50000000; | ||
| 829 | break; | ||
| 830 | case SCCNXP_TYPE_SC68681: | ||
| 831 | s->name = "SC68681"; | ||
| 832 | s->uart.nr = 2; | ||
| 833 | s->freq_std = 3686400; | ||
| 834 | s->addr_mask = 0x0f; | ||
| 835 | s->flags = SCCNXP_HAVE_IO; | ||
| 836 | fifosize = 3; | ||
| 837 | freq_min = 1000000; | ||
| 838 | freq_max = 4000000; | ||
| 839 | break; | ||
| 840 | case SCCNXP_TYPE_SC68692: | ||
| 841 | s->name = "SC68692"; | ||
| 842 | s->uart.nr = 2; | ||
| 843 | s->freq_std = 3686400; | ||
| 844 | s->addr_mask = 0x0f; | ||
| 845 | s->flags = SCCNXP_HAVE_IO; | ||
| 846 | fifosize = 3; | ||
| 847 | freq_min = 1000000; | ||
| 848 | freq_max = 4000000; | ||
| 849 | break; | ||
| 850 | default: | ||
| 851 | dev_err(&pdev->dev, "Unsupported chip type %i\n", chiptype); | ||
| 852 | ret = -ENOTSUPP; | ||
| 853 | goto err_out; | ||
| 854 | } | ||
| 855 | |||
| 856 | if (!pdata) { | ||
| 857 | dev_warn(&pdev->dev, | ||
| 858 | "No platform data supplied, using defaults\n"); | ||
| 859 | s->pdata.frequency = s->freq_std; | ||
| 860 | } else | ||
| 861 | memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); | ||
| 862 | |||
| 863 | s->irq = platform_get_irq(pdev, 0); | ||
| 864 | if (s->irq <= 0) { | ||
| 865 | dev_err(&pdev->dev, "Missing irq resource data\n"); | ||
| 866 | ret = -ENXIO; | ||
| 867 | goto err_out; | ||
| 868 | } | ||
| 869 | |||
| 870 | /* Check input frequency */ | ||
| 871 | if ((s->pdata.frequency < freq_min) || | ||
| 872 | (s->pdata.frequency > freq_max)) { | ||
| 873 | dev_err(&pdev->dev, "Frequency out of bounds\n"); | ||
| 874 | ret = -EINVAL; | ||
| 875 | goto err_out; | ||
| 876 | } | ||
| 877 | |||
| 878 | membase = devm_request_and_ioremap(&pdev->dev, res); | ||
| 879 | if (!membase) { | ||
| 880 | dev_err(&pdev->dev, "Failed to ioremap\n"); | ||
| 881 | ret = -EIO; | ||
| 882 | goto err_out; | ||
| 883 | } | ||
| 884 | |||
| 885 | s->uart.owner = THIS_MODULE; | ||
| 886 | s->uart.dev_name = "ttySC"; | ||
| 887 | s->uart.major = SCCNXP_MAJOR; | ||
| 888 | s->uart.minor = SCCNXP_MINOR; | ||
| 889 | #ifdef CONFIG_SERIAL_SCCNXP_CONSOLE | ||
| 890 | s->uart.cons = &s->console; | ||
| 891 | s->uart.cons->device = uart_console_device; | ||
| 892 | s->uart.cons->write = sccnxp_console_write; | ||
| 893 | s->uart.cons->setup = sccnxp_console_setup; | ||
| 894 | s->uart.cons->flags = CON_PRINTBUFFER; | ||
| 895 | s->uart.cons->index = -1; | ||
| 896 | s->uart.cons->data = s; | ||
| 897 | strcpy(s->uart.cons->name, "ttySC"); | ||
| 898 | #endif | ||
| 899 | ret = uart_register_driver(&s->uart); | ||
| 900 | if (ret) { | ||
| 901 | dev_err(&pdev->dev, "Registering UART driver failed\n"); | ||
| 902 | goto err_out; | ||
| 903 | } | ||
| 904 | |||
| 905 | for (i = 0; i < s->uart.nr; i++) { | ||
| 906 | s->port[i].line = i; | ||
| 907 | s->port[i].dev = &pdev->dev; | ||
| 908 | s->port[i].irq = s->irq; | ||
| 909 | s->port[i].type = PORT_SC26XX; | ||
| 910 | s->port[i].fifosize = fifosize; | ||
| 911 | s->port[i].flags = UPF_SKIP_TEST | UPF_FIXED_TYPE; | ||
| 912 | s->port[i].iotype = UPIO_MEM; | ||
| 913 | s->port[i].mapbase = res->start; | ||
| 914 | s->port[i].membase = membase; | ||
| 915 | s->port[i].regshift = s->pdata.reg_shift; | ||
| 916 | s->port[i].uartclk = s->pdata.frequency; | ||
| 917 | s->port[i].ops = &sccnxp_ops; | ||
| 918 | uart_add_one_port(&s->uart, &s->port[i]); | ||
| 919 | /* Set direction to input */ | ||
| 920 | if (s->flags & SCCNXP_HAVE_IO) | ||
| 921 | sccnxp_set_bit(&s->port[i], DIR_OP, 0); | ||
| 922 | } | ||
| 923 | |||
| 924 | /* Disable interrupts */ | ||
| 925 | s->imr = 0; | ||
| 926 | sccnxp_write(&s->port[0], SCCNXP_IMR_REG, 0); | ||
| 927 | |||
| 928 | /* Board specific configure */ | ||
| 929 | if (s->pdata.init) | ||
| 930 | s->pdata.init(); | ||
| 931 | |||
| 932 | ret = devm_request_threaded_irq(&pdev->dev, s->irq, NULL, sccnxp_ist, | ||
| 933 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
| 934 | dev_name(&pdev->dev), s); | ||
| 935 | if (!ret) | ||
| 936 | return 0; | ||
| 937 | |||
| 938 | dev_err(&pdev->dev, "Unable to reguest IRQ %i\n", s->irq); | ||
| 939 | |||
| 940 | err_out: | ||
| 941 | platform_set_drvdata(pdev, NULL); | ||
| 942 | |||
| 943 | return ret; | ||
| 944 | } | ||
| 945 | |||
| 946 | static int __devexit sccnxp_remove(struct platform_device *pdev) | ||
| 947 | { | ||
| 948 | int i; | ||
| 949 | struct sccnxp_port *s = platform_get_drvdata(pdev); | ||
| 950 | |||
| 951 | devm_free_irq(&pdev->dev, s->irq, s); | ||
| 952 | |||
| 953 | for (i = 0; i < s->uart.nr; i++) | ||
| 954 | uart_remove_one_port(&s->uart, &s->port[i]); | ||
| 955 | |||
| 956 | uart_unregister_driver(&s->uart); | ||
| 957 | platform_set_drvdata(pdev, NULL); | ||
| 958 | |||
| 959 | if (s->pdata.exit) | ||
| 960 | s->pdata.exit(); | ||
| 961 | |||
| 962 | return 0; | ||
| 963 | } | ||
| 964 | |||
| 965 | static const struct platform_device_id sccnxp_id_table[] = { | ||
| 966 | { "sc2681", SCCNXP_TYPE_SC2681 }, | ||
| 967 | { "sc2691", SCCNXP_TYPE_SC2691 }, | ||
| 968 | { "sc2692", SCCNXP_TYPE_SC2692 }, | ||
| 969 | { "sc2891", SCCNXP_TYPE_SC2891 }, | ||
| 970 | { "sc2892", SCCNXP_TYPE_SC2892 }, | ||
| 971 | { "sc28202", SCCNXP_TYPE_SC28202 }, | ||
| 972 | { "sc68681", SCCNXP_TYPE_SC68681 }, | ||
| 973 | { "sc68692", SCCNXP_TYPE_SC68692 }, | ||
| 974 | }; | ||
| 975 | MODULE_DEVICE_TABLE(platform, sccnxp_id_table); | ||
| 976 | |||
| 977 | static struct platform_driver sccnxp_uart_driver = { | ||
| 978 | .driver = { | ||
| 979 | .name = SCCNXP_NAME, | ||
| 980 | .owner = THIS_MODULE, | ||
| 981 | }, | ||
| 982 | .probe = sccnxp_probe, | ||
| 983 | .remove = __devexit_p(sccnxp_remove), | ||
| 984 | .id_table = sccnxp_id_table, | ||
| 985 | }; | ||
| 986 | module_platform_driver(sccnxp_uart_driver); | ||
| 987 | |||
| 988 | MODULE_LICENSE("GPL v2"); | ||
| 989 | MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); | ||
| 990 | MODULE_DESCRIPTION("SCCNXP serial driver"); | ||
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index a21dc8e3b7c0..0fcfd98a9566 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
| @@ -159,7 +159,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, | |||
| 159 | retval = uport->ops->startup(uport); | 159 | retval = uport->ops->startup(uport); |
| 160 | if (retval == 0) { | 160 | if (retval == 0) { |
| 161 | if (uart_console(uport) && uport->cons->cflag) { | 161 | if (uart_console(uport) && uport->cons->cflag) { |
| 162 | tty->termios->c_cflag = uport->cons->cflag; | 162 | tty->termios.c_cflag = uport->cons->cflag; |
| 163 | uport->cons->cflag = 0; | 163 | uport->cons->cflag = 0; |
| 164 | } | 164 | } |
| 165 | /* | 165 | /* |
| @@ -172,11 +172,11 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, | |||
| 172 | * Setup the RTS and DTR signals once the | 172 | * Setup the RTS and DTR signals once the |
| 173 | * port is open and ready to respond. | 173 | * port is open and ready to respond. |
| 174 | */ | 174 | */ |
| 175 | if (tty->termios->c_cflag & CBAUD) | 175 | if (tty->termios.c_cflag & CBAUD) |
| 176 | uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); | 176 | uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | if (port->flags & ASYNC_CTS_FLOW) { | 179 | if (tty_port_cts_enabled(port)) { |
| 180 | spin_lock_irq(&uport->lock); | 180 | spin_lock_irq(&uport->lock); |
| 181 | if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) | 181 | if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) |
| 182 | tty->hw_stopped = 1; | 182 | tty->hw_stopped = 1; |
| @@ -240,7 +240,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) | |||
| 240 | /* | 240 | /* |
| 241 | * Turn off DTR and RTS early. | 241 | * Turn off DTR and RTS early. |
| 242 | */ | 242 | */ |
| 243 | if (!tty || (tty->termios->c_cflag & HUPCL)) | 243 | if (!tty || (tty->termios.c_cflag & HUPCL)) |
| 244 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); | 244 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
| 245 | 245 | ||
| 246 | uart_port_shutdown(port); | 246 | uart_port_shutdown(port); |
| @@ -440,10 +440,10 @@ static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | |||
| 440 | * If we have no tty, termios, or the port does not exist, | 440 | * If we have no tty, termios, or the port does not exist, |
| 441 | * then we can't set the parameters for this port. | 441 | * then we can't set the parameters for this port. |
| 442 | */ | 442 | */ |
| 443 | if (!tty || !tty->termios || uport->type == PORT_UNKNOWN) | 443 | if (!tty || uport->type == PORT_UNKNOWN) |
| 444 | return; | 444 | return; |
| 445 | 445 | ||
| 446 | termios = tty->termios; | 446 | termios = &tty->termios; |
| 447 | 447 | ||
| 448 | /* | 448 | /* |
| 449 | * Set flags based on termios cflag | 449 | * Set flags based on termios cflag |
| @@ -614,7 +614,7 @@ static void uart_throttle(struct tty_struct *tty) | |||
| 614 | if (I_IXOFF(tty)) | 614 | if (I_IXOFF(tty)) |
| 615 | uart_send_xchar(tty, STOP_CHAR(tty)); | 615 | uart_send_xchar(tty, STOP_CHAR(tty)); |
| 616 | 616 | ||
| 617 | if (tty->termios->c_cflag & CRTSCTS) | 617 | if (tty->termios.c_cflag & CRTSCTS) |
| 618 | uart_clear_mctrl(state->uart_port, TIOCM_RTS); | 618 | uart_clear_mctrl(state->uart_port, TIOCM_RTS); |
| 619 | } | 619 | } |
| 620 | 620 | ||
| @@ -630,42 +630,48 @@ static void uart_unthrottle(struct tty_struct *tty) | |||
| 630 | uart_send_xchar(tty, START_CHAR(tty)); | 630 | uart_send_xchar(tty, START_CHAR(tty)); |
| 631 | } | 631 | } |
| 632 | 632 | ||
| 633 | if (tty->termios->c_cflag & CRTSCTS) | 633 | if (tty->termios.c_cflag & CRTSCTS) |
| 634 | uart_set_mctrl(port, TIOCM_RTS); | 634 | uart_set_mctrl(port, TIOCM_RTS); |
| 635 | } | 635 | } |
| 636 | 636 | ||
| 637 | static int uart_get_info(struct uart_state *state, | 637 | static void uart_get_info(struct tty_port *port, |
| 638 | struct serial_struct __user *retinfo) | 638 | struct uart_state *state, |
| 639 | struct serial_struct *retinfo) | ||
| 639 | { | 640 | { |
| 640 | struct uart_port *uport = state->uart_port; | 641 | struct uart_port *uport = state->uart_port; |
| 641 | struct tty_port *port = &state->port; | ||
| 642 | struct serial_struct tmp; | ||
| 643 | 642 | ||
| 644 | memset(&tmp, 0, sizeof(tmp)); | 643 | memset(retinfo, 0, sizeof(*retinfo)); |
| 645 | 644 | ||
| 646 | /* Ensure the state we copy is consistent and no hardware changes | 645 | retinfo->type = uport->type; |
| 647 | occur as we go */ | 646 | retinfo->line = uport->line; |
| 648 | mutex_lock(&port->mutex); | 647 | retinfo->port = uport->iobase; |
| 649 | |||
| 650 | tmp.type = uport->type; | ||
| 651 | tmp.line = uport->line; | ||
| 652 | tmp.port = uport->iobase; | ||
| 653 | if (HIGH_BITS_OFFSET) | 648 | if (HIGH_BITS_OFFSET) |
| 654 | tmp.port_high = (long) uport->iobase >> HIGH_BITS_OFFSET; | 649 | retinfo->port_high = (long) uport->iobase >> HIGH_BITS_OFFSET; |
| 655 | tmp.irq = uport->irq; | 650 | retinfo->irq = uport->irq; |
| 656 | tmp.flags = uport->flags; | 651 | retinfo->flags = uport->flags; |
| 657 | tmp.xmit_fifo_size = uport->fifosize; | 652 | retinfo->xmit_fifo_size = uport->fifosize; |
| 658 | tmp.baud_base = uport->uartclk / 16; | 653 | retinfo->baud_base = uport->uartclk / 16; |
| 659 | tmp.close_delay = jiffies_to_msecs(port->close_delay) / 10; | 654 | retinfo->close_delay = jiffies_to_msecs(port->close_delay) / 10; |
| 660 | tmp.closing_wait = port->closing_wait == ASYNC_CLOSING_WAIT_NONE ? | 655 | retinfo->closing_wait = port->closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
| 661 | ASYNC_CLOSING_WAIT_NONE : | 656 | ASYNC_CLOSING_WAIT_NONE : |
| 662 | jiffies_to_msecs(port->closing_wait) / 10; | 657 | jiffies_to_msecs(port->closing_wait) / 10; |
| 663 | tmp.custom_divisor = uport->custom_divisor; | 658 | retinfo->custom_divisor = uport->custom_divisor; |
| 664 | tmp.hub6 = uport->hub6; | 659 | retinfo->hub6 = uport->hub6; |
| 665 | tmp.io_type = uport->iotype; | 660 | retinfo->io_type = uport->iotype; |
| 666 | tmp.iomem_reg_shift = uport->regshift; | 661 | retinfo->iomem_reg_shift = uport->regshift; |
| 667 | tmp.iomem_base = (void *)(unsigned long)uport->mapbase; | 662 | retinfo->iomem_base = (void *)(unsigned long)uport->mapbase; |
| 663 | } | ||
| 664 | |||
| 665 | static int uart_get_info_user(struct uart_state *state, | ||
| 666 | struct serial_struct __user *retinfo) | ||
| 667 | { | ||
| 668 | struct tty_port *port = &state->port; | ||
| 669 | struct serial_struct tmp; | ||
| 668 | 670 | ||
| 671 | /* Ensure the state we copy is consistent and no hardware changes | ||
| 672 | occur as we go */ | ||
| 673 | mutex_lock(&port->mutex); | ||
| 674 | uart_get_info(port, state, &tmp); | ||
| 669 | mutex_unlock(&port->mutex); | 675 | mutex_unlock(&port->mutex); |
| 670 | 676 | ||
| 671 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | 677 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
| @@ -673,42 +679,30 @@ static int uart_get_info(struct uart_state *state, | |||
| 673 | return 0; | 679 | return 0; |
| 674 | } | 680 | } |
| 675 | 681 | ||
| 676 | static int uart_set_info(struct tty_struct *tty, struct uart_state *state, | 682 | static int uart_set_info(struct tty_struct *tty, struct tty_port *port, |
| 677 | struct serial_struct __user *newinfo) | 683 | struct uart_state *state, |
| 684 | struct serial_struct *new_info) | ||
| 678 | { | 685 | { |
| 679 | struct serial_struct new_serial; | ||
| 680 | struct uart_port *uport = state->uart_port; | 686 | struct uart_port *uport = state->uart_port; |
| 681 | struct tty_port *port = &state->port; | ||
| 682 | unsigned long new_port; | 687 | unsigned long new_port; |
| 683 | unsigned int change_irq, change_port, closing_wait; | 688 | unsigned int change_irq, change_port, closing_wait; |
| 684 | unsigned int old_custom_divisor, close_delay; | 689 | unsigned int old_custom_divisor, close_delay; |
| 685 | upf_t old_flags, new_flags; | 690 | upf_t old_flags, new_flags; |
| 686 | int retval = 0; | 691 | int retval = 0; |
| 687 | 692 | ||
| 688 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) | 693 | new_port = new_info->port; |
| 689 | return -EFAULT; | ||
| 690 | |||
| 691 | new_port = new_serial.port; | ||
| 692 | if (HIGH_BITS_OFFSET) | 694 | if (HIGH_BITS_OFFSET) |
| 693 | new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; | 695 | new_port += (unsigned long) new_info->port_high << HIGH_BITS_OFFSET; |
| 694 | 696 | ||
| 695 | new_serial.irq = irq_canonicalize(new_serial.irq); | 697 | new_info->irq = irq_canonicalize(new_info->irq); |
| 696 | close_delay = msecs_to_jiffies(new_serial.close_delay * 10); | 698 | close_delay = msecs_to_jiffies(new_info->close_delay * 10); |
| 697 | closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? | 699 | closing_wait = new_info->closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
| 698 | ASYNC_CLOSING_WAIT_NONE : | 700 | ASYNC_CLOSING_WAIT_NONE : |
| 699 | msecs_to_jiffies(new_serial.closing_wait * 10); | 701 | msecs_to_jiffies(new_info->closing_wait * 10); |
| 700 | 702 | ||
| 701 | /* | ||
| 702 | * This semaphore protects port->count. It is also | ||
| 703 | * very useful to prevent opens. Also, take the | ||
| 704 | * port configuration semaphore to make sure that a | ||
| 705 | * module insertion/removal doesn't change anything | ||
| 706 | * under us. | ||
| 707 | */ | ||
| 708 | mutex_lock(&port->mutex); | ||
| 709 | 703 | ||
| 710 | change_irq = !(uport->flags & UPF_FIXED_PORT) | 704 | change_irq = !(uport->flags & UPF_FIXED_PORT) |
| 711 | && new_serial.irq != uport->irq; | 705 | && new_info->irq != uport->irq; |
| 712 | 706 | ||
| 713 | /* | 707 | /* |
| 714 | * Since changing the 'type' of the port changes its resource | 708 | * Since changing the 'type' of the port changes its resource |
| @@ -717,29 +711,29 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state, | |||
| 717 | */ | 711 | */ |
| 718 | change_port = !(uport->flags & UPF_FIXED_PORT) | 712 | change_port = !(uport->flags & UPF_FIXED_PORT) |
| 719 | && (new_port != uport->iobase || | 713 | && (new_port != uport->iobase || |
| 720 | (unsigned long)new_serial.iomem_base != uport->mapbase || | 714 | (unsigned long)new_info->iomem_base != uport->mapbase || |
| 721 | new_serial.hub6 != uport->hub6 || | 715 | new_info->hub6 != uport->hub6 || |
| 722 | new_serial.io_type != uport->iotype || | 716 | new_info->io_type != uport->iotype || |
| 723 | new_serial.iomem_reg_shift != uport->regshift || | 717 | new_info->iomem_reg_shift != uport->regshift || |
| 724 | new_serial.type != uport->type); | 718 | new_info->type != uport->type); |
| 725 | 719 | ||
| 726 | old_flags = uport->flags; | 720 | old_flags = uport->flags; |
| 727 | new_flags = new_serial.flags; | 721 | new_flags = new_info->flags; |
| 728 | old_custom_divisor = uport->custom_divisor; | 722 | old_custom_divisor = uport->custom_divisor; |
| 729 | 723 | ||
| 730 | if (!capable(CAP_SYS_ADMIN)) { | 724 | if (!capable(CAP_SYS_ADMIN)) { |
| 731 | retval = -EPERM; | 725 | retval = -EPERM; |
| 732 | if (change_irq || change_port || | 726 | if (change_irq || change_port || |
| 733 | (new_serial.baud_base != uport->uartclk / 16) || | 727 | (new_info->baud_base != uport->uartclk / 16) || |
| 734 | (close_delay != port->close_delay) || | 728 | (close_delay != port->close_delay) || |
| 735 | (closing_wait != port->closing_wait) || | 729 | (closing_wait != port->closing_wait) || |
| 736 | (new_serial.xmit_fifo_size && | 730 | (new_info->xmit_fifo_size && |
| 737 | new_serial.xmit_fifo_size != uport->fifosize) || | 731 | new_info->xmit_fifo_size != uport->fifosize) || |
| 738 | (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0)) | 732 | (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0)) |
| 739 | goto exit; | 733 | goto exit; |
| 740 | uport->flags = ((uport->flags & ~UPF_USR_MASK) | | 734 | uport->flags = ((uport->flags & ~UPF_USR_MASK) | |
| 741 | (new_flags & UPF_USR_MASK)); | 735 | (new_flags & UPF_USR_MASK)); |
| 742 | uport->custom_divisor = new_serial.custom_divisor; | 736 | uport->custom_divisor = new_info->custom_divisor; |
| 743 | goto check_and_exit; | 737 | goto check_and_exit; |
| 744 | } | 738 | } |
| 745 | 739 | ||
| @@ -747,10 +741,10 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state, | |||
| 747 | * Ask the low level driver to verify the settings. | 741 | * Ask the low level driver to verify the settings. |
| 748 | */ | 742 | */ |
| 749 | if (uport->ops->verify_port) | 743 | if (uport->ops->verify_port) |
| 750 | retval = uport->ops->verify_port(uport, &new_serial); | 744 | retval = uport->ops->verify_port(uport, new_info); |
| 751 | 745 | ||
| 752 | if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) || | 746 | if ((new_info->irq >= nr_irqs) || (new_info->irq < 0) || |
| 753 | (new_serial.baud_base < 9600)) | 747 | (new_info->baud_base < 9600)) |
| 754 | retval = -EINVAL; | 748 | retval = -EINVAL; |
| 755 | 749 | ||
| 756 | if (retval) | 750 | if (retval) |
| @@ -790,11 +784,11 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state, | |||
| 790 | uport->ops->release_port(uport); | 784 | uport->ops->release_port(uport); |
| 791 | 785 | ||
| 792 | uport->iobase = new_port; | 786 | uport->iobase = new_port; |
| 793 | uport->type = new_serial.type; | 787 | uport->type = new_info->type; |
| 794 | uport->hub6 = new_serial.hub6; | 788 | uport->hub6 = new_info->hub6; |
| 795 | uport->iotype = new_serial.io_type; | 789 | uport->iotype = new_info->io_type; |
| 796 | uport->regshift = new_serial.iomem_reg_shift; | 790 | uport->regshift = new_info->iomem_reg_shift; |
| 797 | uport->mapbase = (unsigned long)new_serial.iomem_base; | 791 | uport->mapbase = (unsigned long)new_info->iomem_base; |
| 798 | 792 | ||
| 799 | /* | 793 | /* |
| 800 | * Claim and map the new regions | 794 | * Claim and map the new regions |
| @@ -835,16 +829,16 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state, | |||
| 835 | } | 829 | } |
| 836 | 830 | ||
| 837 | if (change_irq) | 831 | if (change_irq) |
| 838 | uport->irq = new_serial.irq; | 832 | uport->irq = new_info->irq; |
| 839 | if (!(uport->flags & UPF_FIXED_PORT)) | 833 | if (!(uport->flags & UPF_FIXED_PORT)) |
| 840 | uport->uartclk = new_serial.baud_base * 16; | 834 | uport->uartclk = new_info->baud_base * 16; |
| 841 | uport->flags = (uport->flags & ~UPF_CHANGE_MASK) | | 835 | uport->flags = (uport->flags & ~UPF_CHANGE_MASK) | |
| 842 | (new_flags & UPF_CHANGE_MASK); | 836 | (new_flags & UPF_CHANGE_MASK); |
| 843 | uport->custom_divisor = new_serial.custom_divisor; | 837 | uport->custom_divisor = new_info->custom_divisor; |
| 844 | port->close_delay = close_delay; | 838 | port->close_delay = close_delay; |
| 845 | port->closing_wait = closing_wait; | 839 | port->closing_wait = closing_wait; |
| 846 | if (new_serial.xmit_fifo_size) | 840 | if (new_info->xmit_fifo_size) |
| 847 | uport->fifosize = new_serial.xmit_fifo_size; | 841 | uport->fifosize = new_info->xmit_fifo_size; |
| 848 | if (port->tty) | 842 | if (port->tty) |
| 849 | port->tty->low_latency = | 843 | port->tty->low_latency = |
| 850 | (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; | 844 | (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; |
| @@ -873,6 +867,28 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state, | |||
| 873 | } else | 867 | } else |
| 874 | retval = uart_startup(tty, state, 1); | 868 | retval = uart_startup(tty, state, 1); |
| 875 | exit: | 869 | exit: |
| 870 | return retval; | ||
| 871 | } | ||
| 872 | |||
| 873 | static int uart_set_info_user(struct tty_struct *tty, struct uart_state *state, | ||
| 874 | struct serial_struct __user *newinfo) | ||
| 875 | { | ||
| 876 | struct serial_struct new_serial; | ||
| 877 | struct tty_port *port = &state->port; | ||
| 878 | int retval; | ||
| 879 | |||
| 880 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) | ||
| 881 | return -EFAULT; | ||
| 882 | |||
| 883 | /* | ||
| 884 | * This semaphore protects port->count. It is also | ||
| 885 | * very useful to prevent opens. Also, take the | ||
| 886 | * port configuration semaphore to make sure that a | ||
| 887 | * module insertion/removal doesn't change anything | ||
| 888 | * under us. | ||
| 889 | */ | ||
| 890 | mutex_lock(&port->mutex); | ||
| 891 | retval = uart_set_info(tty, port, state, &new_serial); | ||
| 876 | mutex_unlock(&port->mutex); | 892 | mutex_unlock(&port->mutex); |
| 877 | return retval; | 893 | return retval; |
| 878 | } | 894 | } |
| @@ -1115,11 +1131,11 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, | |||
| 1115 | */ | 1131 | */ |
| 1116 | switch (cmd) { | 1132 | switch (cmd) { |
| 1117 | case TIOCGSERIAL: | 1133 | case TIOCGSERIAL: |
| 1118 | ret = uart_get_info(state, uarg); | 1134 | ret = uart_get_info_user(state, uarg); |
| 1119 | break; | 1135 | break; |
| 1120 | 1136 | ||
| 1121 | case TIOCSSERIAL: | 1137 | case TIOCSSERIAL: |
| 1122 | ret = uart_set_info(tty, state, uarg); | 1138 | ret = uart_set_info_user(tty, state, uarg); |
| 1123 | break; | 1139 | break; |
| 1124 | 1140 | ||
| 1125 | case TIOCSERCONFIG: | 1141 | case TIOCSERCONFIG: |
| @@ -1187,7 +1203,7 @@ static void uart_set_ldisc(struct tty_struct *tty) | |||
| 1187 | struct uart_port *uport = state->uart_port; | 1203 | struct uart_port *uport = state->uart_port; |
| 1188 | 1204 | ||
| 1189 | if (uport->ops->set_ldisc) | 1205 | if (uport->ops->set_ldisc) |
| 1190 | uport->ops->set_ldisc(uport, tty->termios->c_line); | 1206 | uport->ops->set_ldisc(uport, tty->termios.c_line); |
| 1191 | } | 1207 | } |
| 1192 | 1208 | ||
| 1193 | static void uart_set_termios(struct tty_struct *tty, | 1209 | static void uart_set_termios(struct tty_struct *tty, |
| @@ -1195,7 +1211,7 @@ static void uart_set_termios(struct tty_struct *tty, | |||
| 1195 | { | 1211 | { |
| 1196 | struct uart_state *state = tty->driver_data; | 1212 | struct uart_state *state = tty->driver_data; |
| 1197 | unsigned long flags; | 1213 | unsigned long flags; |
| 1198 | unsigned int cflag = tty->termios->c_cflag; | 1214 | unsigned int cflag = tty->termios.c_cflag; |
| 1199 | 1215 | ||
| 1200 | 1216 | ||
| 1201 | /* | 1217 | /* |
| @@ -1206,9 +1222,9 @@ static void uart_set_termios(struct tty_struct *tty, | |||
| 1206 | */ | 1222 | */ |
| 1207 | #define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) | 1223 | #define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) |
| 1208 | if ((cflag ^ old_termios->c_cflag) == 0 && | 1224 | if ((cflag ^ old_termios->c_cflag) == 0 && |
| 1209 | tty->termios->c_ospeed == old_termios->c_ospeed && | 1225 | tty->termios.c_ospeed == old_termios->c_ospeed && |
| 1210 | tty->termios->c_ispeed == old_termios->c_ispeed && | 1226 | tty->termios.c_ispeed == old_termios->c_ispeed && |
| 1211 | RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) { | 1227 | RELEVANT_IFLAG(tty->termios.c_iflag ^ old_termios->c_iflag) == 0) { |
| 1212 | return; | 1228 | return; |
| 1213 | } | 1229 | } |
| 1214 | 1230 | ||
| @@ -1960,8 +1976,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
| 1960 | /* | 1976 | /* |
| 1961 | * If that's unset, use the tty termios setting. | 1977 | * If that's unset, use the tty termios setting. |
| 1962 | */ | 1978 | */ |
| 1963 | if (port->tty && port->tty->termios && termios.c_cflag == 0) | 1979 | if (port->tty && termios.c_cflag == 0) |
| 1964 | termios = *(port->tty->termios); | 1980 | termios = port->tty->termios; |
| 1965 | 1981 | ||
| 1966 | if (console_suspend_enabled) | 1982 | if (console_suspend_enabled) |
| 1967 | uart_change_pm(state, 0); | 1983 | uart_change_pm(state, 0); |
| @@ -2113,6 +2129,7 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options) | |||
| 2113 | int bits = 8; | 2129 | int bits = 8; |
| 2114 | int parity = 'n'; | 2130 | int parity = 'n'; |
| 2115 | int flow = 'n'; | 2131 | int flow = 'n'; |
| 2132 | int ret; | ||
| 2116 | 2133 | ||
| 2117 | if (!state || !state->uart_port) | 2134 | if (!state || !state->uart_port) |
| 2118 | return -1; | 2135 | return -1; |
| @@ -2121,6 +2138,22 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options) | |||
| 2121 | if (!(port->ops->poll_get_char && port->ops->poll_put_char)) | 2138 | if (!(port->ops->poll_get_char && port->ops->poll_put_char)) |
| 2122 | return -1; | 2139 | return -1; |
| 2123 | 2140 | ||
| 2141 | if (port->ops->poll_init) { | ||
| 2142 | struct tty_port *tport = &state->port; | ||
| 2143 | |||
| 2144 | ret = 0; | ||
| 2145 | mutex_lock(&tport->mutex); | ||
| 2146 | /* | ||
| 2147 | * We don't set ASYNCB_INITIALIZED as we only initialized the | ||
| 2148 | * hw, e.g. state->xmit is still uninitialized. | ||
| 2149 | */ | ||
| 2150 | if (!test_bit(ASYNCB_INITIALIZED, &tport->flags)) | ||
| 2151 | ret = port->ops->poll_init(port); | ||
| 2152 | mutex_unlock(&tport->mutex); | ||
| 2153 | if (ret) | ||
| 2154 | return ret; | ||
| 2155 | } | ||
| 2156 | |||
| 2124 | if (options) { | 2157 | if (options) { |
| 2125 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 2158 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
| 2126 | return uart_set_options(port, NULL, baud, parity, bits, flow); | 2159 | return uart_set_options(port, NULL, baud, parity, bits, flow); |
| @@ -2293,6 +2326,36 @@ struct tty_driver *uart_console_device(struct console *co, int *index) | |||
| 2293 | return p->tty_driver; | 2326 | return p->tty_driver; |
| 2294 | } | 2327 | } |
| 2295 | 2328 | ||
| 2329 | static ssize_t uart_get_attr_uartclk(struct device *dev, | ||
| 2330 | struct device_attribute *attr, char *buf) | ||
| 2331 | { | ||
| 2332 | int ret; | ||
| 2333 | struct tty_port *port = dev_get_drvdata(dev); | ||
| 2334 | struct uart_state *state = container_of(port, struct uart_state, port); | ||
| 2335 | |||
| 2336 | mutex_lock(&state->port.mutex); | ||
| 2337 | ret = snprintf(buf, PAGE_SIZE, "%d\n", state->uart_port->uartclk); | ||
| 2338 | mutex_unlock(&state->port.mutex); | ||
| 2339 | |||
| 2340 | return ret; | ||
| 2341 | } | ||
| 2342 | |||
| 2343 | static DEVICE_ATTR(uartclk, S_IRUSR | S_IRGRP, uart_get_attr_uartclk, NULL); | ||
| 2344 | |||
| 2345 | static struct attribute *tty_dev_attrs[] = { | ||
| 2346 | &dev_attr_uartclk.attr, | ||
| 2347 | NULL, | ||
| 2348 | }; | ||
| 2349 | |||
| 2350 | static const struct attribute_group tty_dev_attr_group = { | ||
| 2351 | .attrs = tty_dev_attrs, | ||
| 2352 | }; | ||
| 2353 | |||
| 2354 | static const struct attribute_group *tty_dev_attr_groups[] = { | ||
| 2355 | &tty_dev_attr_group, | ||
| 2356 | NULL | ||
| 2357 | }; | ||
| 2358 | |||
| 2296 | /** | 2359 | /** |
| 2297 | * uart_add_one_port - attach a driver-defined port structure | 2360 | * uart_add_one_port - attach a driver-defined port structure |
| 2298 | * @drv: pointer to the uart low level driver structure for this port | 2361 | * @drv: pointer to the uart low level driver structure for this port |
| @@ -2346,7 +2409,8 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
| 2346 | * Register the port whether it's detected or not. This allows | 2409 | * Register the port whether it's detected or not. This allows |
| 2347 | * setserial to be used to alter this ports parameters. | 2410 | * setserial to be used to alter this ports parameters. |
| 2348 | */ | 2411 | */ |
| 2349 | tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev); | 2412 | tty_dev = tty_port_register_device_attr(port, drv->tty_driver, |
| 2413 | uport->line, uport->dev, port, tty_dev_attr_groups); | ||
| 2350 | if (likely(!IS_ERR(tty_dev))) { | 2414 | if (likely(!IS_ERR(tty_dev))) { |
| 2351 | device_set_wakeup_capable(tty_dev, 1); | 2415 | device_set_wakeup_capable(tty_dev, 1); |
| 2352 | } else { | 2416 | } else { |
| @@ -2454,9 +2518,12 @@ void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) | |||
| 2454 | { | 2518 | { |
| 2455 | struct uart_state *state = uport->state; | 2519 | struct uart_state *state = uport->state; |
| 2456 | struct tty_port *port = &state->port; | 2520 | struct tty_port *port = &state->port; |
| 2457 | struct tty_ldisc *ld = tty_ldisc_ref(port->tty); | 2521 | struct tty_ldisc *ld = NULL; |
| 2458 | struct pps_event_time ts; | 2522 | struct pps_event_time ts; |
| 2523 | struct tty_struct *tty = port->tty; | ||
| 2459 | 2524 | ||
| 2525 | if (tty) | ||
| 2526 | ld = tty_ldisc_ref(tty); | ||
| 2460 | if (ld && ld->ops->dcd_change) | 2527 | if (ld && ld->ops->dcd_change) |
| 2461 | pps_get_ts(&ts); | 2528 | pps_get_ts(&ts); |
| 2462 | 2529 | ||
| @@ -2469,12 +2536,12 @@ void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) | |||
| 2469 | if (port->flags & ASYNC_CHECK_CD) { | 2536 | if (port->flags & ASYNC_CHECK_CD) { |
| 2470 | if (status) | 2537 | if (status) |
| 2471 | wake_up_interruptible(&port->open_wait); | 2538 | wake_up_interruptible(&port->open_wait); |
| 2472 | else if (port->tty) | 2539 | else if (tty) |
| 2473 | tty_hangup(port->tty); | 2540 | tty_hangup(tty); |
| 2474 | } | 2541 | } |
| 2475 | 2542 | ||
| 2476 | if (ld && ld->ops->dcd_change) | 2543 | if (ld && ld->ops->dcd_change) |
| 2477 | ld->ops->dcd_change(port->tty, status, &ts); | 2544 | ld->ops->dcd_change(tty, status, &ts); |
| 2478 | if (ld) | 2545 | if (ld) |
| 2479 | tty_ldisc_deref(ld); | 2546 | tty_ldisc_deref(ld); |
| 2480 | } | 2547 | } |
| @@ -2492,7 +2559,7 @@ void uart_handle_cts_change(struct uart_port *uport, unsigned int status) | |||
| 2492 | 2559 | ||
| 2493 | uport->icount.cts++; | 2560 | uport->icount.cts++; |
| 2494 | 2561 | ||
| 2495 | if (port->flags & ASYNC_CTS_FLOW) { | 2562 | if (tty_port_cts_enabled(port)) { |
| 2496 | if (tty->hw_stopped) { | 2563 | if (tty->hw_stopped) { |
| 2497 | if (status) { | 2564 | if (status) { |
| 2498 | tty->hw_stopped = 0; | 2565 | tty->hw_stopped = 0; |
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 5b3eda2024fe..a9e2bd1ab534 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
| @@ -668,7 +668,7 @@ int sirfsoc_uart_probe(struct platform_device *pdev) | |||
| 668 | if (res == NULL) { | 668 | if (res == NULL) { |
| 669 | dev_err(&pdev->dev, "Insufficient resources.\n"); | 669 | dev_err(&pdev->dev, "Insufficient resources.\n"); |
| 670 | ret = -EFAULT; | 670 | ret = -EFAULT; |
| 671 | goto irq_err; | 671 | goto err; |
| 672 | } | 672 | } |
| 673 | port->irq = res->start; | 673 | port->irq = res->start; |
| 674 | 674 | ||
| @@ -676,7 +676,7 @@ int sirfsoc_uart_probe(struct platform_device *pdev) | |||
| 676 | sirfport->p = pinctrl_get_select_default(&pdev->dev); | 676 | sirfport->p = pinctrl_get_select_default(&pdev->dev); |
| 677 | ret = IS_ERR(sirfport->p); | 677 | ret = IS_ERR(sirfport->p); |
| 678 | if (ret) | 678 | if (ret) |
| 679 | goto pin_err; | 679 | goto err; |
| 680 | } | 680 | } |
| 681 | 681 | ||
| 682 | port->ops = &sirfsoc_uart_ops; | 682 | port->ops = &sirfsoc_uart_ops; |
| @@ -695,9 +695,6 @@ port_err: | |||
| 695 | platform_set_drvdata(pdev, NULL); | 695 | platform_set_drvdata(pdev, NULL); |
| 696 | if (sirfport->hw_flow_ctrl) | 696 | if (sirfport->hw_flow_ctrl) |
| 697 | pinctrl_put(sirfport->p); | 697 | pinctrl_put(sirfport->p); |
| 698 | pin_err: | ||
| 699 | irq_err: | ||
| 700 | devm_iounmap(&pdev->dev, port->membase); | ||
| 701 | err: | 698 | err: |
| 702 | return ret; | 699 | return ret; |
| 703 | } | 700 | } |
| @@ -709,7 +706,6 @@ static int sirfsoc_uart_remove(struct platform_device *pdev) | |||
| 709 | platform_set_drvdata(pdev, NULL); | 706 | platform_set_drvdata(pdev, NULL); |
| 710 | if (sirfport->hw_flow_ctrl) | 707 | if (sirfport->hw_flow_ctrl) |
| 711 | pinctrl_put(sirfport->p); | 708 | pinctrl_put(sirfport->p); |
| 712 | devm_iounmap(&pdev->dev, port->membase); | ||
| 713 | uart_remove_one_port(&sirfsoc_uart_drv, port); | 709 | uart_remove_one_port(&sirfsoc_uart_drv, port); |
| 714 | return 0; | 710 | return 0; |
| 715 | } | 711 | } |
diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 675303b8ed84..b97913dcdbff 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c | |||
| @@ -58,10 +58,16 @@ | |||
| 58 | enum su_type { SU_PORT_NONE, SU_PORT_MS, SU_PORT_KBD, SU_PORT_PORT }; | 58 | enum su_type { SU_PORT_NONE, SU_PORT_MS, SU_PORT_KBD, SU_PORT_PORT }; |
| 59 | static char *su_typev[] = { "su(???)", "su(mouse)", "su(kbd)", "su(serial)" }; | 59 | static char *su_typev[] = { "su(???)", "su(mouse)", "su(kbd)", "su(serial)" }; |
| 60 | 60 | ||
| 61 | struct serial_uart_config { | ||
| 62 | char *name; | ||
| 63 | int dfl_xmit_fifo_size; | ||
| 64 | int flags; | ||
| 65 | }; | ||
| 66 | |||
| 61 | /* | 67 | /* |
| 62 | * Here we define the default xmit fifo size used for each type of UART. | 68 | * Here we define the default xmit fifo size used for each type of UART. |
| 63 | */ | 69 | */ |
| 64 | static const struct serial_uart_config uart_config[PORT_MAX_8250+1] = { | 70 | static const struct serial_uart_config uart_config[] = { |
| 65 | { "unknown", 1, 0 }, | 71 | { "unknown", 1, 0 }, |
| 66 | { "8250", 1, 0 }, | 72 | { "8250", 1, 0 }, |
| 67 | { "16450", 1, 0 }, | 73 | { "16450", 1, 0 }, |
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 593d40ad0a6b..70e3a525bc82 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c | |||
| @@ -1359,7 +1359,7 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info ) | |||
| 1359 | } | 1359 | } |
| 1360 | } | 1360 | } |
| 1361 | 1361 | ||
| 1362 | if ( (info->port.flags & ASYNC_CTS_FLOW) && | 1362 | if (tty_port_cts_enabled(&info->port) && |
| 1363 | (status & MISCSTATUS_CTS_LATCHED) ) { | 1363 | (status & MISCSTATUS_CTS_LATCHED) ) { |
| 1364 | if (info->port.tty->hw_stopped) { | 1364 | if (info->port.tty->hw_stopped) { |
| 1365 | if (status & MISCSTATUS_CTS) { | 1365 | if (status & MISCSTATUS_CTS) { |
| @@ -1840,22 +1840,22 @@ static void shutdown(struct mgsl_struct * info) | |||
| 1840 | usc_DisableInterrupts(info,RECEIVE_DATA + RECEIVE_STATUS + | 1840 | usc_DisableInterrupts(info,RECEIVE_DATA + RECEIVE_STATUS + |
| 1841 | TRANSMIT_DATA + TRANSMIT_STATUS + IO_PIN + MISC ); | 1841 | TRANSMIT_DATA + TRANSMIT_STATUS + IO_PIN + MISC ); |
| 1842 | usc_DisableDmaInterrupts(info,DICR_MASTER + DICR_TRANSMIT + DICR_RECEIVE); | 1842 | usc_DisableDmaInterrupts(info,DICR_MASTER + DICR_TRANSMIT + DICR_RECEIVE); |
| 1843 | 1843 | ||
| 1844 | /* Disable DMAEN (Port 7, Bit 14) */ | 1844 | /* Disable DMAEN (Port 7, Bit 14) */ |
| 1845 | /* This disconnects the DMA request signal from the ISA bus */ | 1845 | /* This disconnects the DMA request signal from the ISA bus */ |
| 1846 | /* on the ISA adapter. This has no effect for the PCI adapter */ | 1846 | /* on the ISA adapter. This has no effect for the PCI adapter */ |
| 1847 | usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) | BIT14)); | 1847 | usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) | BIT14)); |
| 1848 | 1848 | ||
| 1849 | /* Disable INTEN (Port 6, Bit12) */ | 1849 | /* Disable INTEN (Port 6, Bit12) */ |
| 1850 | /* This disconnects the IRQ request signal to the ISA bus */ | 1850 | /* This disconnects the IRQ request signal to the ISA bus */ |
| 1851 | /* on the ISA adapter. This has no effect for the PCI adapter */ | 1851 | /* on the ISA adapter. This has no effect for the PCI adapter */ |
| 1852 | usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12)); | 1852 | usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12)); |
| 1853 | 1853 | ||
| 1854 | if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) { | 1854 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { |
| 1855 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 1855 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); |
| 1856 | usc_set_serial_signals(info); | 1856 | usc_set_serial_signals(info); |
| 1857 | } | 1857 | } |
| 1858 | 1858 | ||
| 1859 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 1859 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
| 1860 | 1860 | ||
| 1861 | mgsl_release_resources(info); | 1861 | mgsl_release_resources(info); |
| @@ -1895,7 +1895,7 @@ static void mgsl_program_hw(struct mgsl_struct *info) | |||
| 1895 | usc_EnableInterrupts(info, IO_PIN); | 1895 | usc_EnableInterrupts(info, IO_PIN); |
| 1896 | usc_get_serial_signals(info); | 1896 | usc_get_serial_signals(info); |
| 1897 | 1897 | ||
| 1898 | if (info->netcount || info->port.tty->termios->c_cflag & CREAD) | 1898 | if (info->netcount || info->port.tty->termios.c_cflag & CREAD) |
| 1899 | usc_start_receiver(info); | 1899 | usc_start_receiver(info); |
| 1900 | 1900 | ||
| 1901 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 1901 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
| @@ -1908,14 +1908,14 @@ static void mgsl_change_params(struct mgsl_struct *info) | |||
| 1908 | unsigned cflag; | 1908 | unsigned cflag; |
| 1909 | int bits_per_char; | 1909 | int bits_per_char; |
| 1910 | 1910 | ||
| 1911 | if (!info->port.tty || !info->port.tty->termios) | 1911 | if (!info->port.tty) |
| 1912 | return; | 1912 | return; |
| 1913 | 1913 | ||
| 1914 | if (debug_level >= DEBUG_LEVEL_INFO) | 1914 | if (debug_level >= DEBUG_LEVEL_INFO) |
| 1915 | printk("%s(%d):mgsl_change_params(%s)\n", | 1915 | printk("%s(%d):mgsl_change_params(%s)\n", |
| 1916 | __FILE__,__LINE__, info->device_name ); | 1916 | __FILE__,__LINE__, info->device_name ); |
| 1917 | 1917 | ||
| 1918 | cflag = info->port.tty->termios->c_cflag; | 1918 | cflag = info->port.tty->termios.c_cflag; |
| 1919 | 1919 | ||
| 1920 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 1920 | /* if B0 rate (hangup) specified then negate DTR and RTS */ |
| 1921 | /* otherwise assert DTR and RTS */ | 1921 | /* otherwise assert DTR and RTS */ |
| @@ -2367,8 +2367,8 @@ static void mgsl_throttle(struct tty_struct * tty) | |||
| 2367 | 2367 | ||
| 2368 | if (I_IXOFF(tty)) | 2368 | if (I_IXOFF(tty)) |
| 2369 | mgsl_send_xchar(tty, STOP_CHAR(tty)); | 2369 | mgsl_send_xchar(tty, STOP_CHAR(tty)); |
| 2370 | 2370 | ||
| 2371 | if (tty->termios->c_cflag & CRTSCTS) { | 2371 | if (tty->termios.c_cflag & CRTSCTS) { |
| 2372 | spin_lock_irqsave(&info->irq_spinlock,flags); | 2372 | spin_lock_irqsave(&info->irq_spinlock,flags); |
| 2373 | info->serial_signals &= ~SerialSignal_RTS; | 2373 | info->serial_signals &= ~SerialSignal_RTS; |
| 2374 | usc_set_serial_signals(info); | 2374 | usc_set_serial_signals(info); |
| @@ -2401,8 +2401,8 @@ static void mgsl_unthrottle(struct tty_struct * tty) | |||
| 2401 | else | 2401 | else |
| 2402 | mgsl_send_xchar(tty, START_CHAR(tty)); | 2402 | mgsl_send_xchar(tty, START_CHAR(tty)); |
| 2403 | } | 2403 | } |
| 2404 | 2404 | ||
| 2405 | if (tty->termios->c_cflag & CRTSCTS) { | 2405 | if (tty->termios.c_cflag & CRTSCTS) { |
| 2406 | spin_lock_irqsave(&info->irq_spinlock,flags); | 2406 | spin_lock_irqsave(&info->irq_spinlock,flags); |
| 2407 | info->serial_signals |= SerialSignal_RTS; | 2407 | info->serial_signals |= SerialSignal_RTS; |
| 2408 | usc_set_serial_signals(info); | 2408 | usc_set_serial_signals(info); |
| @@ -3045,7 +3045,7 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio | |||
| 3045 | 3045 | ||
| 3046 | /* Handle transition to B0 status */ | 3046 | /* Handle transition to B0 status */ |
| 3047 | if (old_termios->c_cflag & CBAUD && | 3047 | if (old_termios->c_cflag & CBAUD && |
| 3048 | !(tty->termios->c_cflag & CBAUD)) { | 3048 | !(tty->termios.c_cflag & CBAUD)) { |
| 3049 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 3049 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); |
| 3050 | spin_lock_irqsave(&info->irq_spinlock,flags); | 3050 | spin_lock_irqsave(&info->irq_spinlock,flags); |
| 3051 | usc_set_serial_signals(info); | 3051 | usc_set_serial_signals(info); |
| @@ -3054,9 +3054,9 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio | |||
| 3054 | 3054 | ||
| 3055 | /* Handle transition away from B0 status */ | 3055 | /* Handle transition away from B0 status */ |
| 3056 | if (!(old_termios->c_cflag & CBAUD) && | 3056 | if (!(old_termios->c_cflag & CBAUD) && |
| 3057 | tty->termios->c_cflag & CBAUD) { | 3057 | tty->termios.c_cflag & CBAUD) { |
| 3058 | info->serial_signals |= SerialSignal_DTR; | 3058 | info->serial_signals |= SerialSignal_DTR; |
| 3059 | if (!(tty->termios->c_cflag & CRTSCTS) || | 3059 | if (!(tty->termios.c_cflag & CRTSCTS) || |
| 3060 | !test_bit(TTY_THROTTLED, &tty->flags)) { | 3060 | !test_bit(TTY_THROTTLED, &tty->flags)) { |
| 3061 | info->serial_signals |= SerialSignal_RTS; | 3061 | info->serial_signals |= SerialSignal_RTS; |
| 3062 | } | 3062 | } |
| @@ -3067,7 +3067,7 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio | |||
| 3067 | 3067 | ||
| 3068 | /* Handle turning off CRTSCTS */ | 3068 | /* Handle turning off CRTSCTS */ |
| 3069 | if (old_termios->c_cflag & CRTSCTS && | 3069 | if (old_termios->c_cflag & CRTSCTS && |
| 3070 | !(tty->termios->c_cflag & CRTSCTS)) { | 3070 | !(tty->termios.c_cflag & CRTSCTS)) { |
| 3071 | tty->hw_stopped = 0; | 3071 | tty->hw_stopped = 0; |
| 3072 | mgsl_start(tty); | 3072 | mgsl_start(tty); |
| 3073 | } | 3073 | } |
| @@ -3287,7 +3287,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
| 3287 | return 0; | 3287 | return 0; |
| 3288 | } | 3288 | } |
| 3289 | 3289 | ||
| 3290 | if (tty->termios->c_cflag & CLOCAL) | 3290 | if (tty->termios.c_cflag & CLOCAL) |
| 3291 | do_clocal = true; | 3291 | do_clocal = true; |
| 3292 | 3292 | ||
| 3293 | /* Wait for carrier detect and the line to become | 3293 | /* Wait for carrier detect and the line to become |
| @@ -3313,7 +3313,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
| 3313 | port->blocked_open++; | 3313 | port->blocked_open++; |
| 3314 | 3314 | ||
| 3315 | while (1) { | 3315 | while (1) { |
| 3316 | if (tty->termios->c_cflag & CBAUD) | 3316 | if (tty->termios.c_cflag & CBAUD) |
| 3317 | tty_port_raise_dtr_rts(port); | 3317 | tty_port_raise_dtr_rts(port); |
| 3318 | 3318 | ||
| 3319 | set_current_state(TASK_INTERRUPTIBLE); | 3319 | set_current_state(TASK_INTERRUPTIBLE); |
| @@ -3338,9 +3338,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
| 3338 | printk("%s(%d):block_til_ready blocking on %s count=%d\n", | 3338 | printk("%s(%d):block_til_ready blocking on %s count=%d\n", |
| 3339 | __FILE__,__LINE__, tty->driver->name, port->count ); | 3339 | __FILE__,__LINE__, tty->driver->name, port->count ); |
| 3340 | 3340 | ||
| 3341 | tty_unlock(); | 3341 | tty_unlock(tty); |
| 3342 | schedule(); | 3342 | schedule(); |
| 3343 | tty_lock(); | 3343 | tty_lock(tty); |
| 3344 | } | 3344 | } |
| 3345 | 3345 | ||
| 3346 | set_current_state(TASK_RUNNING); | 3346 | set_current_state(TASK_RUNNING); |
| @@ -3362,6 +3362,29 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
| 3362 | 3362 | ||
| 3363 | } /* end of block_til_ready() */ | 3363 | } /* end of block_til_ready() */ |
| 3364 | 3364 | ||
| 3365 | static int mgsl_install(struct tty_driver *driver, struct tty_struct *tty) | ||
| 3366 | { | ||
| 3367 | struct mgsl_struct *info; | ||
| 3368 | int line = tty->index; | ||
| 3369 | |||
| 3370 | /* verify range of specified line number */ | ||
| 3371 | if (line >= mgsl_device_count) { | ||
| 3372 | printk("%s(%d):mgsl_open with invalid line #%d.\n", | ||
| 3373 | __FILE__, __LINE__, line); | ||
| 3374 | return -ENODEV; | ||
| 3375 | } | ||
| 3376 | |||
| 3377 | /* find the info structure for the specified line */ | ||
| 3378 | info = mgsl_device_list; | ||
| 3379 | while (info && info->line != line) | ||
| 3380 | info = info->next_device; | ||
| 3381 | if (mgsl_paranoia_check(info, tty->name, "mgsl_open")) | ||
| 3382 | return -ENODEV; | ||
| 3383 | tty->driver_data = info; | ||
| 3384 | |||
| 3385 | return tty_port_install(&info->port, driver, tty); | ||
| 3386 | } | ||
| 3387 | |||
| 3365 | /* mgsl_open() | 3388 | /* mgsl_open() |
| 3366 | * | 3389 | * |
| 3367 | * Called when a port is opened. Init and enable port. | 3390 | * Called when a port is opened. Init and enable port. |
| @@ -3374,26 +3397,10 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
| 3374 | */ | 3397 | */ |
| 3375 | static int mgsl_open(struct tty_struct *tty, struct file * filp) | 3398 | static int mgsl_open(struct tty_struct *tty, struct file * filp) |
| 3376 | { | 3399 | { |
| 3377 | struct mgsl_struct *info; | 3400 | struct mgsl_struct *info = tty->driver_data; |
| 3378 | int retval, line; | ||
| 3379 | unsigned long flags; | 3401 | unsigned long flags; |
| 3402 | int retval; | ||
| 3380 | 3403 | ||
| 3381 | /* verify range of specified line number */ | ||
| 3382 | line = tty->index; | ||
| 3383 | if (line >= mgsl_device_count) { | ||
| 3384 | printk("%s(%d):mgsl_open with invalid line #%d.\n", | ||
| 3385 | __FILE__,__LINE__,line); | ||
| 3386 | return -ENODEV; | ||
| 3387 | } | ||
| 3388 | |||
| 3389 | /* find the info structure for the specified line */ | ||
| 3390 | info = mgsl_device_list; | ||
| 3391 | while(info && info->line != line) | ||
| 3392 | info = info->next_device; | ||
| 3393 | if (mgsl_paranoia_check(info, tty->name, "mgsl_open")) | ||
| 3394 | return -ENODEV; | ||
| 3395 | |||
| 3396 | tty->driver_data = info; | ||
| 3397 | info->port.tty = tty; | 3404 | info->port.tty = tty; |
| 3398 | 3405 | ||
| 3399 | if (debug_level >= DEBUG_LEVEL_INFO) | 3406 | if (debug_level >= DEBUG_LEVEL_INFO) |
| @@ -4297,6 +4304,7 @@ static struct mgsl_struct* mgsl_allocate_device(void) | |||
| 4297 | } /* end of mgsl_allocate_device()*/ | 4304 | } /* end of mgsl_allocate_device()*/ |
| 4298 | 4305 | ||
| 4299 | static const struct tty_operations mgsl_ops = { | 4306 | static const struct tty_operations mgsl_ops = { |
| 4307 | .install = mgsl_install, | ||
| 4300 | .open = mgsl_open, | 4308 | .open = mgsl_open, |
| 4301 | .close = mgsl_close, | 4309 | .close = mgsl_close, |
| 4302 | .write = mgsl_write, | 4310 | .write = mgsl_write, |
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index aa1debf97cc7..b38e954eedd3 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c | |||
| @@ -785,7 +785,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 785 | 785 | ||
| 786 | /* Handle transition to B0 status */ | 786 | /* Handle transition to B0 status */ |
| 787 | if (old_termios->c_cflag & CBAUD && | 787 | if (old_termios->c_cflag & CBAUD && |
| 788 | !(tty->termios->c_cflag & CBAUD)) { | 788 | !(tty->termios.c_cflag & CBAUD)) { |
| 789 | info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 789 | info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); |
| 790 | spin_lock_irqsave(&info->lock,flags); | 790 | spin_lock_irqsave(&info->lock,flags); |
| 791 | set_signals(info); | 791 | set_signals(info); |
| @@ -794,9 +794,9 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 794 | 794 | ||
| 795 | /* Handle transition away from B0 status */ | 795 | /* Handle transition away from B0 status */ |
| 796 | if (!(old_termios->c_cflag & CBAUD) && | 796 | if (!(old_termios->c_cflag & CBAUD) && |
| 797 | tty->termios->c_cflag & CBAUD) { | 797 | tty->termios.c_cflag & CBAUD) { |
| 798 | info->signals |= SerialSignal_DTR; | 798 | info->signals |= SerialSignal_DTR; |
| 799 | if (!(tty->termios->c_cflag & CRTSCTS) || | 799 | if (!(tty->termios.c_cflag & CRTSCTS) || |
| 800 | !test_bit(TTY_THROTTLED, &tty->flags)) { | 800 | !test_bit(TTY_THROTTLED, &tty->flags)) { |
| 801 | info->signals |= SerialSignal_RTS; | 801 | info->signals |= SerialSignal_RTS; |
| 802 | } | 802 | } |
| @@ -807,7 +807,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 807 | 807 | ||
| 808 | /* Handle turning off CRTSCTS */ | 808 | /* Handle turning off CRTSCTS */ |
| 809 | if (old_termios->c_cflag & CRTSCTS && | 809 | if (old_termios->c_cflag & CRTSCTS && |
| 810 | !(tty->termios->c_cflag & CRTSCTS)) { | 810 | !(tty->termios.c_cflag & CRTSCTS)) { |
| 811 | tty->hw_stopped = 0; | 811 | tty->hw_stopped = 0; |
| 812 | tx_release(tty); | 812 | tx_release(tty); |
| 813 | } | 813 | } |
| @@ -1372,7 +1372,7 @@ static void throttle(struct tty_struct * tty) | |||
| 1372 | DBGINFO(("%s throttle\n", info->device_name)); | 1372 | DBGINFO(("%s throttle\n", info->device_name)); |
| 1373 | if (I_IXOFF(tty)) | 1373 | if (I_IXOFF(tty)) |
| 1374 | send_xchar(tty, STOP_CHAR(tty)); | 1374 | send_xchar(tty, STOP_CHAR(tty)); |
| 1375 | if (tty->termios->c_cflag & CRTSCTS) { | 1375 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1376 | spin_lock_irqsave(&info->lock,flags); | 1376 | spin_lock_irqsave(&info->lock,flags); |
| 1377 | info->signals &= ~SerialSignal_RTS; | 1377 | info->signals &= ~SerialSignal_RTS; |
| 1378 | set_signals(info); | 1378 | set_signals(info); |
| @@ -1397,7 +1397,7 @@ static void unthrottle(struct tty_struct * tty) | |||
| 1397 | else | 1397 | else |
| 1398 | send_xchar(tty, START_CHAR(tty)); | 1398 | send_xchar(tty, START_CHAR(tty)); |
| 1399 | } | 1399 | } |
| 1400 | if (tty->termios->c_cflag & CRTSCTS) { | 1400 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1401 | spin_lock_irqsave(&info->lock,flags); | 1401 | spin_lock_irqsave(&info->lock,flags); |
| 1402 | info->signals |= SerialSignal_RTS; | 1402 | info->signals |= SerialSignal_RTS; |
| 1403 | set_signals(info); | 1403 | set_signals(info); |
| @@ -2053,7 +2053,7 @@ static void cts_change(struct slgt_info *info, unsigned short status) | |||
| 2053 | wake_up_interruptible(&info->event_wait_q); | 2053 | wake_up_interruptible(&info->event_wait_q); |
| 2054 | info->pending_bh |= BH_STATUS; | 2054 | info->pending_bh |= BH_STATUS; |
| 2055 | 2055 | ||
| 2056 | if (info->port.flags & ASYNC_CTS_FLOW) { | 2056 | if (tty_port_cts_enabled(&info->port)) { |
| 2057 | if (info->port.tty) { | 2057 | if (info->port.tty) { |
| 2058 | if (info->port.tty->hw_stopped) { | 2058 | if (info->port.tty->hw_stopped) { |
| 2059 | if (info->signals & SerialSignal_CTS) { | 2059 | if (info->signals & SerialSignal_CTS) { |
| @@ -2493,7 +2493,7 @@ static void shutdown(struct slgt_info *info) | |||
| 2493 | 2493 | ||
| 2494 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); | 2494 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); |
| 2495 | 2495 | ||
| 2496 | if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) { | 2496 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { |
| 2497 | info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 2497 | info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); |
| 2498 | set_signals(info); | 2498 | set_signals(info); |
| 2499 | } | 2499 | } |
| @@ -2534,7 +2534,7 @@ static void program_hw(struct slgt_info *info) | |||
| 2534 | get_signals(info); | 2534 | get_signals(info); |
| 2535 | 2535 | ||
| 2536 | if (info->netcount || | 2536 | if (info->netcount || |
| 2537 | (info->port.tty && info->port.tty->termios->c_cflag & CREAD)) | 2537 | (info->port.tty && info->port.tty->termios.c_cflag & CREAD)) |
| 2538 | rx_start(info); | 2538 | rx_start(info); |
| 2539 | 2539 | ||
| 2540 | spin_unlock_irqrestore(&info->lock,flags); | 2540 | spin_unlock_irqrestore(&info->lock,flags); |
| @@ -2548,11 +2548,11 @@ static void change_params(struct slgt_info *info) | |||
| 2548 | unsigned cflag; | 2548 | unsigned cflag; |
| 2549 | int bits_per_char; | 2549 | int bits_per_char; |
| 2550 | 2550 | ||
| 2551 | if (!info->port.tty || !info->port.tty->termios) | 2551 | if (!info->port.tty) |
| 2552 | return; | 2552 | return; |
| 2553 | DBGINFO(("%s change_params\n", info->device_name)); | 2553 | DBGINFO(("%s change_params\n", info->device_name)); |
| 2554 | 2554 | ||
| 2555 | cflag = info->port.tty->termios->c_cflag; | 2555 | cflag = info->port.tty->termios.c_cflag; |
| 2556 | 2556 | ||
| 2557 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 2557 | /* if B0 rate (hangup) specified then negate DTR and RTS */ |
| 2558 | /* otherwise assert DTR and RTS */ | 2558 | /* otherwise assert DTR and RTS */ |
| @@ -3292,7 +3292,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
| 3292 | return 0; | 3292 | return 0; |
| 3293 | } | 3293 | } |
| 3294 | 3294 | ||
| 3295 | if (tty->termios->c_cflag & CLOCAL) | 3295 | if (tty->termios.c_cflag & CLOCAL) |
| 3296 | do_clocal = true; | 3296 | do_clocal = true; |
| 3297 | 3297 | ||
| 3298 | /* Wait for carrier detect and the line to become | 3298 | /* Wait for carrier detect and the line to become |
| @@ -3314,7 +3314,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
| 3314 | port->blocked_open++; | 3314 | port->blocked_open++; |
| 3315 | 3315 | ||
| 3316 | while (1) { | 3316 | while (1) { |
| 3317 | if ((tty->termios->c_cflag & CBAUD)) | 3317 | if ((tty->termios.c_cflag & CBAUD)) |
| 3318 | tty_port_raise_dtr_rts(port); | 3318 | tty_port_raise_dtr_rts(port); |
| 3319 | 3319 | ||
| 3320 | set_current_state(TASK_INTERRUPTIBLE); | 3320 | set_current_state(TASK_INTERRUPTIBLE); |
| @@ -3336,9 +3336,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
| 3336 | } | 3336 | } |
| 3337 | 3337 | ||
| 3338 | DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); | 3338 | DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); |
| 3339 | tty_unlock(); | 3339 | tty_unlock(tty); |
| 3340 | schedule(); | 3340 | schedule(); |
| 3341 | tty_lock(); | 3341 | tty_lock(tty); |
| 3342 | } | 3342 | } |
| 3343 | 3343 | ||
| 3344 | set_current_state(TASK_RUNNING); | 3344 | set_current_state(TASK_RUNNING); |
| @@ -3689,8 +3689,11 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
| 3689 | } | 3689 | } |
| 3690 | } | 3690 | } |
| 3691 | 3691 | ||
| 3692 | for (i=0; i < port_count; ++i) | 3692 | for (i = 0; i < port_count; ++i) { |
| 3693 | tty_register_device(serial_driver, port_array[i]->line, &(port_array[i]->pdev->dev)); | 3693 | struct slgt_info *info = port_array[i]; |
| 3694 | tty_port_register_device(&info->port, serial_driver, info->line, | ||
| 3695 | &info->pdev->dev); | ||
| 3696 | } | ||
| 3694 | } | 3697 | } |
| 3695 | 3698 | ||
| 3696 | static int __devinit init_one(struct pci_dev *dev, | 3699 | static int __devinit init_one(struct pci_dev *dev, |
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index a3dddc12d2fe..f17d9f3d84a2 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c | |||
| @@ -711,15 +711,11 @@ static void ldisc_receive_buf(struct tty_struct *tty, | |||
| 711 | 711 | ||
| 712 | /* tty callbacks */ | 712 | /* tty callbacks */ |
| 713 | 713 | ||
| 714 | /* Called when a port is opened. Init and enable port. | 714 | static int install(struct tty_driver *driver, struct tty_struct *tty) |
| 715 | */ | ||
| 716 | static int open(struct tty_struct *tty, struct file *filp) | ||
| 717 | { | 715 | { |
| 718 | SLMP_INFO *info; | 716 | SLMP_INFO *info; |
| 719 | int retval, line; | 717 | int line = tty->index; |
| 720 | unsigned long flags; | ||
| 721 | 718 | ||
| 722 | line = tty->index; | ||
| 723 | if (line >= synclinkmp_device_count) { | 719 | if (line >= synclinkmp_device_count) { |
| 724 | printk("%s(%d): open with invalid line #%d.\n", | 720 | printk("%s(%d): open with invalid line #%d.\n", |
| 725 | __FILE__,__LINE__,line); | 721 | __FILE__,__LINE__,line); |
| @@ -727,17 +723,30 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
| 727 | } | 723 | } |
| 728 | 724 | ||
| 729 | info = synclinkmp_device_list; | 725 | info = synclinkmp_device_list; |
| 730 | while(info && info->line != line) | 726 | while (info && info->line != line) |
| 731 | info = info->next_device; | 727 | info = info->next_device; |
| 732 | if (sanity_check(info, tty->name, "open")) | 728 | if (sanity_check(info, tty->name, "open")) |
| 733 | return -ENODEV; | 729 | return -ENODEV; |
| 734 | if ( info->init_error ) { | 730 | if (info->init_error) { |
| 735 | printk("%s(%d):%s device is not allocated, init error=%d\n", | 731 | printk("%s(%d):%s device is not allocated, init error=%d\n", |
| 736 | __FILE__,__LINE__,info->device_name,info->init_error); | 732 | __FILE__, __LINE__, info->device_name, |
| 733 | info->init_error); | ||
| 737 | return -ENODEV; | 734 | return -ENODEV; |
| 738 | } | 735 | } |
| 739 | 736 | ||
| 740 | tty->driver_data = info; | 737 | tty->driver_data = info; |
| 738 | |||
| 739 | return tty_port_install(&info->port, driver, tty); | ||
| 740 | } | ||
| 741 | |||
| 742 | /* Called when a port is opened. Init and enable port. | ||
| 743 | */ | ||
| 744 | static int open(struct tty_struct *tty, struct file *filp) | ||
| 745 | { | ||
| 746 | SLMP_INFO *info = tty->driver_data; | ||
| 747 | unsigned long flags; | ||
| 748 | int retval; | ||
| 749 | |||
| 741 | info->port.tty = tty; | 750 | info->port.tty = tty; |
| 742 | 751 | ||
| 743 | if (debug_level >= DEBUG_LEVEL_INFO) | 752 | if (debug_level >= DEBUG_LEVEL_INFO) |
| @@ -873,7 +882,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 873 | 882 | ||
| 874 | /* Handle transition to B0 status */ | 883 | /* Handle transition to B0 status */ |
| 875 | if (old_termios->c_cflag & CBAUD && | 884 | if (old_termios->c_cflag & CBAUD && |
| 876 | !(tty->termios->c_cflag & CBAUD)) { | 885 | !(tty->termios.c_cflag & CBAUD)) { |
| 877 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 886 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); |
| 878 | spin_lock_irqsave(&info->lock,flags); | 887 | spin_lock_irqsave(&info->lock,flags); |
| 879 | set_signals(info); | 888 | set_signals(info); |
| @@ -882,9 +891,9 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 882 | 891 | ||
| 883 | /* Handle transition away from B0 status */ | 892 | /* Handle transition away from B0 status */ |
| 884 | if (!(old_termios->c_cflag & CBAUD) && | 893 | if (!(old_termios->c_cflag & CBAUD) && |
| 885 | tty->termios->c_cflag & CBAUD) { | 894 | tty->termios.c_cflag & CBAUD) { |
| 886 | info->serial_signals |= SerialSignal_DTR; | 895 | info->serial_signals |= SerialSignal_DTR; |
| 887 | if (!(tty->termios->c_cflag & CRTSCTS) || | 896 | if (!(tty->termios.c_cflag & CRTSCTS) || |
| 888 | !test_bit(TTY_THROTTLED, &tty->flags)) { | 897 | !test_bit(TTY_THROTTLED, &tty->flags)) { |
| 889 | info->serial_signals |= SerialSignal_RTS; | 898 | info->serial_signals |= SerialSignal_RTS; |
| 890 | } | 899 | } |
| @@ -895,7 +904,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
| 895 | 904 | ||
| 896 | /* Handle turning off CRTSCTS */ | 905 | /* Handle turning off CRTSCTS */ |
| 897 | if (old_termios->c_cflag & CRTSCTS && | 906 | if (old_termios->c_cflag & CRTSCTS && |
| 898 | !(tty->termios->c_cflag & CRTSCTS)) { | 907 | !(tty->termios.c_cflag & CRTSCTS)) { |
| 899 | tty->hw_stopped = 0; | 908 | tty->hw_stopped = 0; |
| 900 | tx_release(tty); | 909 | tx_release(tty); |
| 901 | } | 910 | } |
| @@ -1473,7 +1482,7 @@ static void throttle(struct tty_struct * tty) | |||
| 1473 | if (I_IXOFF(tty)) | 1482 | if (I_IXOFF(tty)) |
| 1474 | send_xchar(tty, STOP_CHAR(tty)); | 1483 | send_xchar(tty, STOP_CHAR(tty)); |
| 1475 | 1484 | ||
| 1476 | if (tty->termios->c_cflag & CRTSCTS) { | 1485 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1477 | spin_lock_irqsave(&info->lock,flags); | 1486 | spin_lock_irqsave(&info->lock,flags); |
| 1478 | info->serial_signals &= ~SerialSignal_RTS; | 1487 | info->serial_signals &= ~SerialSignal_RTS; |
| 1479 | set_signals(info); | 1488 | set_signals(info); |
| @@ -1502,7 +1511,7 @@ static void unthrottle(struct tty_struct * tty) | |||
| 1502 | send_xchar(tty, START_CHAR(tty)); | 1511 | send_xchar(tty, START_CHAR(tty)); |
| 1503 | } | 1512 | } |
| 1504 | 1513 | ||
| 1505 | if (tty->termios->c_cflag & CRTSCTS) { | 1514 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1506 | spin_lock_irqsave(&info->lock,flags); | 1515 | spin_lock_irqsave(&info->lock,flags); |
| 1507 | info->serial_signals |= SerialSignal_RTS; | 1516 | info->serial_signals |= SerialSignal_RTS; |
| 1508 | set_signals(info); | 1517 | set_signals(info); |
| @@ -2491,7 +2500,7 @@ static void isr_io_pin( SLMP_INFO *info, u16 status ) | |||
| 2491 | } | 2500 | } |
| 2492 | } | 2501 | } |
| 2493 | 2502 | ||
| 2494 | if ( (info->port.flags & ASYNC_CTS_FLOW) && | 2503 | if (tty_port_cts_enabled(&info->port) && |
| 2495 | (status & MISCSTATUS_CTS_LATCHED) ) { | 2504 | (status & MISCSTATUS_CTS_LATCHED) ) { |
| 2496 | if ( info->port.tty ) { | 2505 | if ( info->port.tty ) { |
| 2497 | if (info->port.tty->hw_stopped) { | 2506 | if (info->port.tty->hw_stopped) { |
| @@ -2708,7 +2717,7 @@ static void shutdown(SLMP_INFO * info) | |||
| 2708 | 2717 | ||
| 2709 | reset_port(info); | 2718 | reset_port(info); |
| 2710 | 2719 | ||
| 2711 | if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) { | 2720 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { |
| 2712 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 2721 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); |
| 2713 | set_signals(info); | 2722 | set_signals(info); |
| 2714 | } | 2723 | } |
| @@ -2749,7 +2758,7 @@ static void program_hw(SLMP_INFO *info) | |||
| 2749 | 2758 | ||
| 2750 | get_signals(info); | 2759 | get_signals(info); |
| 2751 | 2760 | ||
| 2752 | if (info->netcount || (info->port.tty && info->port.tty->termios->c_cflag & CREAD) ) | 2761 | if (info->netcount || (info->port.tty && info->port.tty->termios.c_cflag & CREAD) ) |
| 2753 | rx_start(info); | 2762 | rx_start(info); |
| 2754 | 2763 | ||
| 2755 | spin_unlock_irqrestore(&info->lock,flags); | 2764 | spin_unlock_irqrestore(&info->lock,flags); |
| @@ -2762,14 +2771,14 @@ static void change_params(SLMP_INFO *info) | |||
| 2762 | unsigned cflag; | 2771 | unsigned cflag; |
| 2763 | int bits_per_char; | 2772 | int bits_per_char; |
| 2764 | 2773 | ||
| 2765 | if (!info->port.tty || !info->port.tty->termios) | 2774 | if (!info->port.tty) |
| 2766 | return; | 2775 | return; |
| 2767 | 2776 | ||
| 2768 | if (debug_level >= DEBUG_LEVEL_INFO) | 2777 | if (debug_level >= DEBUG_LEVEL_INFO) |
| 2769 | printk("%s(%d):%s change_params()\n", | 2778 | printk("%s(%d):%s change_params()\n", |
| 2770 | __FILE__,__LINE__, info->device_name ); | 2779 | __FILE__,__LINE__, info->device_name ); |
| 2771 | 2780 | ||
| 2772 | cflag = info->port.tty->termios->c_cflag; | 2781 | cflag = info->port.tty->termios.c_cflag; |
| 2773 | 2782 | ||
| 2774 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 2783 | /* if B0 rate (hangup) specified then negate DTR and RTS */ |
| 2775 | /* otherwise assert DTR and RTS */ | 2784 | /* otherwise assert DTR and RTS */ |
| @@ -3306,7 +3315,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
| 3306 | return 0; | 3315 | return 0; |
| 3307 | } | 3316 | } |
| 3308 | 3317 | ||
| 3309 | if (tty->termios->c_cflag & CLOCAL) | 3318 | if (tty->termios.c_cflag & CLOCAL) |
| 3310 | do_clocal = true; | 3319 | do_clocal = true; |
| 3311 | 3320 | ||
| 3312 | /* Wait for carrier detect and the line to become | 3321 | /* Wait for carrier detect and the line to become |
| @@ -3332,7 +3341,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
| 3332 | port->blocked_open++; | 3341 | port->blocked_open++; |
| 3333 | 3342 | ||
| 3334 | while (1) { | 3343 | while (1) { |
| 3335 | if (tty->termios->c_cflag & CBAUD) | 3344 | if (tty->termios.c_cflag & CBAUD) |
| 3336 | tty_port_raise_dtr_rts(port); | 3345 | tty_port_raise_dtr_rts(port); |
| 3337 | 3346 | ||
| 3338 | set_current_state(TASK_INTERRUPTIBLE); | 3347 | set_current_state(TASK_INTERRUPTIBLE); |
| @@ -3357,9 +3366,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
| 3357 | printk("%s(%d):%s block_til_ready() count=%d\n", | 3366 | printk("%s(%d):%s block_til_ready() count=%d\n", |
| 3358 | __FILE__,__LINE__, tty->driver->name, port->count ); | 3367 | __FILE__,__LINE__, tty->driver->name, port->count ); |
| 3359 | 3368 | ||
| 3360 | tty_unlock(); | 3369 | tty_unlock(tty); |
| 3361 | schedule(); | 3370 | schedule(); |
| 3362 | tty_lock(); | 3371 | tty_lock(tty); |
| 3363 | } | 3372 | } |
| 3364 | 3373 | ||
| 3365 | set_current_state(TASK_RUNNING); | 3374 | set_current_state(TASK_RUNNING); |
| @@ -3881,6 +3890,7 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
| 3881 | } | 3890 | } |
| 3882 | 3891 | ||
| 3883 | static const struct tty_operations ops = { | 3892 | static const struct tty_operations ops = { |
| 3893 | .install = install, | ||
| 3884 | .open = open, | 3894 | .open = open, |
| 3885 | .close = close, | 3895 | .close = close, |
| 3886 | .write = write, | 3896 | .write = write, |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b425c79675ad..8a5a8b064616 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
| @@ -181,10 +181,13 @@ struct tty_struct *alloc_tty_struct(void) | |||
| 181 | 181 | ||
| 182 | void free_tty_struct(struct tty_struct *tty) | 182 | void free_tty_struct(struct tty_struct *tty) |
| 183 | { | 183 | { |
| 184 | if (!tty) | ||
| 185 | return; | ||
| 184 | if (tty->dev) | 186 | if (tty->dev) |
| 185 | put_device(tty->dev); | 187 | put_device(tty->dev); |
| 186 | kfree(tty->write_buf); | 188 | kfree(tty->write_buf); |
| 187 | tty_buffer_free_all(tty); | 189 | tty_buffer_free_all(tty); |
| 190 | tty->magic = 0xDEADDEAD; | ||
| 188 | kfree(tty); | 191 | kfree(tty); |
| 189 | } | 192 | } |
| 190 | 193 | ||
| @@ -573,7 +576,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
| 573 | } | 576 | } |
| 574 | spin_unlock(&redirect_lock); | 577 | spin_unlock(&redirect_lock); |
| 575 | 578 | ||
| 576 | tty_lock(); | 579 | tty_lock(tty); |
| 577 | 580 | ||
| 578 | /* some functions below drop BTM, so we need this bit */ | 581 | /* some functions below drop BTM, so we need this bit */ |
| 579 | set_bit(TTY_HUPPING, &tty->flags); | 582 | set_bit(TTY_HUPPING, &tty->flags); |
| @@ -666,7 +669,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
| 666 | clear_bit(TTY_HUPPING, &tty->flags); | 669 | clear_bit(TTY_HUPPING, &tty->flags); |
| 667 | tty_ldisc_enable(tty); | 670 | tty_ldisc_enable(tty); |
| 668 | 671 | ||
| 669 | tty_unlock(); | 672 | tty_unlock(tty); |
| 670 | 673 | ||
| 671 | if (f) | 674 | if (f) |
| 672 | fput(f); | 675 | fput(f); |
| @@ -1103,12 +1106,12 @@ void tty_write_message(struct tty_struct *tty, char *msg) | |||
| 1103 | { | 1106 | { |
| 1104 | if (tty) { | 1107 | if (tty) { |
| 1105 | mutex_lock(&tty->atomic_write_lock); | 1108 | mutex_lock(&tty->atomic_write_lock); |
| 1106 | tty_lock(); | 1109 | tty_lock(tty); |
| 1107 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { | 1110 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { |
| 1108 | tty_unlock(); | 1111 | tty_unlock(tty); |
| 1109 | tty->ops->write(tty, msg, strlen(msg)); | 1112 | tty->ops->write(tty, msg, strlen(msg)); |
| 1110 | } else | 1113 | } else |
| 1111 | tty_unlock(); | 1114 | tty_unlock(tty); |
| 1112 | tty_write_unlock(tty); | 1115 | tty_write_unlock(tty); |
| 1113 | } | 1116 | } |
| 1114 | return; | 1117 | return; |
| @@ -1213,7 +1216,10 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p) | |||
| 1213 | */ | 1216 | */ |
| 1214 | static void tty_line_name(struct tty_driver *driver, int index, char *p) | 1217 | static void tty_line_name(struct tty_driver *driver, int index, char *p) |
| 1215 | { | 1218 | { |
| 1216 | sprintf(p, "%s%d", driver->name, index + driver->name_base); | 1219 | if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE) |
| 1220 | strcpy(p, driver->name); | ||
| 1221 | else | ||
| 1222 | sprintf(p, "%s%d", driver->name, index + driver->name_base); | ||
| 1217 | } | 1223 | } |
| 1218 | 1224 | ||
| 1219 | /** | 1225 | /** |
| @@ -1249,21 +1255,19 @@ int tty_init_termios(struct tty_struct *tty) | |||
| 1249 | struct ktermios *tp; | 1255 | struct ktermios *tp; |
| 1250 | int idx = tty->index; | 1256 | int idx = tty->index; |
| 1251 | 1257 | ||
| 1252 | tp = tty->driver->termios[idx]; | 1258 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
| 1253 | if (tp == NULL) { | 1259 | tty->termios = tty->driver->init_termios; |
| 1254 | tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | 1260 | else { |
| 1255 | if (tp == NULL) | 1261 | /* Check for lazy saved data */ |
| 1256 | return -ENOMEM; | 1262 | tp = tty->driver->termios[idx]; |
| 1257 | memcpy(tp, &tty->driver->init_termios, | 1263 | if (tp != NULL) |
| 1258 | sizeof(struct ktermios)); | 1264 | tty->termios = *tp; |
| 1259 | tty->driver->termios[idx] = tp; | 1265 | else |
| 1266 | tty->termios = tty->driver->init_termios; | ||
| 1260 | } | 1267 | } |
| 1261 | tty->termios = tp; | ||
| 1262 | tty->termios_locked = tp + 1; | ||
| 1263 | |||
| 1264 | /* Compatibility until drivers always set this */ | 1268 | /* Compatibility until drivers always set this */ |
| 1265 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | 1269 | tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios); |
| 1266 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | 1270 | tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios); |
| 1267 | return 0; | 1271 | return 0; |
| 1268 | } | 1272 | } |
| 1269 | EXPORT_SYMBOL_GPL(tty_init_termios); | 1273 | EXPORT_SYMBOL_GPL(tty_init_termios); |
| @@ -1403,10 +1407,18 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
| 1403 | } | 1407 | } |
| 1404 | initialize_tty_struct(tty, driver, idx); | 1408 | initialize_tty_struct(tty, driver, idx); |
| 1405 | 1409 | ||
| 1410 | tty_lock(tty); | ||
| 1406 | retval = tty_driver_install_tty(driver, tty); | 1411 | retval = tty_driver_install_tty(driver, tty); |
| 1407 | if (retval < 0) | 1412 | if (retval < 0) |
| 1408 | goto err_deinit_tty; | 1413 | goto err_deinit_tty; |
| 1409 | 1414 | ||
| 1415 | if (!tty->port) | ||
| 1416 | tty->port = driver->ports[idx]; | ||
| 1417 | |||
| 1418 | WARN_RATELIMIT(!tty->port, | ||
| 1419 | "%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n", | ||
| 1420 | __func__, tty->driver->name); | ||
| 1421 | |||
| 1410 | /* | 1422 | /* |
| 1411 | * Structures all installed ... call the ldisc open routines. | 1423 | * Structures all installed ... call the ldisc open routines. |
| 1412 | * If we fail here just call release_tty to clean up. No need | 1424 | * If we fail here just call release_tty to clean up. No need |
| @@ -1415,9 +1427,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
| 1415 | retval = tty_ldisc_setup(tty, tty->link); | 1427 | retval = tty_ldisc_setup(tty, tty->link); |
| 1416 | if (retval) | 1428 | if (retval) |
| 1417 | goto err_release_tty; | 1429 | goto err_release_tty; |
| 1430 | /* Return the tty locked so that it cannot vanish under the caller */ | ||
| 1418 | return tty; | 1431 | return tty; |
| 1419 | 1432 | ||
| 1420 | err_deinit_tty: | 1433 | err_deinit_tty: |
| 1434 | tty_unlock(tty); | ||
| 1421 | deinitialize_tty_struct(tty); | 1435 | deinitialize_tty_struct(tty); |
| 1422 | free_tty_struct(tty); | 1436 | free_tty_struct(tty); |
| 1423 | err_module_put: | 1437 | err_module_put: |
| @@ -1426,6 +1440,7 @@ err_module_put: | |||
| 1426 | 1440 | ||
| 1427 | /* call the tty release_tty routine to clean out this slot */ | 1441 | /* call the tty release_tty routine to clean out this slot */ |
| 1428 | err_release_tty: | 1442 | err_release_tty: |
| 1443 | tty_unlock(tty); | ||
| 1429 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " | 1444 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " |
| 1430 | "clearing slot %d\n", idx); | 1445 | "clearing slot %d\n", idx); |
| 1431 | release_tty(tty, idx); | 1446 | release_tty(tty, idx); |
| @@ -1436,22 +1451,25 @@ void tty_free_termios(struct tty_struct *tty) | |||
| 1436 | { | 1451 | { |
| 1437 | struct ktermios *tp; | 1452 | struct ktermios *tp; |
| 1438 | int idx = tty->index; | 1453 | int idx = tty->index; |
| 1439 | /* Kill this flag and push into drivers for locking etc */ | 1454 | |
| 1440 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | 1455 | /* If the port is going to reset then it has no termios to save */ |
| 1441 | /* FIXME: Locking on ->termios array */ | 1456 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
| 1442 | tp = tty->termios; | 1457 | return; |
| 1443 | tty->driver->termios[idx] = NULL; | 1458 | |
| 1444 | kfree(tp); | 1459 | /* Stash the termios data */ |
| 1460 | tp = tty->driver->termios[idx]; | ||
| 1461 | if (tp == NULL) { | ||
| 1462 | tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
| 1463 | if (tp == NULL) { | ||
| 1464 | pr_warn("tty: no memory to save termios state.\n"); | ||
| 1465 | return; | ||
| 1466 | } | ||
| 1467 | tty->driver->termios[idx] = tp; | ||
| 1445 | } | 1468 | } |
| 1469 | *tp = tty->termios; | ||
| 1446 | } | 1470 | } |
| 1447 | EXPORT_SYMBOL(tty_free_termios); | 1471 | EXPORT_SYMBOL(tty_free_termios); |
| 1448 | 1472 | ||
| 1449 | void tty_shutdown(struct tty_struct *tty) | ||
| 1450 | { | ||
| 1451 | tty_driver_remove_tty(tty->driver, tty); | ||
| 1452 | tty_free_termios(tty); | ||
| 1453 | } | ||
| 1454 | EXPORT_SYMBOL(tty_shutdown); | ||
| 1455 | 1473 | ||
| 1456 | /** | 1474 | /** |
| 1457 | * release_one_tty - release tty structure memory | 1475 | * release_one_tty - release tty structure memory |
| @@ -1462,7 +1480,6 @@ EXPORT_SYMBOL(tty_shutdown); | |||
| 1462 | * in use. It also gets called when setup of a device fails. | 1480 | * in use. It also gets called when setup of a device fails. |
| 1463 | * | 1481 | * |
| 1464 | * Locking: | 1482 | * Locking: |
| 1465 | * tty_mutex - sometimes only | ||
| 1466 | * takes the file list lock internally when working on the list | 1483 | * takes the file list lock internally when working on the list |
| 1467 | * of ttys that the driver keeps. | 1484 | * of ttys that the driver keeps. |
| 1468 | * | 1485 | * |
| @@ -1495,11 +1512,6 @@ static void queue_release_one_tty(struct kref *kref) | |||
| 1495 | { | 1512 | { |
| 1496 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); | 1513 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); |
| 1497 | 1514 | ||
| 1498 | if (tty->ops->shutdown) | ||
| 1499 | tty->ops->shutdown(tty); | ||
| 1500 | else | ||
| 1501 | tty_shutdown(tty); | ||
| 1502 | |||
| 1503 | /* The hangup queue is now free so we can reuse it rather than | 1515 | /* The hangup queue is now free so we can reuse it rather than |
| 1504 | waste a chunk of memory for each port */ | 1516 | waste a chunk of memory for each port */ |
| 1505 | INIT_WORK(&tty->hangup_work, release_one_tty); | 1517 | INIT_WORK(&tty->hangup_work, release_one_tty); |
| @@ -1528,16 +1540,20 @@ EXPORT_SYMBOL(tty_kref_put); | |||
| 1528 | * and decrement the refcount of the backing module. | 1540 | * and decrement the refcount of the backing module. |
| 1529 | * | 1541 | * |
| 1530 | * Locking: | 1542 | * Locking: |
| 1531 | * tty_mutex - sometimes only | 1543 | * tty_mutex |
| 1532 | * takes the file list lock internally when working on the list | 1544 | * takes the file list lock internally when working on the list |
| 1533 | * of ttys that the driver keeps. | 1545 | * of ttys that the driver keeps. |
| 1534 | * FIXME: should we require tty_mutex is held here ?? | ||
| 1535 | * | 1546 | * |
| 1536 | */ | 1547 | */ |
| 1537 | static void release_tty(struct tty_struct *tty, int idx) | 1548 | static void release_tty(struct tty_struct *tty, int idx) |
| 1538 | { | 1549 | { |
| 1539 | /* This should always be true but check for the moment */ | 1550 | /* This should always be true but check for the moment */ |
| 1540 | WARN_ON(tty->index != idx); | 1551 | WARN_ON(tty->index != idx); |
| 1552 | WARN_ON(!mutex_is_locked(&tty_mutex)); | ||
| 1553 | if (tty->ops->shutdown) | ||
| 1554 | tty->ops->shutdown(tty); | ||
| 1555 | tty_free_termios(tty); | ||
| 1556 | tty_driver_remove_tty(tty->driver, tty); | ||
| 1541 | 1557 | ||
| 1542 | if (tty->link) | 1558 | if (tty->link) |
| 1543 | tty_kref_put(tty->link); | 1559 | tty_kref_put(tty->link); |
| @@ -1572,22 +1588,12 @@ static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, | |||
| 1572 | __func__, idx, tty->name); | 1588 | __func__, idx, tty->name); |
| 1573 | return -1; | 1589 | return -1; |
| 1574 | } | 1590 | } |
| 1575 | if (tty->termios != tty->driver->termios[idx]) { | ||
| 1576 | printk(KERN_DEBUG "%s: driver.termios[%d] not termios for (%s)\n", | ||
| 1577 | __func__, idx, tty->name); | ||
| 1578 | return -1; | ||
| 1579 | } | ||
| 1580 | if (tty->driver->other) { | 1591 | if (tty->driver->other) { |
| 1581 | if (o_tty != tty->driver->other->ttys[idx]) { | 1592 | if (o_tty != tty->driver->other->ttys[idx]) { |
| 1582 | printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s)\n", | 1593 | printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s)\n", |
| 1583 | __func__, idx, tty->name); | 1594 | __func__, idx, tty->name); |
| 1584 | return -1; | 1595 | return -1; |
| 1585 | } | 1596 | } |
| 1586 | if (o_tty->termios != tty->driver->other->termios[idx]) { | ||
| 1587 | printk(KERN_DEBUG "%s: other->termios[%d] not o_termios for (%s)\n", | ||
| 1588 | __func__, idx, tty->name); | ||
| 1589 | return -1; | ||
| 1590 | } | ||
| 1591 | if (o_tty->link != tty) { | 1597 | if (o_tty->link != tty) { |
| 1592 | printk(KERN_DEBUG "%s: bad pty pointers\n", __func__); | 1598 | printk(KERN_DEBUG "%s: bad pty pointers\n", __func__); |
| 1593 | return -1; | 1599 | return -1; |
| @@ -1628,7 +1634,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1628 | if (tty_paranoia_check(tty, inode, __func__)) | 1634 | if (tty_paranoia_check(tty, inode, __func__)) |
| 1629 | return 0; | 1635 | return 0; |
| 1630 | 1636 | ||
| 1631 | tty_lock(); | 1637 | tty_lock(tty); |
| 1632 | check_tty_count(tty, __func__); | 1638 | check_tty_count(tty, __func__); |
| 1633 | 1639 | ||
| 1634 | __tty_fasync(-1, filp, 0); | 1640 | __tty_fasync(-1, filp, 0); |
| @@ -1637,10 +1643,11 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1637 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1643 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
| 1638 | tty->driver->subtype == PTY_TYPE_MASTER); | 1644 | tty->driver->subtype == PTY_TYPE_MASTER); |
| 1639 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; | 1645 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; |
| 1646 | /* Review: parallel close */ | ||
| 1640 | o_tty = tty->link; | 1647 | o_tty = tty->link; |
| 1641 | 1648 | ||
| 1642 | if (tty_release_checks(tty, o_tty, idx)) { | 1649 | if (tty_release_checks(tty, o_tty, idx)) { |
| 1643 | tty_unlock(); | 1650 | tty_unlock(tty); |
| 1644 | return 0; | 1651 | return 0; |
| 1645 | } | 1652 | } |
| 1646 | 1653 | ||
| @@ -1652,7 +1659,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1652 | if (tty->ops->close) | 1659 | if (tty->ops->close) |
| 1653 | tty->ops->close(tty, filp); | 1660 | tty->ops->close(tty, filp); |
| 1654 | 1661 | ||
| 1655 | tty_unlock(); | 1662 | tty_unlock(tty); |
| 1656 | /* | 1663 | /* |
| 1657 | * Sanity check: if tty->count is going to zero, there shouldn't be | 1664 | * Sanity check: if tty->count is going to zero, there shouldn't be |
| 1658 | * any waiters on tty->read_wait or tty->write_wait. We test the | 1665 | * any waiters on tty->read_wait or tty->write_wait. We test the |
| @@ -1675,7 +1682,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1675 | opens on /dev/tty */ | 1682 | opens on /dev/tty */ |
| 1676 | 1683 | ||
| 1677 | mutex_lock(&tty_mutex); | 1684 | mutex_lock(&tty_mutex); |
| 1678 | tty_lock(); | 1685 | tty_lock_pair(tty, o_tty); |
| 1679 | tty_closing = tty->count <= 1; | 1686 | tty_closing = tty->count <= 1; |
| 1680 | o_tty_closing = o_tty && | 1687 | o_tty_closing = o_tty && |
| 1681 | (o_tty->count <= (pty_master ? 1 : 0)); | 1688 | (o_tty->count <= (pty_master ? 1 : 0)); |
| @@ -1706,7 +1713,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1706 | 1713 | ||
| 1707 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", | 1714 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", |
| 1708 | __func__, tty_name(tty, buf)); | 1715 | __func__, tty_name(tty, buf)); |
| 1709 | tty_unlock(); | 1716 | tty_unlock_pair(tty, o_tty); |
| 1710 | mutex_unlock(&tty_mutex); | 1717 | mutex_unlock(&tty_mutex); |
| 1711 | schedule(); | 1718 | schedule(); |
| 1712 | } | 1719 | } |
| @@ -1715,6 +1722,9 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1715 | * The closing flags are now consistent with the open counts on | 1722 | * The closing flags are now consistent with the open counts on |
| 1716 | * both sides, and we've completed the last operation that could | 1723 | * both sides, and we've completed the last operation that could |
| 1717 | * block, so it's safe to proceed with closing. | 1724 | * block, so it's safe to proceed with closing. |
| 1725 | * | ||
| 1726 | * We must *not* drop the tty_mutex until we ensure that a further | ||
| 1727 | * entry into tty_open can not pick up this tty. | ||
| 1718 | */ | 1728 | */ |
| 1719 | if (pty_master) { | 1729 | if (pty_master) { |
| 1720 | if (--o_tty->count < 0) { | 1730 | if (--o_tty->count < 0) { |
| @@ -1766,12 +1776,13 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1766 | } | 1776 | } |
| 1767 | 1777 | ||
| 1768 | mutex_unlock(&tty_mutex); | 1778 | mutex_unlock(&tty_mutex); |
| 1779 | tty_unlock_pair(tty, o_tty); | ||
| 1780 | /* At this point the TTY_CLOSING flag should ensure a dead tty | ||
| 1781 | cannot be re-opened by a racing opener */ | ||
| 1769 | 1782 | ||
| 1770 | /* check whether both sides are closing ... */ | 1783 | /* check whether both sides are closing ... */ |
| 1771 | if (!tty_closing || (o_tty && !o_tty_closing)) { | 1784 | if (!tty_closing || (o_tty && !o_tty_closing)) |
| 1772 | tty_unlock(); | ||
| 1773 | return 0; | 1785 | return 0; |
| 1774 | } | ||
| 1775 | 1786 | ||
| 1776 | #ifdef TTY_DEBUG_HANGUP | 1787 | #ifdef TTY_DEBUG_HANGUP |
| 1777 | printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); | 1788 | printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); |
| @@ -1782,14 +1793,17 @@ int tty_release(struct inode *inode, struct file *filp) | |||
| 1782 | tty_ldisc_release(tty, o_tty); | 1793 | tty_ldisc_release(tty, o_tty); |
| 1783 | /* | 1794 | /* |
| 1784 | * The release_tty function takes care of the details of clearing | 1795 | * The release_tty function takes care of the details of clearing |
| 1785 | * the slots and preserving the termios structure. | 1796 | * the slots and preserving the termios structure. The tty_unlock_pair |
| 1797 | * should be safe as we keep a kref while the tty is locked (so the | ||
| 1798 | * unlock never unlocks a freed tty). | ||
| 1786 | */ | 1799 | */ |
| 1800 | mutex_lock(&tty_mutex); | ||
| 1787 | release_tty(tty, idx); | 1801 | release_tty(tty, idx); |
| 1802 | mutex_unlock(&tty_mutex); | ||
| 1788 | 1803 | ||
| 1789 | /* Make this pty number available for reallocation */ | 1804 | /* Make this pty number available for reallocation */ |
| 1790 | if (devpts) | 1805 | if (devpts) |
| 1791 | devpts_kill_index(inode, idx); | 1806 | devpts_kill_index(inode, idx); |
| 1792 | tty_unlock(); | ||
| 1793 | return 0; | 1807 | return 0; |
| 1794 | } | 1808 | } |
| 1795 | 1809 | ||
| @@ -1893,6 +1907,9 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | |||
| 1893 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. | 1907 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. |
| 1894 | * tty->count should protect the rest. | 1908 | * tty->count should protect the rest. |
| 1895 | * ->siglock protects ->signal/->sighand | 1909 | * ->siglock protects ->signal/->sighand |
| 1910 | * | ||
| 1911 | * Note: the tty_unlock/lock cases without a ref are only safe due to | ||
| 1912 | * tty_mutex | ||
| 1896 | */ | 1913 | */ |
| 1897 | 1914 | ||
| 1898 | static int tty_open(struct inode *inode, struct file *filp) | 1915 | static int tty_open(struct inode *inode, struct file *filp) |
| @@ -1916,8 +1933,7 @@ retry_open: | |||
| 1916 | retval = 0; | 1933 | retval = 0; |
| 1917 | 1934 | ||
| 1918 | mutex_lock(&tty_mutex); | 1935 | mutex_lock(&tty_mutex); |
| 1919 | tty_lock(); | 1936 | /* This is protected by the tty_mutex */ |
| 1920 | |||
| 1921 | tty = tty_open_current_tty(device, filp); | 1937 | tty = tty_open_current_tty(device, filp); |
| 1922 | if (IS_ERR(tty)) { | 1938 | if (IS_ERR(tty)) { |
| 1923 | retval = PTR_ERR(tty); | 1939 | retval = PTR_ERR(tty); |
| @@ -1938,17 +1954,19 @@ retry_open: | |||
| 1938 | } | 1954 | } |
| 1939 | 1955 | ||
| 1940 | if (tty) { | 1956 | if (tty) { |
| 1957 | tty_lock(tty); | ||
| 1941 | retval = tty_reopen(tty); | 1958 | retval = tty_reopen(tty); |
| 1942 | if (retval) | 1959 | if (retval < 0) { |
| 1960 | tty_unlock(tty); | ||
| 1943 | tty = ERR_PTR(retval); | 1961 | tty = ERR_PTR(retval); |
| 1944 | } else | 1962 | } |
| 1963 | } else /* Returns with the tty_lock held for now */ | ||
| 1945 | tty = tty_init_dev(driver, index); | 1964 | tty = tty_init_dev(driver, index); |
| 1946 | 1965 | ||
| 1947 | mutex_unlock(&tty_mutex); | 1966 | mutex_unlock(&tty_mutex); |
| 1948 | if (driver) | 1967 | if (driver) |
| 1949 | tty_driver_kref_put(driver); | 1968 | tty_driver_kref_put(driver); |
| 1950 | if (IS_ERR(tty)) { | 1969 | if (IS_ERR(tty)) { |
| 1951 | tty_unlock(); | ||
| 1952 | retval = PTR_ERR(tty); | 1970 | retval = PTR_ERR(tty); |
| 1953 | goto err_file; | 1971 | goto err_file; |
| 1954 | } | 1972 | } |
| @@ -1977,7 +1995,7 @@ retry_open: | |||
| 1977 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, | 1995 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, |
| 1978 | retval, tty->name); | 1996 | retval, tty->name); |
| 1979 | #endif | 1997 | #endif |
| 1980 | tty_unlock(); /* need to call tty_release without BTM */ | 1998 | tty_unlock(tty); /* need to call tty_release without BTM */ |
| 1981 | tty_release(inode, filp); | 1999 | tty_release(inode, filp); |
| 1982 | if (retval != -ERESTARTSYS) | 2000 | if (retval != -ERESTARTSYS) |
| 1983 | return retval; | 2001 | return retval; |
| @@ -1989,17 +2007,15 @@ retry_open: | |||
| 1989 | /* | 2007 | /* |
| 1990 | * Need to reset f_op in case a hangup happened. | 2008 | * Need to reset f_op in case a hangup happened. |
| 1991 | */ | 2009 | */ |
| 1992 | tty_lock(); | ||
| 1993 | if (filp->f_op == &hung_up_tty_fops) | 2010 | if (filp->f_op == &hung_up_tty_fops) |
| 1994 | filp->f_op = &tty_fops; | 2011 | filp->f_op = &tty_fops; |
| 1995 | tty_unlock(); | ||
| 1996 | goto retry_open; | 2012 | goto retry_open; |
| 1997 | } | 2013 | } |
| 1998 | tty_unlock(); | 2014 | tty_unlock(tty); |
| 1999 | 2015 | ||
| 2000 | 2016 | ||
| 2001 | mutex_lock(&tty_mutex); | 2017 | mutex_lock(&tty_mutex); |
| 2002 | tty_lock(); | 2018 | tty_lock(tty); |
| 2003 | spin_lock_irq(¤t->sighand->siglock); | 2019 | spin_lock_irq(¤t->sighand->siglock); |
| 2004 | if (!noctty && | 2020 | if (!noctty && |
| 2005 | current->signal->leader && | 2021 | current->signal->leader && |
| @@ -2007,11 +2023,10 @@ retry_open: | |||
| 2007 | tty->session == NULL) | 2023 | tty->session == NULL) |
| 2008 | __proc_set_tty(current, tty); | 2024 | __proc_set_tty(current, tty); |
| 2009 | spin_unlock_irq(¤t->sighand->siglock); | 2025 | spin_unlock_irq(¤t->sighand->siglock); |
| 2010 | tty_unlock(); | 2026 | tty_unlock(tty); |
| 2011 | mutex_unlock(&tty_mutex); | 2027 | mutex_unlock(&tty_mutex); |
| 2012 | return 0; | 2028 | return 0; |
| 2013 | err_unlock: | 2029 | err_unlock: |
| 2014 | tty_unlock(); | ||
| 2015 | mutex_unlock(&tty_mutex); | 2030 | mutex_unlock(&tty_mutex); |
| 2016 | /* after locks to avoid deadlock */ | 2031 | /* after locks to avoid deadlock */ |
| 2017 | if (!IS_ERR_OR_NULL(driver)) | 2032 | if (!IS_ERR_OR_NULL(driver)) |
| @@ -2094,10 +2109,13 @@ out: | |||
| 2094 | 2109 | ||
| 2095 | static int tty_fasync(int fd, struct file *filp, int on) | 2110 | static int tty_fasync(int fd, struct file *filp, int on) |
| 2096 | { | 2111 | { |
| 2112 | struct tty_struct *tty = file_tty(filp); | ||
| 2097 | int retval; | 2113 | int retval; |
| 2098 | tty_lock(); | 2114 | |
| 2115 | tty_lock(tty); | ||
| 2099 | retval = __tty_fasync(fd, filp, on); | 2116 | retval = __tty_fasync(fd, filp, on); |
| 2100 | tty_unlock(); | 2117 | tty_unlock(tty); |
| 2118 | |||
| 2101 | return retval; | 2119 | return retval; |
| 2102 | } | 2120 | } |
| 2103 | 2121 | ||
| @@ -2756,7 +2774,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 2756 | if (ld->ops->ioctl) { | 2774 | if (ld->ops->ioctl) { |
| 2757 | retval = ld->ops->ioctl(tty, file, cmd, arg); | 2775 | retval = ld->ops->ioctl(tty, file, cmd, arg); |
| 2758 | if (retval == -ENOIOCTLCMD) | 2776 | if (retval == -ENOIOCTLCMD) |
| 2759 | retval = -EINVAL; | 2777 | retval = -ENOTTY; |
| 2760 | } | 2778 | } |
| 2761 | tty_ldisc_deref(ld); | 2779 | tty_ldisc_deref(ld); |
| 2762 | return retval; | 2780 | return retval; |
| @@ -2934,6 +2952,7 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
| 2934 | tty->pgrp = NULL; | 2952 | tty->pgrp = NULL; |
| 2935 | tty->overrun_time = jiffies; | 2953 | tty->overrun_time = jiffies; |
| 2936 | tty_buffer_init(tty); | 2954 | tty_buffer_init(tty); |
| 2955 | mutex_init(&tty->legacy_mutex); | ||
| 2937 | mutex_init(&tty->termios_mutex); | 2956 | mutex_init(&tty->termios_mutex); |
| 2938 | mutex_init(&tty->ldisc_mutex); | 2957 | mutex_init(&tty->ldisc_mutex); |
| 2939 | init_waitqueue_head(&tty->write_wait); | 2958 | init_waitqueue_head(&tty->write_wait); |
| @@ -2991,6 +3010,15 @@ EXPORT_SYMBOL_GPL(tty_put_char); | |||
| 2991 | 3010 | ||
| 2992 | struct class *tty_class; | 3011 | struct class *tty_class; |
| 2993 | 3012 | ||
| 3013 | static int tty_cdev_add(struct tty_driver *driver, dev_t dev, | ||
| 3014 | unsigned int index, unsigned int count) | ||
| 3015 | { | ||
| 3016 | /* init here, since reused cdevs cause crashes */ | ||
| 3017 | cdev_init(&driver->cdevs[index], &tty_fops); | ||
| 3018 | driver->cdevs[index].owner = driver->owner; | ||
| 3019 | return cdev_add(&driver->cdevs[index], dev, count); | ||
| 3020 | } | ||
| 3021 | |||
| 2994 | /** | 3022 | /** |
| 2995 | * tty_register_device - register a tty device | 3023 | * tty_register_device - register a tty device |
| 2996 | * @driver: the tty driver that describes the tty device | 3024 | * @driver: the tty driver that describes the tty device |
| @@ -3013,8 +3041,46 @@ struct class *tty_class; | |||
| 3013 | struct device *tty_register_device(struct tty_driver *driver, unsigned index, | 3041 | struct device *tty_register_device(struct tty_driver *driver, unsigned index, |
| 3014 | struct device *device) | 3042 | struct device *device) |
| 3015 | { | 3043 | { |
| 3044 | return tty_register_device_attr(driver, index, device, NULL, NULL); | ||
| 3045 | } | ||
| 3046 | EXPORT_SYMBOL(tty_register_device); | ||
| 3047 | |||
| 3048 | static void tty_device_create_release(struct device *dev) | ||
| 3049 | { | ||
| 3050 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); | ||
| 3051 | kfree(dev); | ||
| 3052 | } | ||
| 3053 | |||
| 3054 | /** | ||
| 3055 | * tty_register_device_attr - register a tty device | ||
| 3056 | * @driver: the tty driver that describes the tty device | ||
| 3057 | * @index: the index in the tty driver for this tty device | ||
| 3058 | * @device: a struct device that is associated with this tty device. | ||
| 3059 | * This field is optional, if there is no known struct device | ||
| 3060 | * for this tty device it can be set to NULL safely. | ||
| 3061 | * @drvdata: Driver data to be set to device. | ||
| 3062 | * @attr_grp: Attribute group to be set on device. | ||
| 3063 | * | ||
| 3064 | * Returns a pointer to the struct device for this tty device | ||
| 3065 | * (or ERR_PTR(-EFOO) on error). | ||
| 3066 | * | ||
| 3067 | * This call is required to be made to register an individual tty device | ||
| 3068 | * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If | ||
| 3069 | * that bit is not set, this function should not be called by a tty | ||
| 3070 | * driver. | ||
| 3071 | * | ||
| 3072 | * Locking: ?? | ||
| 3073 | */ | ||
| 3074 | struct device *tty_register_device_attr(struct tty_driver *driver, | ||
| 3075 | unsigned index, struct device *device, | ||
| 3076 | void *drvdata, | ||
| 3077 | const struct attribute_group **attr_grp) | ||
| 3078 | { | ||
| 3016 | char name[64]; | 3079 | char name[64]; |
| 3017 | dev_t dev = MKDEV(driver->major, driver->minor_start) + index; | 3080 | dev_t devt = MKDEV(driver->major, driver->minor_start) + index; |
| 3081 | struct device *dev = NULL; | ||
| 3082 | int retval = -ENODEV; | ||
| 3083 | bool cdev = false; | ||
| 3018 | 3084 | ||
| 3019 | if (index >= driver->num) { | 3085 | if (index >= driver->num) { |
| 3020 | printk(KERN_ERR "Attempt to register invalid tty line number " | 3086 | printk(KERN_ERR "Attempt to register invalid tty line number " |
| @@ -3027,9 +3093,40 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index, | |||
| 3027 | else | 3093 | else |
| 3028 | tty_line_name(driver, index, name); | 3094 | tty_line_name(driver, index, name); |
| 3029 | 3095 | ||
| 3030 | return device_create(tty_class, device, dev, NULL, name); | 3096 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) { |
| 3097 | retval = tty_cdev_add(driver, devt, index, 1); | ||
| 3098 | if (retval) | ||
| 3099 | goto error; | ||
| 3100 | cdev = true; | ||
| 3101 | } | ||
| 3102 | |||
| 3103 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 3104 | if (!dev) { | ||
| 3105 | retval = -ENOMEM; | ||
| 3106 | goto error; | ||
| 3107 | } | ||
| 3108 | |||
| 3109 | dev->devt = devt; | ||
| 3110 | dev->class = tty_class; | ||
| 3111 | dev->parent = device; | ||
| 3112 | dev->release = tty_device_create_release; | ||
| 3113 | dev_set_name(dev, "%s", name); | ||
| 3114 | dev->groups = attr_grp; | ||
| 3115 | dev_set_drvdata(dev, drvdata); | ||
| 3116 | |||
| 3117 | retval = device_register(dev); | ||
| 3118 | if (retval) | ||
| 3119 | goto error; | ||
| 3120 | |||
| 3121 | return dev; | ||
| 3122 | |||
| 3123 | error: | ||
| 3124 | put_device(dev); | ||
| 3125 | if (cdev) | ||
| 3126 | cdev_del(&driver->cdevs[index]); | ||
| 3127 | return ERR_PTR(retval); | ||
| 3031 | } | 3128 | } |
| 3032 | EXPORT_SYMBOL(tty_register_device); | 3129 | EXPORT_SYMBOL_GPL(tty_register_device_attr); |
| 3033 | 3130 | ||
| 3034 | /** | 3131 | /** |
| 3035 | * tty_unregister_device - unregister a tty device | 3132 | * tty_unregister_device - unregister a tty device |
| @@ -3046,31 +3143,82 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) | |||
| 3046 | { | 3143 | { |
| 3047 | device_destroy(tty_class, | 3144 | device_destroy(tty_class, |
| 3048 | MKDEV(driver->major, driver->minor_start) + index); | 3145 | MKDEV(driver->major, driver->minor_start) + index); |
| 3146 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) | ||
| 3147 | cdev_del(&driver->cdevs[index]); | ||
| 3049 | } | 3148 | } |
| 3050 | EXPORT_SYMBOL(tty_unregister_device); | 3149 | EXPORT_SYMBOL(tty_unregister_device); |
| 3051 | 3150 | ||
| 3052 | struct tty_driver *__alloc_tty_driver(int lines, struct module *owner) | 3151 | /** |
| 3152 | * __tty_alloc_driver -- allocate tty driver | ||
| 3153 | * @lines: count of lines this driver can handle at most | ||
| 3154 | * @owner: module which is repsonsible for this driver | ||
| 3155 | * @flags: some of TTY_DRIVER_* flags, will be set in driver->flags | ||
| 3156 | * | ||
| 3157 | * This should not be called directly, some of the provided macros should be | ||
| 3158 | * used instead. Use IS_ERR and friends on @retval. | ||
| 3159 | */ | ||
| 3160 | struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, | ||
| 3161 | unsigned long flags) | ||
| 3053 | { | 3162 | { |
| 3054 | struct tty_driver *driver; | 3163 | struct tty_driver *driver; |
| 3164 | unsigned int cdevs = 1; | ||
| 3165 | int err; | ||
| 3166 | |||
| 3167 | if (!lines || (flags & TTY_DRIVER_UNNUMBERED_NODE && lines > 1)) | ||
| 3168 | return ERR_PTR(-EINVAL); | ||
| 3055 | 3169 | ||
| 3056 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); | 3170 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); |
| 3057 | if (driver) { | 3171 | if (!driver) |
| 3058 | kref_init(&driver->kref); | 3172 | return ERR_PTR(-ENOMEM); |
| 3059 | driver->magic = TTY_DRIVER_MAGIC; | 3173 | |
| 3060 | driver->num = lines; | 3174 | kref_init(&driver->kref); |
| 3061 | driver->owner = owner; | 3175 | driver->magic = TTY_DRIVER_MAGIC; |
| 3062 | /* later we'll move allocation of tables here */ | 3176 | driver->num = lines; |
| 3177 | driver->owner = owner; | ||
| 3178 | driver->flags = flags; | ||
| 3179 | |||
| 3180 | if (!(flags & TTY_DRIVER_DEVPTS_MEM)) { | ||
| 3181 | driver->ttys = kcalloc(lines, sizeof(*driver->ttys), | ||
| 3182 | GFP_KERNEL); | ||
| 3183 | driver->termios = kcalloc(lines, sizeof(*driver->termios), | ||
| 3184 | GFP_KERNEL); | ||
| 3185 | if (!driver->ttys || !driver->termios) { | ||
| 3186 | err = -ENOMEM; | ||
| 3187 | goto err_free_all; | ||
| 3188 | } | ||
| 3063 | } | 3189 | } |
| 3190 | |||
| 3191 | if (!(flags & TTY_DRIVER_DYNAMIC_ALLOC)) { | ||
| 3192 | driver->ports = kcalloc(lines, sizeof(*driver->ports), | ||
| 3193 | GFP_KERNEL); | ||
| 3194 | if (!driver->ports) { | ||
| 3195 | err = -ENOMEM; | ||
| 3196 | goto err_free_all; | ||
| 3197 | } | ||
| 3198 | cdevs = lines; | ||
| 3199 | } | ||
| 3200 | |||
| 3201 | driver->cdevs = kcalloc(cdevs, sizeof(*driver->cdevs), GFP_KERNEL); | ||
| 3202 | if (!driver->cdevs) { | ||
| 3203 | err = -ENOMEM; | ||
| 3204 | goto err_free_all; | ||
| 3205 | } | ||
| 3206 | |||
| 3064 | return driver; | 3207 | return driver; |
| 3208 | err_free_all: | ||
| 3209 | kfree(driver->ports); | ||
| 3210 | kfree(driver->ttys); | ||
| 3211 | kfree(driver->termios); | ||
| 3212 | kfree(driver); | ||
| 3213 | return ERR_PTR(err); | ||
| 3065 | } | 3214 | } |
| 3066 | EXPORT_SYMBOL(__alloc_tty_driver); | 3215 | EXPORT_SYMBOL(__tty_alloc_driver); |
| 3067 | 3216 | ||
| 3068 | static void destruct_tty_driver(struct kref *kref) | 3217 | static void destruct_tty_driver(struct kref *kref) |
| 3069 | { | 3218 | { |
| 3070 | struct tty_driver *driver = container_of(kref, struct tty_driver, kref); | 3219 | struct tty_driver *driver = container_of(kref, struct tty_driver, kref); |
| 3071 | int i; | 3220 | int i; |
| 3072 | struct ktermios *tp; | 3221 | struct ktermios *tp; |
| 3073 | void *p; | ||
| 3074 | 3222 | ||
| 3075 | if (driver->flags & TTY_DRIVER_INSTALLED) { | 3223 | if (driver->flags & TTY_DRIVER_INSTALLED) { |
| 3076 | /* | 3224 | /* |
| @@ -3087,13 +3235,14 @@ static void destruct_tty_driver(struct kref *kref) | |||
| 3087 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) | 3235 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) |
| 3088 | tty_unregister_device(driver, i); | 3236 | tty_unregister_device(driver, i); |
| 3089 | } | 3237 | } |
| 3090 | p = driver->ttys; | ||
| 3091 | proc_tty_unregister_driver(driver); | 3238 | proc_tty_unregister_driver(driver); |
| 3092 | driver->ttys = NULL; | 3239 | if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) |
| 3093 | driver->termios = NULL; | 3240 | cdev_del(&driver->cdevs[0]); |
| 3094 | kfree(p); | ||
| 3095 | cdev_del(&driver->cdev); | ||
| 3096 | } | 3241 | } |
| 3242 | kfree(driver->cdevs); | ||
| 3243 | kfree(driver->ports); | ||
| 3244 | kfree(driver->termios); | ||
| 3245 | kfree(driver->ttys); | ||
| 3097 | kfree(driver); | 3246 | kfree(driver); |
| 3098 | } | 3247 | } |
| 3099 | 3248 | ||
| @@ -3124,15 +3273,8 @@ int tty_register_driver(struct tty_driver *driver) | |||
| 3124 | int error; | 3273 | int error; |
| 3125 | int i; | 3274 | int i; |
| 3126 | dev_t dev; | 3275 | dev_t dev; |
| 3127 | void **p = NULL; | ||
| 3128 | struct device *d; | 3276 | struct device *d; |
| 3129 | 3277 | ||
| 3130 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { | ||
| 3131 | p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL); | ||
| 3132 | if (!p) | ||
| 3133 | return -ENOMEM; | ||
| 3134 | } | ||
| 3135 | |||
| 3136 | if (!driver->major) { | 3278 | if (!driver->major) { |
| 3137 | error = alloc_chrdev_region(&dev, driver->minor_start, | 3279 | error = alloc_chrdev_region(&dev, driver->minor_start, |
| 3138 | driver->num, driver->name); | 3280 | driver->num, driver->name); |
| @@ -3144,28 +3286,13 @@ int tty_register_driver(struct tty_driver *driver) | |||
| 3144 | dev = MKDEV(driver->major, driver->minor_start); | 3286 | dev = MKDEV(driver->major, driver->minor_start); |
| 3145 | error = register_chrdev_region(dev, driver->num, driver->name); | 3287 | error = register_chrdev_region(dev, driver->num, driver->name); |
| 3146 | } | 3288 | } |
| 3147 | if (error < 0) { | 3289 | if (error < 0) |
| 3148 | kfree(p); | 3290 | goto err; |
| 3149 | return error; | ||
| 3150 | } | ||
| 3151 | 3291 | ||
| 3152 | if (p) { | 3292 | if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) { |
| 3153 | driver->ttys = (struct tty_struct **)p; | 3293 | error = tty_cdev_add(driver, dev, 0, driver->num); |
| 3154 | driver->termios = (struct ktermios **)(p + driver->num); | 3294 | if (error) |
| 3155 | } else { | 3295 | goto err_unreg_char; |
| 3156 | driver->ttys = NULL; | ||
| 3157 | driver->termios = NULL; | ||
| 3158 | } | ||
| 3159 | |||
| 3160 | cdev_init(&driver->cdev, &tty_fops); | ||
| 3161 | driver->cdev.owner = driver->owner; | ||
| 3162 | error = cdev_add(&driver->cdev, dev, driver->num); | ||
| 3163 | if (error) { | ||
| 3164 | unregister_chrdev_region(dev, driver->num); | ||
| 3165 | driver->ttys = NULL; | ||
| 3166 | driver->termios = NULL; | ||
| 3167 | kfree(p); | ||
| 3168 | return error; | ||
| 3169 | } | 3296 | } |
| 3170 | 3297 | ||
| 3171 | mutex_lock(&tty_mutex); | 3298 | mutex_lock(&tty_mutex); |
| @@ -3177,7 +3304,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
| 3177 | d = tty_register_device(driver, i, NULL); | 3304 | d = tty_register_device(driver, i, NULL); |
| 3178 | if (IS_ERR(d)) { | 3305 | if (IS_ERR(d)) { |
| 3179 | error = PTR_ERR(d); | 3306 | error = PTR_ERR(d); |
| 3180 | goto err; | 3307 | goto err_unreg_devs; |
| 3181 | } | 3308 | } |
| 3182 | } | 3309 | } |
| 3183 | } | 3310 | } |
| @@ -3185,7 +3312,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
| 3185 | driver->flags |= TTY_DRIVER_INSTALLED; | 3312 | driver->flags |= TTY_DRIVER_INSTALLED; |
| 3186 | return 0; | 3313 | return 0; |
| 3187 | 3314 | ||
| 3188 | err: | 3315 | err_unreg_devs: |
| 3189 | for (i--; i >= 0; i--) | 3316 | for (i--; i >= 0; i--) |
| 3190 | tty_unregister_device(driver, i); | 3317 | tty_unregister_device(driver, i); |
| 3191 | 3318 | ||
| @@ -3193,13 +3320,11 @@ err: | |||
| 3193 | list_del(&driver->tty_drivers); | 3320 | list_del(&driver->tty_drivers); |
| 3194 | mutex_unlock(&tty_mutex); | 3321 | mutex_unlock(&tty_mutex); |
| 3195 | 3322 | ||
| 3323 | err_unreg_char: | ||
| 3196 | unregister_chrdev_region(dev, driver->num); | 3324 | unregister_chrdev_region(dev, driver->num); |
| 3197 | driver->ttys = NULL; | 3325 | err: |
| 3198 | driver->termios = NULL; | ||
| 3199 | kfree(p); | ||
| 3200 | return error; | 3326 | return error; |
| 3201 | } | 3327 | } |
| 3202 | |||
| 3203 | EXPORT_SYMBOL(tty_register_driver); | 3328 | EXPORT_SYMBOL(tty_register_driver); |
| 3204 | 3329 | ||
| 3205 | /* | 3330 | /* |
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index a1b9a2f68567..12b1fa0f4f86 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
| @@ -410,7 +410,7 @@ EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); | |||
| 410 | 410 | ||
| 411 | void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) | 411 | void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) |
| 412 | { | 412 | { |
| 413 | tty_termios_encode_baud_rate(tty->termios, ibaud, obaud); | 413 | tty_termios_encode_baud_rate(&tty->termios, ibaud, obaud); |
| 414 | } | 414 | } |
| 415 | EXPORT_SYMBOL_GPL(tty_encode_baud_rate); | 415 | EXPORT_SYMBOL_GPL(tty_encode_baud_rate); |
| 416 | 416 | ||
| @@ -427,7 +427,7 @@ EXPORT_SYMBOL_GPL(tty_encode_baud_rate); | |||
| 427 | 427 | ||
| 428 | speed_t tty_get_baud_rate(struct tty_struct *tty) | 428 | speed_t tty_get_baud_rate(struct tty_struct *tty) |
| 429 | { | 429 | { |
| 430 | speed_t baud = tty_termios_baud_rate(tty->termios); | 430 | speed_t baud = tty_termios_baud_rate(&tty->termios); |
| 431 | 431 | ||
| 432 | if (baud == 38400 && tty->alt_speed) { | 432 | if (baud == 38400 && tty->alt_speed) { |
| 433 | if (!tty->warned) { | 433 | if (!tty->warned) { |
| @@ -509,14 +509,14 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
| 509 | /* FIXME: we need to decide on some locking/ordering semantics | 509 | /* FIXME: we need to decide on some locking/ordering semantics |
| 510 | for the set_termios notification eventually */ | 510 | for the set_termios notification eventually */ |
| 511 | mutex_lock(&tty->termios_mutex); | 511 | mutex_lock(&tty->termios_mutex); |
| 512 | old_termios = *tty->termios; | 512 | old_termios = tty->termios; |
| 513 | *tty->termios = *new_termios; | 513 | tty->termios = *new_termios; |
| 514 | unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); | 514 | unset_locked_termios(&tty->termios, &old_termios, &tty->termios_locked); |
| 515 | 515 | ||
| 516 | /* See if packet mode change of state. */ | 516 | /* See if packet mode change of state. */ |
| 517 | if (tty->link && tty->link->packet) { | 517 | if (tty->link && tty->link->packet) { |
| 518 | int extproc = (old_termios.c_lflag & EXTPROC) | | 518 | int extproc = (old_termios.c_lflag & EXTPROC) | |
| 519 | (tty->termios->c_lflag & EXTPROC); | 519 | (tty->termios.c_lflag & EXTPROC); |
| 520 | int old_flow = ((old_termios.c_iflag & IXON) && | 520 | int old_flow = ((old_termios.c_iflag & IXON) && |
| 521 | (old_termios.c_cc[VSTOP] == '\023') && | 521 | (old_termios.c_cc[VSTOP] == '\023') && |
| 522 | (old_termios.c_cc[VSTART] == '\021')); | 522 | (old_termios.c_cc[VSTART] == '\021')); |
| @@ -542,7 +542,7 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
| 542 | if (tty->ops->set_termios) | 542 | if (tty->ops->set_termios) |
| 543 | (*tty->ops->set_termios)(tty, &old_termios); | 543 | (*tty->ops->set_termios)(tty, &old_termios); |
| 544 | else | 544 | else |
| 545 | tty_termios_copy_hw(tty->termios, &old_termios); | 545 | tty_termios_copy_hw(&tty->termios, &old_termios); |
| 546 | 546 | ||
| 547 | ld = tty_ldisc_ref(tty); | 547 | ld = tty_ldisc_ref(tty); |
| 548 | if (ld != NULL) { | 548 | if (ld != NULL) { |
| @@ -578,7 +578,7 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) | |||
| 578 | return retval; | 578 | return retval; |
| 579 | 579 | ||
| 580 | mutex_lock(&tty->termios_mutex); | 580 | mutex_lock(&tty->termios_mutex); |
| 581 | memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios)); | 581 | tmp_termios = tty->termios; |
| 582 | mutex_unlock(&tty->termios_mutex); | 582 | mutex_unlock(&tty->termios_mutex); |
| 583 | 583 | ||
| 584 | if (opt & TERMIOS_TERMIO) { | 584 | if (opt & TERMIOS_TERMIO) { |
| @@ -632,14 +632,14 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) | |||
| 632 | static void copy_termios(struct tty_struct *tty, struct ktermios *kterm) | 632 | static void copy_termios(struct tty_struct *tty, struct ktermios *kterm) |
| 633 | { | 633 | { |
| 634 | mutex_lock(&tty->termios_mutex); | 634 | mutex_lock(&tty->termios_mutex); |
| 635 | memcpy(kterm, tty->termios, sizeof(struct ktermios)); | 635 | *kterm = tty->termios; |
| 636 | mutex_unlock(&tty->termios_mutex); | 636 | mutex_unlock(&tty->termios_mutex); |
| 637 | } | 637 | } |
| 638 | 638 | ||
| 639 | static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm) | 639 | static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm) |
| 640 | { | 640 | { |
| 641 | mutex_lock(&tty->termios_mutex); | 641 | mutex_lock(&tty->termios_mutex); |
| 642 | memcpy(kterm, tty->termios_locked, sizeof(struct ktermios)); | 642 | *kterm = tty->termios_locked; |
| 643 | mutex_unlock(&tty->termios_mutex); | 643 | mutex_unlock(&tty->termios_mutex); |
| 644 | } | 644 | } |
| 645 | 645 | ||
| @@ -707,16 +707,16 @@ static int get_sgflags(struct tty_struct *tty) | |||
| 707 | { | 707 | { |
| 708 | int flags = 0; | 708 | int flags = 0; |
| 709 | 709 | ||
| 710 | if (!(tty->termios->c_lflag & ICANON)) { | 710 | if (!(tty->termios.c_lflag & ICANON)) { |
| 711 | if (tty->termios->c_lflag & ISIG) | 711 | if (tty->termios.c_lflag & ISIG) |
| 712 | flags |= 0x02; /* cbreak */ | 712 | flags |= 0x02; /* cbreak */ |
| 713 | else | 713 | else |
| 714 | flags |= 0x20; /* raw */ | 714 | flags |= 0x20; /* raw */ |
| 715 | } | 715 | } |
| 716 | if (tty->termios->c_lflag & ECHO) | 716 | if (tty->termios.c_lflag & ECHO) |
| 717 | flags |= 0x08; /* echo */ | 717 | flags |= 0x08; /* echo */ |
| 718 | if (tty->termios->c_oflag & OPOST) | 718 | if (tty->termios.c_oflag & OPOST) |
| 719 | if (tty->termios->c_oflag & ONLCR) | 719 | if (tty->termios.c_oflag & ONLCR) |
| 720 | flags |= 0x10; /* crmod */ | 720 | flags |= 0x10; /* crmod */ |
| 721 | return flags; | 721 | return flags; |
| 722 | } | 722 | } |
| @@ -726,10 +726,10 @@ static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) | |||
| 726 | struct sgttyb tmp; | 726 | struct sgttyb tmp; |
| 727 | 727 | ||
| 728 | mutex_lock(&tty->termios_mutex); | 728 | mutex_lock(&tty->termios_mutex); |
| 729 | tmp.sg_ispeed = tty->termios->c_ispeed; | 729 | tmp.sg_ispeed = tty->termios.c_ispeed; |
| 730 | tmp.sg_ospeed = tty->termios->c_ospeed; | 730 | tmp.sg_ospeed = tty->termios.c_ospeed; |
| 731 | tmp.sg_erase = tty->termios->c_cc[VERASE]; | 731 | tmp.sg_erase = tty->termios.c_cc[VERASE]; |
| 732 | tmp.sg_kill = tty->termios->c_cc[VKILL]; | 732 | tmp.sg_kill = tty->termios.c_cc[VKILL]; |
| 733 | tmp.sg_flags = get_sgflags(tty); | 733 | tmp.sg_flags = get_sgflags(tty); |
| 734 | mutex_unlock(&tty->termios_mutex); | 734 | mutex_unlock(&tty->termios_mutex); |
| 735 | 735 | ||
| @@ -787,7 +787,7 @@ static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) | |||
| 787 | return -EFAULT; | 787 | return -EFAULT; |
| 788 | 788 | ||
| 789 | mutex_lock(&tty->termios_mutex); | 789 | mutex_lock(&tty->termios_mutex); |
| 790 | termios = *tty->termios; | 790 | termios = tty->termios; |
| 791 | termios.c_cc[VERASE] = tmp.sg_erase; | 791 | termios.c_cc[VERASE] = tmp.sg_erase; |
| 792 | termios.c_cc[VKILL] = tmp.sg_kill; | 792 | termios.c_cc[VKILL] = tmp.sg_kill; |
| 793 | set_sgflags(&termios, tmp.sg_flags); | 793 | set_sgflags(&termios, tmp.sg_flags); |
| @@ -808,12 +808,12 @@ static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars) | |||
| 808 | struct tchars tmp; | 808 | struct tchars tmp; |
| 809 | 809 | ||
| 810 | mutex_lock(&tty->termios_mutex); | 810 | mutex_lock(&tty->termios_mutex); |
| 811 | tmp.t_intrc = tty->termios->c_cc[VINTR]; | 811 | tmp.t_intrc = tty->termios.c_cc[VINTR]; |
| 812 | tmp.t_quitc = tty->termios->c_cc[VQUIT]; | 812 | tmp.t_quitc = tty->termios.c_cc[VQUIT]; |
| 813 | tmp.t_startc = tty->termios->c_cc[VSTART]; | 813 | tmp.t_startc = tty->termios.c_cc[VSTART]; |
| 814 | tmp.t_stopc = tty->termios->c_cc[VSTOP]; | 814 | tmp.t_stopc = tty->termios.c_cc[VSTOP]; |
| 815 | tmp.t_eofc = tty->termios->c_cc[VEOF]; | 815 | tmp.t_eofc = tty->termios.c_cc[VEOF]; |
| 816 | tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */ | 816 | tmp.t_brkc = tty->termios.c_cc[VEOL2]; /* what is brkc anyway? */ |
| 817 | mutex_unlock(&tty->termios_mutex); | 817 | mutex_unlock(&tty->termios_mutex); |
| 818 | return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 818 | return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
| 819 | } | 819 | } |
| @@ -825,12 +825,12 @@ static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars) | |||
| 825 | if (copy_from_user(&tmp, tchars, sizeof(tmp))) | 825 | if (copy_from_user(&tmp, tchars, sizeof(tmp))) |
| 826 | return -EFAULT; | 826 | return -EFAULT; |
| 827 | mutex_lock(&tty->termios_mutex); | 827 | mutex_lock(&tty->termios_mutex); |
| 828 | tty->termios->c_cc[VINTR] = tmp.t_intrc; | 828 | tty->termios.c_cc[VINTR] = tmp.t_intrc; |
| 829 | tty->termios->c_cc[VQUIT] = tmp.t_quitc; | 829 | tty->termios.c_cc[VQUIT] = tmp.t_quitc; |
| 830 | tty->termios->c_cc[VSTART] = tmp.t_startc; | 830 | tty->termios.c_cc[VSTART] = tmp.t_startc; |
| 831 | tty->termios->c_cc[VSTOP] = tmp.t_stopc; | 831 | tty->termios.c_cc[VSTOP] = tmp.t_stopc; |
| 832 | tty->termios->c_cc[VEOF] = tmp.t_eofc; | 832 | tty->termios.c_cc[VEOF] = tmp.t_eofc; |
| 833 | tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ | 833 | tty->termios.c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ |
| 834 | mutex_unlock(&tty->termios_mutex); | 834 | mutex_unlock(&tty->termios_mutex); |
| 835 | return 0; | 835 | return 0; |
| 836 | } | 836 | } |
| @@ -842,14 +842,14 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | |||
| 842 | struct ltchars tmp; | 842 | struct ltchars tmp; |
| 843 | 843 | ||
| 844 | mutex_lock(&tty->termios_mutex); | 844 | mutex_lock(&tty->termios_mutex); |
| 845 | tmp.t_suspc = tty->termios->c_cc[VSUSP]; | 845 | tmp.t_suspc = tty->termios.c_cc[VSUSP]; |
| 846 | /* what is dsuspc anyway? */ | 846 | /* what is dsuspc anyway? */ |
| 847 | tmp.t_dsuspc = tty->termios->c_cc[VSUSP]; | 847 | tmp.t_dsuspc = tty->termios.c_cc[VSUSP]; |
| 848 | tmp.t_rprntc = tty->termios->c_cc[VREPRINT]; | 848 | tmp.t_rprntc = tty->termios.c_cc[VREPRINT]; |
| 849 | /* what is flushc anyway? */ | 849 | /* what is flushc anyway? */ |
| 850 | tmp.t_flushc = tty->termios->c_cc[VEOL2]; | 850 | tmp.t_flushc = tty->termios.c_cc[VEOL2]; |
| 851 | tmp.t_werasc = tty->termios->c_cc[VWERASE]; | 851 | tmp.t_werasc = tty->termios.c_cc[VWERASE]; |
| 852 | tmp.t_lnextc = tty->termios->c_cc[VLNEXT]; | 852 | tmp.t_lnextc = tty->termios.c_cc[VLNEXT]; |
| 853 | mutex_unlock(&tty->termios_mutex); | 853 | mutex_unlock(&tty->termios_mutex); |
| 854 | return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 854 | return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
| 855 | } | 855 | } |
| @@ -862,14 +862,14 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | |||
| 862 | return -EFAULT; | 862 | return -EFAULT; |
| 863 | 863 | ||
| 864 | mutex_lock(&tty->termios_mutex); | 864 | mutex_lock(&tty->termios_mutex); |
| 865 | tty->termios->c_cc[VSUSP] = tmp.t_suspc; | 865 | tty->termios.c_cc[VSUSP] = tmp.t_suspc; |
| 866 | /* what is dsuspc anyway? */ | 866 | /* what is dsuspc anyway? */ |
| 867 | tty->termios->c_cc[VEOL2] = tmp.t_dsuspc; | 867 | tty->termios.c_cc[VEOL2] = tmp.t_dsuspc; |
| 868 | tty->termios->c_cc[VREPRINT] = tmp.t_rprntc; | 868 | tty->termios.c_cc[VREPRINT] = tmp.t_rprntc; |
| 869 | /* what is flushc anyway? */ | 869 | /* what is flushc anyway? */ |
| 870 | tty->termios->c_cc[VEOL2] = tmp.t_flushc; | 870 | tty->termios.c_cc[VEOL2] = tmp.t_flushc; |
| 871 | tty->termios->c_cc[VWERASE] = tmp.t_werasc; | 871 | tty->termios.c_cc[VWERASE] = tmp.t_werasc; |
| 872 | tty->termios->c_cc[VLNEXT] = tmp.t_lnextc; | 872 | tty->termios.c_cc[VLNEXT] = tmp.t_lnextc; |
| 873 | mutex_unlock(&tty->termios_mutex); | 873 | mutex_unlock(&tty->termios_mutex); |
| 874 | return 0; | 874 | return 0; |
| 875 | } | 875 | } |
| @@ -920,12 +920,12 @@ static int tty_change_softcar(struct tty_struct *tty, int arg) | |||
| 920 | struct ktermios old; | 920 | struct ktermios old; |
| 921 | 921 | ||
| 922 | mutex_lock(&tty->termios_mutex); | 922 | mutex_lock(&tty->termios_mutex); |
| 923 | old = *tty->termios; | 923 | old = tty->termios; |
| 924 | tty->termios->c_cflag &= ~CLOCAL; | 924 | tty->termios.c_cflag &= ~CLOCAL; |
| 925 | tty->termios->c_cflag |= bit; | 925 | tty->termios.c_cflag |= bit; |
| 926 | if (tty->ops->set_termios) | 926 | if (tty->ops->set_termios) |
| 927 | tty->ops->set_termios(tty, &old); | 927 | tty->ops->set_termios(tty, &old); |
| 928 | if ((tty->termios->c_cflag & CLOCAL) != bit) | 928 | if ((tty->termios.c_cflag & CLOCAL) != bit) |
| 929 | ret = -EINVAL; | 929 | ret = -EINVAL; |
| 930 | mutex_unlock(&tty->termios_mutex); | 930 | mutex_unlock(&tty->termios_mutex); |
| 931 | return ret; | 931 | return ret; |
| @@ -1031,7 +1031,7 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | |||
| 1031 | (struct termios __user *) arg)) | 1031 | (struct termios __user *) arg)) |
| 1032 | return -EFAULT; | 1032 | return -EFAULT; |
| 1033 | mutex_lock(&real_tty->termios_mutex); | 1033 | mutex_lock(&real_tty->termios_mutex); |
| 1034 | memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios)); | 1034 | real_tty->termios_locked = kterm; |
| 1035 | mutex_unlock(&real_tty->termios_mutex); | 1035 | mutex_unlock(&real_tty->termios_mutex); |
| 1036 | return 0; | 1036 | return 0; |
| 1037 | #else | 1037 | #else |
| @@ -1048,7 +1048,7 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | |||
| 1048 | (struct termios __user *) arg)) | 1048 | (struct termios __user *) arg)) |
| 1049 | return -EFAULT; | 1049 | return -EFAULT; |
| 1050 | mutex_lock(&real_tty->termios_mutex); | 1050 | mutex_lock(&real_tty->termios_mutex); |
| 1051 | memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios)); | 1051 | real_tty->termios_locked = kterm; |
| 1052 | mutex_unlock(&real_tty->termios_mutex); | 1052 | mutex_unlock(&real_tty->termios_mutex); |
| 1053 | return ret; | 1053 | return ret; |
| 1054 | #endif | 1054 | #endif |
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 6f99c9959f0c..4d7b56268c79 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
| @@ -413,7 +413,7 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); | |||
| 413 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) | 413 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) |
| 414 | { | 414 | { |
| 415 | mutex_lock(&tty->termios_mutex); | 415 | mutex_lock(&tty->termios_mutex); |
| 416 | tty->termios->c_line = num; | 416 | tty->termios.c_line = num; |
| 417 | mutex_unlock(&tty->termios_mutex); | 417 | mutex_unlock(&tty->termios_mutex); |
| 418 | } | 418 | } |
| 419 | 419 | ||
| @@ -568,7 +568,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
| 568 | if (IS_ERR(new_ldisc)) | 568 | if (IS_ERR(new_ldisc)) |
| 569 | return PTR_ERR(new_ldisc); | 569 | return PTR_ERR(new_ldisc); |
| 570 | 570 | ||
| 571 | tty_lock(); | 571 | tty_lock(tty); |
| 572 | /* | 572 | /* |
| 573 | * We need to look at the tty locking here for pty/tty pairs | 573 | * We need to look at the tty locking here for pty/tty pairs |
| 574 | * when both sides try to change in parallel. | 574 | * when both sides try to change in parallel. |
| @@ -582,12 +582,12 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
| 582 | */ | 582 | */ |
| 583 | 583 | ||
| 584 | if (tty->ldisc->ops->num == ldisc) { | 584 | if (tty->ldisc->ops->num == ldisc) { |
| 585 | tty_unlock(); | 585 | tty_unlock(tty); |
| 586 | tty_ldisc_put(new_ldisc); | 586 | tty_ldisc_put(new_ldisc); |
| 587 | return 0; | 587 | return 0; |
| 588 | } | 588 | } |
| 589 | 589 | ||
| 590 | tty_unlock(); | 590 | tty_unlock(tty); |
| 591 | /* | 591 | /* |
| 592 | * Problem: What do we do if this blocks ? | 592 | * Problem: What do we do if this blocks ? |
| 593 | * We could deadlock here | 593 | * We could deadlock here |
| @@ -595,7 +595,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
| 595 | 595 | ||
| 596 | tty_wait_until_sent(tty, 0); | 596 | tty_wait_until_sent(tty, 0); |
| 597 | 597 | ||
| 598 | tty_lock(); | 598 | tty_lock(tty); |
| 599 | mutex_lock(&tty->ldisc_mutex); | 599 | mutex_lock(&tty->ldisc_mutex); |
| 600 | 600 | ||
| 601 | /* | 601 | /* |
| @@ -605,10 +605,10 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
| 605 | 605 | ||
| 606 | while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) { | 606 | while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) { |
| 607 | mutex_unlock(&tty->ldisc_mutex); | 607 | mutex_unlock(&tty->ldisc_mutex); |
| 608 | tty_unlock(); | 608 | tty_unlock(tty); |
| 609 | wait_event(tty_ldisc_wait, | 609 | wait_event(tty_ldisc_wait, |
| 610 | test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); | 610 | test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); |
| 611 | tty_lock(); | 611 | tty_lock(tty); |
| 612 | mutex_lock(&tty->ldisc_mutex); | 612 | mutex_lock(&tty->ldisc_mutex); |
| 613 | } | 613 | } |
| 614 | 614 | ||
| @@ -623,7 +623,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
| 623 | 623 | ||
| 624 | o_ldisc = tty->ldisc; | 624 | o_ldisc = tty->ldisc; |
| 625 | 625 | ||
| 626 | tty_unlock(); | 626 | tty_unlock(tty); |
| 627 | /* | 627 | /* |
| 628 | * Make sure we don't change while someone holds a | 628 | * Make sure we don't change while someone holds a |
| 629 | * reference to the line discipline. The TTY_LDISC bit | 629 | * reference to the line discipline. The TTY_LDISC bit |
| @@ -650,7 +650,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
| 650 | 650 | ||
| 651 | retval = tty_ldisc_wait_idle(tty, 5 * HZ); | 651 | retval = tty_ldisc_wait_idle(tty, 5 * HZ); |
| 652 | 652 | ||
| 653 | tty_lock(); | 653 | tty_lock(tty); |
| 654 | mutex_lock(&tty->ldisc_mutex); | 654 | mutex_lock(&tty->ldisc_mutex); |
| 655 | 655 | ||
| 656 | /* handle wait idle failure locked */ | 656 | /* handle wait idle failure locked */ |
| @@ -665,7 +665,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
| 665 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); | 665 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); |
| 666 | mutex_unlock(&tty->ldisc_mutex); | 666 | mutex_unlock(&tty->ldisc_mutex); |
| 667 | tty_ldisc_put(new_ldisc); | 667 | tty_ldisc_put(new_ldisc); |
| 668 | tty_unlock(); | 668 | tty_unlock(tty); |
| 669 | return -EIO; | 669 | return -EIO; |
| 670 | } | 670 | } |
| 671 | 671 | ||
| @@ -708,7 +708,7 @@ enable: | |||
| 708 | if (o_work) | 708 | if (o_work) |
| 709 | schedule_work(&o_tty->buf.work); | 709 | schedule_work(&o_tty->buf.work); |
| 710 | mutex_unlock(&tty->ldisc_mutex); | 710 | mutex_unlock(&tty->ldisc_mutex); |
| 711 | tty_unlock(); | 711 | tty_unlock(tty); |
| 712 | return retval; | 712 | return retval; |
| 713 | } | 713 | } |
| 714 | 714 | ||
| @@ -722,9 +722,9 @@ enable: | |||
| 722 | static void tty_reset_termios(struct tty_struct *tty) | 722 | static void tty_reset_termios(struct tty_struct *tty) |
| 723 | { | 723 | { |
| 724 | mutex_lock(&tty->termios_mutex); | 724 | mutex_lock(&tty->termios_mutex); |
| 725 | *tty->termios = tty->driver->init_termios; | 725 | tty->termios = tty->driver->init_termios; |
| 726 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | 726 | tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios); |
| 727 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | 727 | tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios); |
| 728 | mutex_unlock(&tty->termios_mutex); | 728 | mutex_unlock(&tty->termios_mutex); |
| 729 | } | 729 | } |
| 730 | 730 | ||
| @@ -816,11 +816,11 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
| 816 | * need to wait for another function taking the BTM | 816 | * need to wait for another function taking the BTM |
| 817 | */ | 817 | */ |
| 818 | clear_bit(TTY_LDISC, &tty->flags); | 818 | clear_bit(TTY_LDISC, &tty->flags); |
| 819 | tty_unlock(); | 819 | tty_unlock(tty); |
| 820 | cancel_work_sync(&tty->buf.work); | 820 | cancel_work_sync(&tty->buf.work); |
| 821 | mutex_unlock(&tty->ldisc_mutex); | 821 | mutex_unlock(&tty->ldisc_mutex); |
| 822 | retry: | 822 | retry: |
| 823 | tty_lock(); | 823 | tty_lock(tty); |
| 824 | mutex_lock(&tty->ldisc_mutex); | 824 | mutex_lock(&tty->ldisc_mutex); |
| 825 | 825 | ||
| 826 | /* At this point we have a closed ldisc and we want to | 826 | /* At this point we have a closed ldisc and we want to |
| @@ -831,7 +831,7 @@ retry: | |||
| 831 | if (atomic_read(&tty->ldisc->users) != 1) { | 831 | if (atomic_read(&tty->ldisc->users) != 1) { |
| 832 | char cur_n[TASK_COMM_LEN], tty_n[64]; | 832 | char cur_n[TASK_COMM_LEN], tty_n[64]; |
| 833 | long timeout = 3 * HZ; | 833 | long timeout = 3 * HZ; |
| 834 | tty_unlock(); | 834 | tty_unlock(tty); |
| 835 | 835 | ||
| 836 | while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { | 836 | while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { |
| 837 | timeout = MAX_SCHEDULE_TIMEOUT; | 837 | timeout = MAX_SCHEDULE_TIMEOUT; |
| @@ -846,7 +846,7 @@ retry: | |||
| 846 | 846 | ||
| 847 | if (reset == 0) { | 847 | if (reset == 0) { |
| 848 | 848 | ||
| 849 | if (!tty_ldisc_reinit(tty, tty->termios->c_line)) | 849 | if (!tty_ldisc_reinit(tty, tty->termios.c_line)) |
| 850 | err = tty_ldisc_open(tty, tty->ldisc); | 850 | err = tty_ldisc_open(tty, tty->ldisc); |
| 851 | else | 851 | else |
| 852 | err = 1; | 852 | err = 1; |
| @@ -894,6 +894,23 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty) | |||
| 894 | tty_ldisc_enable(tty); | 894 | tty_ldisc_enable(tty); |
| 895 | return 0; | 895 | return 0; |
| 896 | } | 896 | } |
| 897 | |||
| 898 | static void tty_ldisc_kill(struct tty_struct *tty) | ||
| 899 | { | ||
| 900 | mutex_lock(&tty->ldisc_mutex); | ||
| 901 | /* | ||
| 902 | * Now kill off the ldisc | ||
| 903 | */ | ||
| 904 | tty_ldisc_close(tty, tty->ldisc); | ||
| 905 | tty_ldisc_put(tty->ldisc); | ||
| 906 | /* Force an oops if we mess this up */ | ||
| 907 | tty->ldisc = NULL; | ||
| 908 | |||
| 909 | /* Ensure the next open requests the N_TTY ldisc */ | ||
| 910 | tty_set_termios_ldisc(tty, N_TTY); | ||
| 911 | mutex_unlock(&tty->ldisc_mutex); | ||
| 912 | } | ||
| 913 | |||
| 897 | /** | 914 | /** |
| 898 | * tty_ldisc_release - release line discipline | 915 | * tty_ldisc_release - release line discipline |
| 899 | * @tty: tty being shut down | 916 | * @tty: tty being shut down |
| @@ -912,28 +929,21 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
| 912 | * race with the set_ldisc code path. | 929 | * race with the set_ldisc code path. |
| 913 | */ | 930 | */ |
| 914 | 931 | ||
| 915 | tty_unlock(); | 932 | tty_lock_pair(tty, o_tty); |
| 916 | tty_ldisc_halt(tty); | 933 | tty_ldisc_halt(tty); |
| 917 | tty_ldisc_flush_works(tty); | 934 | tty_ldisc_flush_works(tty); |
| 918 | tty_lock(); | 935 | if (o_tty) { |
| 919 | 936 | tty_ldisc_halt(o_tty); | |
| 920 | mutex_lock(&tty->ldisc_mutex); | 937 | tty_ldisc_flush_works(o_tty); |
| 921 | /* | 938 | } |
| 922 | * Now kill off the ldisc | ||
| 923 | */ | ||
| 924 | tty_ldisc_close(tty, tty->ldisc); | ||
| 925 | tty_ldisc_put(tty->ldisc); | ||
| 926 | /* Force an oops if we mess this up */ | ||
| 927 | tty->ldisc = NULL; | ||
| 928 | |||
| 929 | /* Ensure the next open requests the N_TTY ldisc */ | ||
| 930 | tty_set_termios_ldisc(tty, N_TTY); | ||
| 931 | mutex_unlock(&tty->ldisc_mutex); | ||
| 932 | 939 | ||
| 933 | /* This will need doing differently if we need to lock */ | 940 | /* This will need doing differently if we need to lock */ |
| 941 | tty_ldisc_kill(tty); | ||
| 942 | |||
| 934 | if (o_tty) | 943 | if (o_tty) |
| 935 | tty_ldisc_release(o_tty, NULL); | 944 | tty_ldisc_kill(o_tty); |
| 936 | 945 | ||
| 946 | tty_unlock_pair(tty, o_tty); | ||
| 937 | /* And the memory resources remaining (buffers, termios) will be | 947 | /* And the memory resources remaining (buffers, termios) will be |
| 938 | disposed of when the kref hits zero */ | 948 | disposed of when the kref hits zero */ |
| 939 | } | 949 | } |
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c index 9ff986c32a21..67feac9e6ebb 100644 --- a/drivers/tty/tty_mutex.c +++ b/drivers/tty/tty_mutex.c | |||
| @@ -4,29 +4,70 @@ | |||
| 4 | #include <linux/semaphore.h> | 4 | #include <linux/semaphore.h> |
| 5 | #include <linux/sched.h> | 5 | #include <linux/sched.h> |
| 6 | 6 | ||
| 7 | /* | 7 | /* Legacy tty mutex glue */ |
| 8 | * The 'big tty mutex' | 8 | |
| 9 | * | 9 | enum { |
| 10 | * This mutex is taken and released by tty_lock() and tty_unlock(), | 10 | TTY_MUTEX_NORMAL, |
| 11 | * replacing the older big kernel lock. | 11 | TTY_MUTEX_NESTED, |
| 12 | * It can no longer be taken recursively, and does not get | 12 | }; |
| 13 | * released implicitly while sleeping. | ||
| 14 | * | ||
| 15 | * Don't use in new code. | ||
| 16 | */ | ||
| 17 | static DEFINE_MUTEX(big_tty_mutex); | ||
| 18 | 13 | ||
| 19 | /* | 14 | /* |
| 20 | * Getting the big tty mutex. | 15 | * Getting the big tty mutex. |
| 21 | */ | 16 | */ |
| 22 | void __lockfunc tty_lock(void) | 17 | |
| 18 | static void __lockfunc tty_lock_nested(struct tty_struct *tty, | ||
| 19 | unsigned int subclass) | ||
| 23 | { | 20 | { |
| 24 | mutex_lock(&big_tty_mutex); | 21 | if (tty->magic != TTY_MAGIC) { |
| 22 | printk(KERN_ERR "L Bad %p\n", tty); | ||
| 23 | WARN_ON(1); | ||
| 24 | return; | ||
| 25 | } | ||
| 26 | tty_kref_get(tty); | ||
| 27 | mutex_lock_nested(&tty->legacy_mutex, subclass); | ||
| 28 | } | ||
| 29 | |||
| 30 | void __lockfunc tty_lock(struct tty_struct *tty) | ||
| 31 | { | ||
| 32 | return tty_lock_nested(tty, TTY_MUTEX_NORMAL); | ||
| 25 | } | 33 | } |
| 26 | EXPORT_SYMBOL(tty_lock); | 34 | EXPORT_SYMBOL(tty_lock); |
| 27 | 35 | ||
| 28 | void __lockfunc tty_unlock(void) | 36 | void __lockfunc tty_unlock(struct tty_struct *tty) |
| 29 | { | 37 | { |
| 30 | mutex_unlock(&big_tty_mutex); | 38 | if (tty->magic != TTY_MAGIC) { |
| 39 | printk(KERN_ERR "U Bad %p\n", tty); | ||
| 40 | WARN_ON(1); | ||
| 41 | return; | ||
| 42 | } | ||
| 43 | mutex_unlock(&tty->legacy_mutex); | ||
| 44 | tty_kref_put(tty); | ||
| 31 | } | 45 | } |
| 32 | EXPORT_SYMBOL(tty_unlock); | 46 | EXPORT_SYMBOL(tty_unlock); |
| 47 | |||
| 48 | /* | ||
| 49 | * Getting the big tty mutex for a pair of ttys with lock ordering | ||
| 50 | * On a non pty/tty pair tty2 can be NULL which is just fine. | ||
| 51 | */ | ||
| 52 | void __lockfunc tty_lock_pair(struct tty_struct *tty, | ||
| 53 | struct tty_struct *tty2) | ||
| 54 | { | ||
| 55 | if (tty < tty2) { | ||
| 56 | tty_lock(tty); | ||
| 57 | tty_lock_nested(tty2, TTY_MUTEX_NESTED); | ||
| 58 | } else { | ||
| 59 | if (tty2 && tty2 != tty) | ||
| 60 | tty_lock(tty2); | ||
| 61 | tty_lock_nested(tty, TTY_MUTEX_NESTED); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | EXPORT_SYMBOL(tty_lock_pair); | ||
| 65 | |||
| 66 | void __lockfunc tty_unlock_pair(struct tty_struct *tty, | ||
| 67 | struct tty_struct *tty2) | ||
| 68 | { | ||
| 69 | tty_unlock(tty); | ||
| 70 | if (tty2 && tty2 != tty) | ||
| 71 | tty_unlock(tty2); | ||
| 72 | } | ||
| 73 | EXPORT_SYMBOL(tty_unlock_pair); | ||
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index bf6e238146ae..d7bdd8d0c23f 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c | |||
| @@ -33,6 +33,70 @@ void tty_port_init(struct tty_port *port) | |||
| 33 | } | 33 | } |
| 34 | EXPORT_SYMBOL(tty_port_init); | 34 | EXPORT_SYMBOL(tty_port_init); |
| 35 | 35 | ||
| 36 | /** | ||
| 37 | * tty_port_link_device - link tty and tty_port | ||
| 38 | * @port: tty_port of the device | ||
| 39 | * @driver: tty_driver for this device | ||
| 40 | * @index: index of the tty | ||
| 41 | * | ||
| 42 | * Provide the tty layer wit ha link from a tty (specified by @index) to a | ||
| 43 | * tty_port (@port). Use this only if neither tty_port_register_device nor | ||
| 44 | * tty_port_install is used in the driver. If used, this has to be called before | ||
| 45 | * tty_register_driver. | ||
| 46 | */ | ||
| 47 | void tty_port_link_device(struct tty_port *port, | ||
| 48 | struct tty_driver *driver, unsigned index) | ||
| 49 | { | ||
| 50 | if (WARN_ON(index >= driver->num)) | ||
| 51 | return; | ||
| 52 | driver->ports[index] = port; | ||
| 53 | } | ||
| 54 | EXPORT_SYMBOL_GPL(tty_port_link_device); | ||
| 55 | |||
| 56 | /** | ||
| 57 | * tty_port_register_device - register tty device | ||
| 58 | * @port: tty_port of the device | ||
| 59 | * @driver: tty_driver for this device | ||
| 60 | * @index: index of the tty | ||
| 61 | * @device: parent if exists, otherwise NULL | ||
| 62 | * | ||
| 63 | * It is the same as tty_register_device except the provided @port is linked to | ||
| 64 | * a concrete tty specified by @index. Use this or tty_port_install (or both). | ||
| 65 | * Call tty_port_link_device as a last resort. | ||
| 66 | */ | ||
| 67 | struct device *tty_port_register_device(struct tty_port *port, | ||
| 68 | struct tty_driver *driver, unsigned index, | ||
| 69 | struct device *device) | ||
| 70 | { | ||
| 71 | tty_port_link_device(port, driver, index); | ||
| 72 | return tty_register_device(driver, index, device); | ||
| 73 | } | ||
| 74 | EXPORT_SYMBOL_GPL(tty_port_register_device); | ||
| 75 | |||
| 76 | /** | ||
| 77 | * tty_port_register_device_attr - register tty device | ||
| 78 | * @port: tty_port of the device | ||
| 79 | * @driver: tty_driver for this device | ||
| 80 | * @index: index of the tty | ||
| 81 | * @device: parent if exists, otherwise NULL | ||
| 82 | * @drvdata: Driver data to be set to device. | ||
| 83 | * @attr_grp: Attribute group to be set on device. | ||
| 84 | * | ||
| 85 | * It is the same as tty_register_device_attr except the provided @port is | ||
| 86 | * linked to a concrete tty specified by @index. Use this or tty_port_install | ||
| 87 | * (or both). Call tty_port_link_device as a last resort. | ||
| 88 | */ | ||
| 89 | struct device *tty_port_register_device_attr(struct tty_port *port, | ||
| 90 | struct tty_driver *driver, unsigned index, | ||
| 91 | struct device *device, void *drvdata, | ||
| 92 | const struct attribute_group **attr_grp) | ||
| 93 | { | ||
| 94 | tty_port_link_device(port, driver, index); | ||
| 95 | return tty_register_device_attr(driver, index, device, drvdata, | ||
| 96 | attr_grp); | ||
| 97 | } | ||
| 98 | EXPORT_SYMBOL_GPL(tty_port_register_device_attr); | ||
| 99 | |||
| 36 | int tty_port_alloc_xmit_buf(struct tty_port *port) | 100 | int tty_port_alloc_xmit_buf(struct tty_port *port) |
| 37 | { | 101 | { |
| 38 | /* We may sleep in get_zeroed_page() */ | 102 | /* We may sleep in get_zeroed_page() */ |
| @@ -230,7 +294,7 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
| 230 | 294 | ||
| 231 | /* block if port is in the process of being closed */ | 295 | /* block if port is in the process of being closed */ |
| 232 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { | 296 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { |
| 233 | wait_event_interruptible_tty(port->close_wait, | 297 | wait_event_interruptible_tty(tty, port->close_wait, |
| 234 | !(port->flags & ASYNC_CLOSING)); | 298 | !(port->flags & ASYNC_CLOSING)); |
| 235 | if (port->flags & ASYNC_HUP_NOTIFY) | 299 | if (port->flags & ASYNC_HUP_NOTIFY) |
| 236 | return -EAGAIN; | 300 | return -EAGAIN; |
| @@ -246,7 +310,7 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
| 246 | } | 310 | } |
| 247 | if (filp->f_flags & O_NONBLOCK) { | 311 | if (filp->f_flags & O_NONBLOCK) { |
| 248 | /* Indicate we are open */ | 312 | /* Indicate we are open */ |
| 249 | if (tty->termios->c_cflag & CBAUD) | 313 | if (tty->termios.c_cflag & CBAUD) |
| 250 | tty_port_raise_dtr_rts(port); | 314 | tty_port_raise_dtr_rts(port); |
| 251 | port->flags |= ASYNC_NORMAL_ACTIVE; | 315 | port->flags |= ASYNC_NORMAL_ACTIVE; |
| 252 | return 0; | 316 | return 0; |
| @@ -270,7 +334,7 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
| 270 | 334 | ||
| 271 | while (1) { | 335 | while (1) { |
| 272 | /* Indicate we are open */ | 336 | /* Indicate we are open */ |
| 273 | if (tty->termios->c_cflag & CBAUD) | 337 | if (tty->termios.c_cflag & CBAUD) |
| 274 | tty_port_raise_dtr_rts(port); | 338 | tty_port_raise_dtr_rts(port); |
| 275 | 339 | ||
| 276 | prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); | 340 | prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); |
| @@ -296,9 +360,9 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
| 296 | retval = -ERESTARTSYS; | 360 | retval = -ERESTARTSYS; |
| 297 | break; | 361 | break; |
| 298 | } | 362 | } |
| 299 | tty_unlock(); | 363 | tty_unlock(tty); |
| 300 | schedule(); | 364 | schedule(); |
| 301 | tty_lock(); | 365 | tty_lock(tty); |
| 302 | } | 366 | } |
| 303 | finish_wait(&port->open_wait, &wait); | 367 | finish_wait(&port->open_wait, &wait); |
| 304 | 368 | ||
| @@ -369,7 +433,7 @@ int tty_port_close_start(struct tty_port *port, | |||
| 369 | 433 | ||
| 370 | /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to | 434 | /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to |
| 371 | hang up the line */ | 435 | hang up the line */ |
| 372 | if (tty->termios->c_cflag & HUPCL) | 436 | if (tty->termios.c_cflag & HUPCL) |
| 373 | tty_port_lower_dtr_rts(port); | 437 | tty_port_lower_dtr_rts(port); |
| 374 | 438 | ||
| 375 | /* Don't call port->drop for the last reference. Callers will want | 439 | /* Don't call port->drop for the last reference. Callers will want |
| @@ -413,6 +477,24 @@ void tty_port_close(struct tty_port *port, struct tty_struct *tty, | |||
| 413 | } | 477 | } |
| 414 | EXPORT_SYMBOL(tty_port_close); | 478 | EXPORT_SYMBOL(tty_port_close); |
| 415 | 479 | ||
| 480 | /** | ||
| 481 | * tty_port_install - generic tty->ops->install handler | ||
| 482 | * @port: tty_port of the device | ||
| 483 | * @driver: tty_driver for this device | ||
| 484 | * @tty: tty to be installed | ||
| 485 | * | ||
| 486 | * It is the same as tty_standard_install except the provided @port is linked | ||
| 487 | * to a concrete tty specified by @tty. Use this or tty_port_register_device | ||
| 488 | * (or both). Call tty_port_link_device as a last resort. | ||
| 489 | */ | ||
| 490 | int tty_port_install(struct tty_port *port, struct tty_driver *driver, | ||
| 491 | struct tty_struct *tty) | ||
| 492 | { | ||
| 493 | tty->port = port; | ||
| 494 | return tty_standard_install(driver, tty); | ||
| 495 | } | ||
| 496 | EXPORT_SYMBOL_GPL(tty_port_install); | ||
| 497 | |||
| 416 | int tty_port_open(struct tty_port *port, struct tty_struct *tty, | 498 | int tty_port_open(struct tty_port *port, struct tty_struct *tty, |
| 417 | struct file *filp) | 499 | struct file *filp) |
| 418 | { | 500 | { |
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 48cc6f25cfd3..681765baef69 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c | |||
| @@ -119,6 +119,7 @@ static const int NR_TYPES = ARRAY_SIZE(max_vals); | |||
| 119 | 119 | ||
| 120 | static struct input_handler kbd_handler; | 120 | static struct input_handler kbd_handler; |
| 121 | static DEFINE_SPINLOCK(kbd_event_lock); | 121 | static DEFINE_SPINLOCK(kbd_event_lock); |
| 122 | static DEFINE_SPINLOCK(led_lock); | ||
| 122 | static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ | 123 | static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ |
| 123 | static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ | 124 | static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ |
| 124 | static bool dead_key_next; | 125 | static bool dead_key_next; |
| @@ -310,7 +311,7 @@ static void put_queue(struct vc_data *vc, int ch) | |||
| 310 | 311 | ||
| 311 | if (tty) { | 312 | if (tty) { |
| 312 | tty_insert_flip_char(tty, ch, 0); | 313 | tty_insert_flip_char(tty, ch, 0); |
| 313 | con_schedule_flip(tty); | 314 | tty_schedule_flip(tty); |
| 314 | } | 315 | } |
| 315 | } | 316 | } |
| 316 | 317 | ||
| @@ -325,7 +326,7 @@ static void puts_queue(struct vc_data *vc, char *cp) | |||
| 325 | tty_insert_flip_char(tty, *cp, 0); | 326 | tty_insert_flip_char(tty, *cp, 0); |
| 326 | cp++; | 327 | cp++; |
| 327 | } | 328 | } |
| 328 | con_schedule_flip(tty); | 329 | tty_schedule_flip(tty); |
| 329 | } | 330 | } |
| 330 | 331 | ||
| 331 | static void applkey(struct vc_data *vc, int key, char mode) | 332 | static void applkey(struct vc_data *vc, int key, char mode) |
| @@ -586,7 +587,7 @@ static void fn_send_intr(struct vc_data *vc) | |||
| 586 | if (!tty) | 587 | if (!tty) |
| 587 | return; | 588 | return; |
| 588 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 589 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
| 589 | con_schedule_flip(tty); | 590 | tty_schedule_flip(tty); |
| 590 | } | 591 | } |
| 591 | 592 | ||
| 592 | static void fn_scroll_forw(struct vc_data *vc) | 593 | static void fn_scroll_forw(struct vc_data *vc) |
| @@ -984,7 +985,7 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag) | |||
| 984 | * or (ii) whatever pattern of lights people want to show using KDSETLED, | 985 | * or (ii) whatever pattern of lights people want to show using KDSETLED, |
| 985 | * or (iii) specified bits of specified words in kernel memory. | 986 | * or (iii) specified bits of specified words in kernel memory. |
| 986 | */ | 987 | */ |
| 987 | unsigned char getledstate(void) | 988 | static unsigned char getledstate(void) |
| 988 | { | 989 | { |
| 989 | return ledstate; | 990 | return ledstate; |
| 990 | } | 991 | } |
| @@ -992,7 +993,7 @@ unsigned char getledstate(void) | |||
| 992 | void setledstate(struct kbd_struct *kbd, unsigned int led) | 993 | void setledstate(struct kbd_struct *kbd, unsigned int led) |
| 993 | { | 994 | { |
| 994 | unsigned long flags; | 995 | unsigned long flags; |
| 995 | spin_lock_irqsave(&kbd_event_lock, flags); | 996 | spin_lock_irqsave(&led_lock, flags); |
| 996 | if (!(led & ~7)) { | 997 | if (!(led & ~7)) { |
| 997 | ledioctl = led; | 998 | ledioctl = led; |
| 998 | kbd->ledmode = LED_SHOW_IOCTL; | 999 | kbd->ledmode = LED_SHOW_IOCTL; |
| @@ -1000,7 +1001,7 @@ void setledstate(struct kbd_struct *kbd, unsigned int led) | |||
| 1000 | kbd->ledmode = LED_SHOW_FLAGS; | 1001 | kbd->ledmode = LED_SHOW_FLAGS; |
| 1001 | 1002 | ||
| 1002 | set_leds(); | 1003 | set_leds(); |
| 1003 | spin_unlock_irqrestore(&kbd_event_lock, flags); | 1004 | spin_unlock_irqrestore(&led_lock, flags); |
| 1004 | } | 1005 | } |
| 1005 | 1006 | ||
| 1006 | static inline unsigned char getleds(void) | 1007 | static inline unsigned char getleds(void) |
| @@ -1049,13 +1050,13 @@ static int kbd_update_leds_helper(struct input_handle *handle, void *data) | |||
| 1049 | */ | 1050 | */ |
| 1050 | int vt_get_leds(int console, int flag) | 1051 | int vt_get_leds(int console, int flag) |
| 1051 | { | 1052 | { |
| 1052 | unsigned long flags; | ||
| 1053 | struct kbd_struct * kbd = kbd_table + console; | 1053 | struct kbd_struct * kbd = kbd_table + console; |
| 1054 | int ret; | 1054 | int ret; |
| 1055 | unsigned long flags; | ||
| 1055 | 1056 | ||
| 1056 | spin_lock_irqsave(&kbd_event_lock, flags); | 1057 | spin_lock_irqsave(&led_lock, flags); |
| 1057 | ret = vc_kbd_led(kbd, flag); | 1058 | ret = vc_kbd_led(kbd, flag); |
| 1058 | spin_unlock_irqrestore(&kbd_event_lock, flags); | 1059 | spin_unlock_irqrestore(&led_lock, flags); |
| 1059 | 1060 | ||
| 1060 | return ret; | 1061 | return ret; |
| 1061 | } | 1062 | } |
| @@ -1091,11 +1092,11 @@ void vt_set_led_state(int console, int leds) | |||
| 1091 | void vt_kbd_con_start(int console) | 1092 | void vt_kbd_con_start(int console) |
| 1092 | { | 1093 | { |
| 1093 | struct kbd_struct * kbd = kbd_table + console; | 1094 | struct kbd_struct * kbd = kbd_table + console; |
| 1094 | /* unsigned long flags; */ | 1095 | unsigned long flags; |
| 1095 | /* spin_lock_irqsave(&kbd_event_lock, flags); */ | 1096 | spin_lock_irqsave(&led_lock, flags); |
| 1096 | clr_vc_kbd_led(kbd, VC_SCROLLOCK); | 1097 | clr_vc_kbd_led(kbd, VC_SCROLLOCK); |
| 1097 | set_leds(); | 1098 | set_leds(); |
| 1098 | /* spin_unlock_irqrestore(&kbd_event_lock, flags); */ | 1099 | spin_unlock_irqrestore(&led_lock, flags); |
| 1099 | } | 1100 | } |
| 1100 | 1101 | ||
| 1101 | /** | 1102 | /** |
| @@ -1104,21 +1105,15 @@ void vt_kbd_con_start(int console) | |||
| 1104 | * | 1105 | * |
| 1105 | * Handle console stop. This is a wrapper for the VT layer | 1106 | * Handle console stop. This is a wrapper for the VT layer |
| 1106 | * so that we can keep kbd knowledge internal | 1107 | * so that we can keep kbd knowledge internal |
| 1107 | * | ||
| 1108 | * FIXME: We eventually need to hold the kbd lock here to protect | ||
| 1109 | * the LED updating. We can't do it yet because fn_hold calls stop_tty | ||
| 1110 | * and start_tty under the kbd_event_lock, while normal tty paths | ||
| 1111 | * don't hold the lock. We probably need to split out an LED lock | ||
| 1112 | * but not during an -rc release! | ||
| 1113 | */ | 1108 | */ |
| 1114 | void vt_kbd_con_stop(int console) | 1109 | void vt_kbd_con_stop(int console) |
| 1115 | { | 1110 | { |
| 1116 | struct kbd_struct * kbd = kbd_table + console; | 1111 | struct kbd_struct * kbd = kbd_table + console; |
| 1117 | /* unsigned long flags; */ | 1112 | unsigned long flags; |
| 1118 | /* spin_lock_irqsave(&kbd_event_lock, flags); */ | 1113 | spin_lock_irqsave(&led_lock, flags); |
| 1119 | set_vc_kbd_led(kbd, VC_SCROLLOCK); | 1114 | set_vc_kbd_led(kbd, VC_SCROLLOCK); |
| 1120 | set_leds(); | 1115 | set_leds(); |
| 1121 | /* spin_unlock_irqrestore(&kbd_event_lock, flags); */ | 1116 | spin_unlock_irqrestore(&led_lock, flags); |
| 1122 | } | 1117 | } |
| 1123 | 1118 | ||
| 1124 | /* | 1119 | /* |
| @@ -1130,7 +1125,12 @@ void vt_kbd_con_stop(int console) | |||
| 1130 | */ | 1125 | */ |
| 1131 | static void kbd_bh(unsigned long dummy) | 1126 | static void kbd_bh(unsigned long dummy) |
| 1132 | { | 1127 | { |
| 1133 | unsigned char leds = getleds(); | 1128 | unsigned char leds; |
| 1129 | unsigned long flags; | ||
| 1130 | |||
| 1131 | spin_lock_irqsave(&led_lock, flags); | ||
| 1132 | leds = getleds(); | ||
| 1133 | spin_unlock_irqrestore(&led_lock, flags); | ||
| 1134 | 1134 | ||
| 1135 | if (leds != ledstate) { | 1135 | if (leds != ledstate) { |
| 1136 | input_handler_for_each_handle(&kbd_handler, &leds, | 1136 | input_handler_for_each_handle(&kbd_handler, &leds, |
| @@ -2035,11 +2035,11 @@ int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) | |||
| 2035 | return -EPERM; | 2035 | return -EPERM; |
| 2036 | if (arg & ~0x77) | 2036 | if (arg & ~0x77) |
| 2037 | return -EINVAL; | 2037 | return -EINVAL; |
| 2038 | spin_lock_irqsave(&kbd_event_lock, flags); | 2038 | spin_lock_irqsave(&led_lock, flags); |
| 2039 | kbd->ledflagstate = (arg & 7); | 2039 | kbd->ledflagstate = (arg & 7); |
| 2040 | kbd->default_ledflagstate = ((arg >> 4) & 7); | 2040 | kbd->default_ledflagstate = ((arg >> 4) & 7); |
| 2041 | set_leds(); | 2041 | set_leds(); |
| 2042 | spin_unlock_irqrestore(&kbd_event_lock, flags); | 2042 | spin_unlock_irqrestore(&led_lock, flags); |
| 2043 | return 0; | 2043 | return 0; |
| 2044 | 2044 | ||
| 2045 | /* the ioctls below only set the lights, not the functions */ | 2045 | /* the ioctls below only set the lights, not the functions */ |
| @@ -2134,8 +2134,10 @@ void vt_reset_keyboard(int console) | |||
| 2134 | clr_vc_kbd_mode(kbd, VC_CRLF); | 2134 | clr_vc_kbd_mode(kbd, VC_CRLF); |
| 2135 | kbd->lockstate = 0; | 2135 | kbd->lockstate = 0; |
| 2136 | kbd->slockstate = 0; | 2136 | kbd->slockstate = 0; |
| 2137 | spin_lock(&led_lock); | ||
| 2137 | kbd->ledmode = LED_SHOW_FLAGS; | 2138 | kbd->ledmode = LED_SHOW_FLAGS; |
| 2138 | kbd->ledflagstate = kbd->default_ledflagstate; | 2139 | kbd->ledflagstate = kbd->default_ledflagstate; |
| 2140 | spin_unlock(&led_lock); | ||
| 2139 | /* do not do set_leds here because this causes an endless tasklet loop | 2141 | /* do not do set_leds here because this causes an endless tasklet loop |
| 2140 | when the keyboard hasn't been initialized yet */ | 2142 | when the keyboard hasn't been initialized yet */ |
| 2141 | spin_unlock_irqrestore(&kbd_event_lock, flags); | 2143 | spin_unlock_irqrestore(&kbd_event_lock, flags); |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 84cbf298c094..999ca63afdef 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
| @@ -537,45 +537,27 @@ void complement_pos(struct vc_data *vc, int offset) | |||
| 537 | 537 | ||
| 538 | static void insert_char(struct vc_data *vc, unsigned int nr) | 538 | static void insert_char(struct vc_data *vc, unsigned int nr) |
| 539 | { | 539 | { |
| 540 | unsigned short *p, *q = (unsigned short *)vc->vc_pos; | 540 | unsigned short *p = (unsigned short *) vc->vc_pos; |
| 541 | 541 | ||
| 542 | p = q + vc->vc_cols - nr - vc->vc_x; | 542 | scr_memmovew(p + nr, p, vc->vc_cols - vc->vc_x); |
| 543 | while (--p >= q) | 543 | scr_memsetw(p, vc->vc_video_erase_char, nr * 2); |
| 544 | scr_writew(scr_readw(p), p + nr); | ||
| 545 | scr_memsetw(q, vc->vc_video_erase_char, nr * 2); | ||
| 546 | vc->vc_need_wrap = 0; | 544 | vc->vc_need_wrap = 0; |
| 547 | if (DO_UPDATE(vc)) { | 545 | if (DO_UPDATE(vc)) |
| 548 | unsigned short oldattr = vc->vc_attr; | 546 | do_update_region(vc, (unsigned long) p, |
| 549 | vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x, vc->vc_y, vc->vc_x + nr, 1, | 547 | (vc->vc_cols - vc->vc_x) / 2 + 1); |
| 550 | vc->vc_cols - vc->vc_x - nr); | ||
| 551 | vc->vc_attr = vc->vc_video_erase_char >> 8; | ||
| 552 | while (nr--) | ||
| 553 | vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, vc->vc_x + nr); | ||
| 554 | vc->vc_attr = oldattr; | ||
| 555 | } | ||
| 556 | } | 548 | } |
| 557 | 549 | ||
| 558 | static void delete_char(struct vc_data *vc, unsigned int nr) | 550 | static void delete_char(struct vc_data *vc, unsigned int nr) |
| 559 | { | 551 | { |
| 560 | unsigned int i = vc->vc_x; | 552 | unsigned short *p = (unsigned short *) vc->vc_pos; |
| 561 | unsigned short *p = (unsigned short *)vc->vc_pos; | ||
| 562 | 553 | ||
| 563 | while (++i <= vc->vc_cols - nr) { | 554 | scr_memcpyw(p, p + nr, vc->vc_cols - vc->vc_x - nr); |
| 564 | scr_writew(scr_readw(p+nr), p); | 555 | scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char, |
| 565 | p++; | 556 | nr * 2); |
| 566 | } | ||
| 567 | scr_memsetw(p, vc->vc_video_erase_char, nr * 2); | ||
| 568 | vc->vc_need_wrap = 0; | 557 | vc->vc_need_wrap = 0; |
| 569 | if (DO_UPDATE(vc)) { | 558 | if (DO_UPDATE(vc)) |
| 570 | unsigned short oldattr = vc->vc_attr; | 559 | do_update_region(vc, (unsigned long) p, |
| 571 | vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x + nr, vc->vc_y, vc->vc_x, 1, | 560 | (vc->vc_cols - vc->vc_x) / 2); |
| 572 | vc->vc_cols - vc->vc_x - nr); | ||
| 573 | vc->vc_attr = vc->vc_video_erase_char >> 8; | ||
| 574 | while (nr--) | ||
| 575 | vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, | ||
| 576 | vc->vc_cols - 1 - nr); | ||
| 577 | vc->vc_attr = oldattr; | ||
| 578 | } | ||
| 579 | } | 561 | } |
| 580 | 562 | ||
| 581 | static int softcursor_original; | 563 | static int softcursor_original; |
| @@ -1172,45 +1154,26 @@ static void csi_J(struct vc_data *vc, int vpar) | |||
| 1172 | case 0: /* erase from cursor to end of display */ | 1154 | case 0: /* erase from cursor to end of display */ |
| 1173 | count = (vc->vc_scr_end - vc->vc_pos) >> 1; | 1155 | count = (vc->vc_scr_end - vc->vc_pos) >> 1; |
| 1174 | start = (unsigned short *)vc->vc_pos; | 1156 | start = (unsigned short *)vc->vc_pos; |
| 1175 | if (DO_UPDATE(vc)) { | ||
| 1176 | /* do in two stages */ | ||
| 1177 | vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, | ||
| 1178 | vc->vc_cols - vc->vc_x); | ||
| 1179 | vc->vc_sw->con_clear(vc, vc->vc_y + 1, 0, | ||
| 1180 | vc->vc_rows - vc->vc_y - 1, | ||
| 1181 | vc->vc_cols); | ||
| 1182 | } | ||
| 1183 | break; | 1157 | break; |
| 1184 | case 1: /* erase from start to cursor */ | 1158 | case 1: /* erase from start to cursor */ |
| 1185 | count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1; | 1159 | count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1; |
| 1186 | start = (unsigned short *)vc->vc_origin; | 1160 | start = (unsigned short *)vc->vc_origin; |
| 1187 | if (DO_UPDATE(vc)) { | ||
| 1188 | /* do in two stages */ | ||
| 1189 | vc->vc_sw->con_clear(vc, 0, 0, vc->vc_y, | ||
| 1190 | vc->vc_cols); | ||
| 1191 | vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1, | ||
| 1192 | vc->vc_x + 1); | ||
| 1193 | } | ||
| 1194 | break; | 1161 | break; |
| 1195 | case 3: /* erase scroll-back buffer (and whole display) */ | 1162 | case 3: /* erase scroll-back buffer (and whole display) */ |
| 1196 | scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, | 1163 | scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, |
| 1197 | vc->vc_screenbuf_size >> 1); | 1164 | vc->vc_screenbuf_size >> 1); |
| 1198 | set_origin(vc); | 1165 | set_origin(vc); |
| 1199 | if (CON_IS_VISIBLE(vc)) | ||
| 1200 | update_screen(vc); | ||
| 1201 | /* fall through */ | 1166 | /* fall through */ |
| 1202 | case 2: /* erase whole display */ | 1167 | case 2: /* erase whole display */ |
| 1203 | count = vc->vc_cols * vc->vc_rows; | 1168 | count = vc->vc_cols * vc->vc_rows; |
| 1204 | start = (unsigned short *)vc->vc_origin; | 1169 | start = (unsigned short *)vc->vc_origin; |
| 1205 | if (DO_UPDATE(vc)) | ||
| 1206 | vc->vc_sw->con_clear(vc, 0, 0, | ||
| 1207 | vc->vc_rows, | ||
| 1208 | vc->vc_cols); | ||
| 1209 | break; | 1170 | break; |
| 1210 | default: | 1171 | default: |
| 1211 | return; | 1172 | return; |
| 1212 | } | 1173 | } |
| 1213 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); | 1174 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); |
| 1175 | if (DO_UPDATE(vc)) | ||
| 1176 | do_update_region(vc, (unsigned long) start, count); | ||
| 1214 | vc->vc_need_wrap = 0; | 1177 | vc->vc_need_wrap = 0; |
| 1215 | } | 1178 | } |
| 1216 | 1179 | ||
| @@ -1223,29 +1186,22 @@ static void csi_K(struct vc_data *vc, int vpar) | |||
| 1223 | case 0: /* erase from cursor to end of line */ | 1186 | case 0: /* erase from cursor to end of line */ |
| 1224 | count = vc->vc_cols - vc->vc_x; | 1187 | count = vc->vc_cols - vc->vc_x; |
| 1225 | start = (unsigned short *)vc->vc_pos; | 1188 | start = (unsigned short *)vc->vc_pos; |
| 1226 | if (DO_UPDATE(vc)) | ||
| 1227 | vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, | ||
| 1228 | vc->vc_cols - vc->vc_x); | ||
| 1229 | break; | 1189 | break; |
| 1230 | case 1: /* erase from start of line to cursor */ | 1190 | case 1: /* erase from start of line to cursor */ |
| 1231 | start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); | 1191 | start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); |
| 1232 | count = vc->vc_x + 1; | 1192 | count = vc->vc_x + 1; |
| 1233 | if (DO_UPDATE(vc)) | ||
| 1234 | vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1, | ||
| 1235 | vc->vc_x + 1); | ||
| 1236 | break; | 1193 | break; |
| 1237 | case 2: /* erase whole line */ | 1194 | case 2: /* erase whole line */ |
| 1238 | start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); | 1195 | start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); |
| 1239 | count = vc->vc_cols; | 1196 | count = vc->vc_cols; |
| 1240 | if (DO_UPDATE(vc)) | ||
| 1241 | vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1, | ||
| 1242 | vc->vc_cols); | ||
| 1243 | break; | 1197 | break; |
| 1244 | default: | 1198 | default: |
| 1245 | return; | 1199 | return; |
| 1246 | } | 1200 | } |
| 1247 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); | 1201 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); |
| 1248 | vc->vc_need_wrap = 0; | 1202 | vc->vc_need_wrap = 0; |
| 1203 | if (DO_UPDATE(vc)) | ||
| 1204 | do_update_region(vc, (unsigned long) start, count); | ||
| 1249 | } | 1205 | } |
| 1250 | 1206 | ||
| 1251 | static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */ | 1207 | static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */ |
| @@ -1380,7 +1336,7 @@ static void respond_string(const char *p, struct tty_struct *tty) | |||
| 1380 | tty_insert_flip_char(tty, *p, 0); | 1336 | tty_insert_flip_char(tty, *p, 0); |
| 1381 | p++; | 1337 | p++; |
| 1382 | } | 1338 | } |
| 1383 | con_schedule_flip(tty); | 1339 | tty_schedule_flip(tty); |
| 1384 | } | 1340 | } |
| 1385 | 1341 | ||
| 1386 | static void cursor_report(struct vc_data *vc, struct tty_struct *tty) | 1342 | static void cursor_report(struct vc_data *vc, struct tty_struct *tty) |
| @@ -2792,41 +2748,52 @@ static void con_flush_chars(struct tty_struct *tty) | |||
| 2792 | /* | 2748 | /* |
| 2793 | * Allocate the console screen memory. | 2749 | * Allocate the console screen memory. |
| 2794 | */ | 2750 | */ |
| 2795 | static int con_open(struct tty_struct *tty, struct file *filp) | 2751 | static int con_install(struct tty_driver *driver, struct tty_struct *tty) |
| 2796 | { | 2752 | { |
| 2797 | unsigned int currcons = tty->index; | 2753 | unsigned int currcons = tty->index; |
| 2798 | int ret = 0; | 2754 | struct vc_data *vc; |
| 2755 | int ret; | ||
| 2799 | 2756 | ||
| 2800 | console_lock(); | 2757 | console_lock(); |
| 2801 | if (tty->driver_data == NULL) { | 2758 | ret = vc_allocate(currcons); |
| 2802 | ret = vc_allocate(currcons); | 2759 | if (ret) |
| 2803 | if (ret == 0) { | 2760 | goto unlock; |
| 2804 | struct vc_data *vc = vc_cons[currcons].d; | ||
| 2805 | 2761 | ||
| 2806 | /* Still being freed */ | 2762 | vc = vc_cons[currcons].d; |
| 2807 | if (vc->port.tty) { | ||
| 2808 | console_unlock(); | ||
| 2809 | return -ERESTARTSYS; | ||
| 2810 | } | ||
| 2811 | tty->driver_data = vc; | ||
| 2812 | vc->port.tty = tty; | ||
| 2813 | 2763 | ||
| 2814 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { | 2764 | /* Still being freed */ |
| 2815 | tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; | 2765 | if (vc->port.tty) { |
| 2816 | tty->winsize.ws_col = vc_cons[currcons].d->vc_cols; | 2766 | ret = -ERESTARTSYS; |
| 2817 | } | 2767 | goto unlock; |
| 2818 | if (vc->vc_utf) | ||
| 2819 | tty->termios->c_iflag |= IUTF8; | ||
| 2820 | else | ||
| 2821 | tty->termios->c_iflag &= ~IUTF8; | ||
| 2822 | console_unlock(); | ||
| 2823 | return ret; | ||
| 2824 | } | ||
| 2825 | } | 2768 | } |
| 2769 | |||
| 2770 | ret = tty_port_install(&vc->port, driver, tty); | ||
| 2771 | if (ret) | ||
| 2772 | goto unlock; | ||
| 2773 | |||
| 2774 | tty->driver_data = vc; | ||
| 2775 | vc->port.tty = tty; | ||
| 2776 | |||
| 2777 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { | ||
| 2778 | tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; | ||
| 2779 | tty->winsize.ws_col = vc_cons[currcons].d->vc_cols; | ||
| 2780 | } | ||
| 2781 | if (vc->vc_utf) | ||
| 2782 | tty->termios.c_iflag |= IUTF8; | ||
| 2783 | else | ||
| 2784 | tty->termios.c_iflag &= ~IUTF8; | ||
| 2785 | unlock: | ||
| 2826 | console_unlock(); | 2786 | console_unlock(); |
| 2827 | return ret; | 2787 | return ret; |
| 2828 | } | 2788 | } |
| 2829 | 2789 | ||
| 2790 | static int con_open(struct tty_struct *tty, struct file *filp) | ||
| 2791 | { | ||
| 2792 | /* everything done in install */ | ||
| 2793 | return 0; | ||
| 2794 | } | ||
| 2795 | |||
| 2796 | |||
| 2830 | static void con_close(struct tty_struct *tty, struct file *filp) | 2797 | static void con_close(struct tty_struct *tty, struct file *filp) |
| 2831 | { | 2798 | { |
| 2832 | /* Nothing to do - we defer to shutdown */ | 2799 | /* Nothing to do - we defer to shutdown */ |
| @@ -2839,7 +2806,6 @@ static void con_shutdown(struct tty_struct *tty) | |||
| 2839 | console_lock(); | 2806 | console_lock(); |
| 2840 | vc->port.tty = NULL; | 2807 | vc->port.tty = NULL; |
| 2841 | console_unlock(); | 2808 | console_unlock(); |
| 2842 | tty_shutdown(tty); | ||
| 2843 | } | 2809 | } |
| 2844 | 2810 | ||
| 2845 | static int default_italic_color = 2; // green (ASCII) | 2811 | static int default_italic_color = 2; // green (ASCII) |
| @@ -2947,6 +2913,7 @@ static int __init con_init(void) | |||
| 2947 | console_initcall(con_init); | 2913 | console_initcall(con_init); |
| 2948 | 2914 | ||
| 2949 | static const struct tty_operations con_ops = { | 2915 | static const struct tty_operations con_ops = { |
| 2916 | .install = con_install, | ||
| 2950 | .open = con_open, | 2917 | .open = con_open, |
| 2951 | .close = con_close, | 2918 | .close = con_close, |
| 2952 | .write = con_write, | 2919 | .write = con_write, |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index f763ed7ba91e..ff7b5a8d501c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -826,7 +826,7 @@ static void acm_tty_set_termios(struct tty_struct *tty, | |||
| 826 | struct ktermios *termios_old) | 826 | struct ktermios *termios_old) |
| 827 | { | 827 | { |
| 828 | struct acm *acm = tty->driver_data; | 828 | struct acm *acm = tty->driver_data; |
| 829 | struct ktermios *termios = tty->termios; | 829 | struct ktermios *termios = &tty->termios; |
| 830 | struct usb_cdc_line_coding newline; | 830 | struct usb_cdc_line_coding newline; |
| 831 | int newctrl = acm->ctrlout; | 831 | int newctrl = acm->ctrlout; |
| 832 | 832 | ||
| @@ -1299,7 +1299,8 @@ skip_countries: | |||
| 1299 | usb_set_intfdata(data_interface, acm); | 1299 | usb_set_intfdata(data_interface, acm); |
| 1300 | 1300 | ||
| 1301 | usb_get_intf(control_interface); | 1301 | usb_get_intf(control_interface); |
| 1302 | tty_register_device(acm_tty_driver, minor, &control_interface->dev); | 1302 | tty_port_register_device(&acm->port, acm_tty_driver, minor, |
| 1303 | &control_interface->dev); | ||
| 1303 | 1304 | ||
| 1304 | return 0; | 1305 | return 0; |
| 1305 | alloc_fail7: | 1306 | alloc_fail7: |
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index da6d479ff9a6..f1739526820f 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
| @@ -1133,7 +1133,8 @@ int gserial_setup(struct usb_gadget *g, unsigned count) | |||
| 1133 | for (i = 0; i < count; i++) { | 1133 | for (i = 0; i < count; i++) { |
| 1134 | struct device *tty_dev; | 1134 | struct device *tty_dev; |
| 1135 | 1135 | ||
| 1136 | tty_dev = tty_register_device(gs_tty_driver, i, &g->dev); | 1136 | tty_dev = tty_port_register_device(&ports[i].port->port, |
| 1137 | gs_tty_driver, i, &g->dev); | ||
| 1137 | if (IS_ERR(tty_dev)) | 1138 | if (IS_ERR(tty_dev)) |
| 1138 | pr_warning("%s: no classdev for port %d, err %ld\n", | 1139 | pr_warning("%s: no classdev for port %d, err %ld\n", |
| 1139 | __func__, i, PTR_ERR(tty_dev)); | 1140 | __func__, i, PTR_ERR(tty_dev)); |
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index f8ce97d8b0ad..3b98fb733362 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
| @@ -215,7 +215,7 @@ static void ark3116_release(struct usb_serial *serial) | |||
| 215 | 215 | ||
| 216 | static void ark3116_init_termios(struct tty_struct *tty) | 216 | static void ark3116_init_termios(struct tty_struct *tty) |
| 217 | { | 217 | { |
| 218 | struct ktermios *termios = tty->termios; | 218 | struct ktermios *termios = &tty->termios; |
| 219 | *termios = tty_std_termios; | 219 | *termios = tty_std_termios; |
| 220 | termios->c_cflag = B9600 | CS8 | 220 | termios->c_cflag = B9600 | CS8 |
| 221 | | CREAD | HUPCL | CLOCAL; | 221 | | CREAD | HUPCL | CLOCAL; |
| @@ -229,7 +229,7 @@ static void ark3116_set_termios(struct tty_struct *tty, | |||
| 229 | { | 229 | { |
| 230 | struct usb_serial *serial = port->serial; | 230 | struct usb_serial *serial = port->serial; |
| 231 | struct ark3116_private *priv = usb_get_serial_port_data(port); | 231 | struct ark3116_private *priv = usb_get_serial_port_data(port); |
| 232 | struct ktermios *termios = tty->termios; | 232 | struct ktermios *termios = &tty->termios; |
| 233 | unsigned int cflag = termios->c_cflag; | 233 | unsigned int cflag = termios->c_cflag; |
| 234 | int bps = tty_get_baud_rate(tty); | 234 | int bps = tty_get_baud_rate(tty); |
| 235 | int quot; | 235 | int quot; |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 6b7365632951..a46df73ee96e 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
| @@ -307,7 +307,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty, | |||
| 307 | unsigned long control_state; | 307 | unsigned long control_state; |
| 308 | int bad_flow_control; | 308 | int bad_flow_control; |
| 309 | speed_t baud; | 309 | speed_t baud; |
| 310 | struct ktermios *termios = tty->termios; | 310 | struct ktermios *termios = &tty->termios; |
| 311 | 311 | ||
| 312 | iflag = termios->c_iflag; | 312 | iflag = termios->c_iflag; |
| 313 | cflag = termios->c_cflag; | 313 | cflag = termios->c_cflag; |
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index b9cca6dcde07..9a564286bfd7 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
| @@ -165,8 +165,8 @@ static int usb_console_setup(struct console *co, char *options) | |||
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | if (serial->type->set_termios) { | 167 | if (serial->type->set_termios) { |
| 168 | tty->termios->c_cflag = cflag; | 168 | tty->termios.c_cflag = cflag; |
| 169 | tty_termios_encode_baud_rate(tty->termios, baud, baud); | 169 | tty_termios_encode_baud_rate(&tty->termios, baud, baud); |
| 170 | memset(&dummy, 0, sizeof(struct ktermios)); | 170 | memset(&dummy, 0, sizeof(struct ktermios)); |
| 171 | serial->type->set_termios(tty, port, &dummy); | 171 | serial->type->set_termios(tty, port, &dummy); |
| 172 | 172 | ||
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 1e71079ce33b..ba5e07e188a0 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
| @@ -469,7 +469,7 @@ static void cp210x_get_termios(struct tty_struct *tty, | |||
| 469 | 469 | ||
| 470 | if (tty) { | 470 | if (tty) { |
| 471 | cp210x_get_termios_port(tty->driver_data, | 471 | cp210x_get_termios_port(tty->driver_data, |
| 472 | &tty->termios->c_cflag, &baud); | 472 | &tty->termios.c_cflag, &baud); |
| 473 | tty_encode_baud_rate(tty, baud, baud); | 473 | tty_encode_baud_rate(tty, baud, baud); |
| 474 | } | 474 | } |
| 475 | 475 | ||
| @@ -631,7 +631,7 @@ static void cp210x_change_speed(struct tty_struct *tty, | |||
| 631 | { | 631 | { |
| 632 | u32 baud; | 632 | u32 baud; |
| 633 | 633 | ||
| 634 | baud = tty->termios->c_ospeed; | 634 | baud = tty->termios.c_ospeed; |
| 635 | 635 | ||
| 636 | /* This maps the requested rate to a rate valid on cp2102 or cp2103, | 636 | /* This maps the requested rate to a rate valid on cp2102 or cp2103, |
| 637 | * or to an arbitrary rate in [1M,2M]. | 637 | * or to an arbitrary rate in [1M,2M]. |
| @@ -665,10 +665,10 @@ static void cp210x_set_termios(struct tty_struct *tty, | |||
| 665 | if (!tty) | 665 | if (!tty) |
| 666 | return; | 666 | return; |
| 667 | 667 | ||
| 668 | cflag = tty->termios->c_cflag; | 668 | cflag = tty->termios.c_cflag; |
| 669 | old_cflag = old_termios->c_cflag; | 669 | old_cflag = old_termios->c_cflag; |
| 670 | 670 | ||
| 671 | if (tty->termios->c_ospeed != old_termios->c_ospeed) | 671 | if (tty->termios.c_ospeed != old_termios->c_ospeed) |
| 672 | cp210x_change_speed(tty, port, old_termios); | 672 | cp210x_change_speed(tty, port, old_termios); |
| 673 | 673 | ||
| 674 | /* If the number of data bits is to be updated */ | 674 | /* If the number of data bits is to be updated */ |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index b78c34eb5d3f..be34f153e566 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
| @@ -922,38 +922,38 @@ static void cypress_set_termios(struct tty_struct *tty, | |||
| 922 | early enough */ | 922 | early enough */ |
| 923 | if (!priv->termios_initialized) { | 923 | if (!priv->termios_initialized) { |
| 924 | if (priv->chiptype == CT_EARTHMATE) { | 924 | if (priv->chiptype == CT_EARTHMATE) { |
| 925 | *(tty->termios) = tty_std_termios; | 925 | tty->termios = tty_std_termios; |
| 926 | tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL | | 926 | tty->termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | |
| 927 | CLOCAL; | 927 | CLOCAL; |
| 928 | tty->termios->c_ispeed = 4800; | 928 | tty->termios.c_ispeed = 4800; |
| 929 | tty->termios->c_ospeed = 4800; | 929 | tty->termios.c_ospeed = 4800; |
| 930 | } else if (priv->chiptype == CT_CYPHIDCOM) { | 930 | } else if (priv->chiptype == CT_CYPHIDCOM) { |
| 931 | *(tty->termios) = tty_std_termios; | 931 | tty->termios = tty_std_termios; |
| 932 | tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | | 932 | tty->termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | |
| 933 | CLOCAL; | 933 | CLOCAL; |
| 934 | tty->termios->c_ispeed = 9600; | 934 | tty->termios.c_ispeed = 9600; |
| 935 | tty->termios->c_ospeed = 9600; | 935 | tty->termios.c_ospeed = 9600; |
| 936 | } else if (priv->chiptype == CT_CA42V2) { | 936 | } else if (priv->chiptype == CT_CA42V2) { |
| 937 | *(tty->termios) = tty_std_termios; | 937 | tty->termios = tty_std_termios; |
| 938 | tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | | 938 | tty->termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | |
| 939 | CLOCAL; | 939 | CLOCAL; |
| 940 | tty->termios->c_ispeed = 9600; | 940 | tty->termios.c_ispeed = 9600; |
| 941 | tty->termios->c_ospeed = 9600; | 941 | tty->termios.c_ospeed = 9600; |
| 942 | } | 942 | } |
| 943 | priv->termios_initialized = 1; | 943 | priv->termios_initialized = 1; |
| 944 | } | 944 | } |
| 945 | spin_unlock_irqrestore(&priv->lock, flags); | 945 | spin_unlock_irqrestore(&priv->lock, flags); |
| 946 | 946 | ||
| 947 | /* Unsupported features need clearing */ | 947 | /* Unsupported features need clearing */ |
| 948 | tty->termios->c_cflag &= ~(CMSPAR|CRTSCTS); | 948 | tty->termios.c_cflag &= ~(CMSPAR|CRTSCTS); |
| 949 | 949 | ||
| 950 | cflag = tty->termios->c_cflag; | 950 | cflag = tty->termios.c_cflag; |
| 951 | iflag = tty->termios->c_iflag; | 951 | iflag = tty->termios.c_iflag; |
| 952 | 952 | ||
| 953 | /* check if there are new settings */ | 953 | /* check if there are new settings */ |
| 954 | if (old_termios) { | 954 | if (old_termios) { |
| 955 | spin_lock_irqsave(&priv->lock, flags); | 955 | spin_lock_irqsave(&priv->lock, flags); |
| 956 | priv->tmp_termios = *(tty->termios); | 956 | priv->tmp_termios = tty->termios; |
| 957 | spin_unlock_irqrestore(&priv->lock, flags); | 957 | spin_unlock_irqrestore(&priv->lock, flags); |
| 958 | } | 958 | } |
| 959 | 959 | ||
| @@ -1021,7 +1021,7 @@ static void cypress_set_termios(struct tty_struct *tty, | |||
| 1021 | "4800bps."); | 1021 | "4800bps."); |
| 1022 | /* define custom termios settings for NMEA protocol */ | 1022 | /* define custom termios settings for NMEA protocol */ |
| 1023 | 1023 | ||
| 1024 | tty->termios->c_iflag /* input modes - */ | 1024 | tty->termios.c_iflag /* input modes - */ |
| 1025 | &= ~(IGNBRK /* disable ignore break */ | 1025 | &= ~(IGNBRK /* disable ignore break */ |
| 1026 | | BRKINT /* disable break causes interrupt */ | 1026 | | BRKINT /* disable break causes interrupt */ |
| 1027 | | PARMRK /* disable mark parity errors */ | 1027 | | PARMRK /* disable mark parity errors */ |
| @@ -1031,10 +1031,10 @@ static void cypress_set_termios(struct tty_struct *tty, | |||
| 1031 | | ICRNL /* disable translate CR to NL */ | 1031 | | ICRNL /* disable translate CR to NL */ |
| 1032 | | IXON); /* disable enable XON/XOFF flow control */ | 1032 | | IXON); /* disable enable XON/XOFF flow control */ |
| 1033 | 1033 | ||
| 1034 | tty->termios->c_oflag /* output modes */ | 1034 | tty->termios.c_oflag /* output modes */ |
| 1035 | &= ~OPOST; /* disable postprocess output char */ | 1035 | &= ~OPOST; /* disable postprocess output char */ |
| 1036 | 1036 | ||
| 1037 | tty->termios->c_lflag /* line discipline modes */ | 1037 | tty->termios.c_lflag /* line discipline modes */ |
| 1038 | &= ~(ECHO /* disable echo input characters */ | 1038 | &= ~(ECHO /* disable echo input characters */ |
| 1039 | | ECHONL /* disable echo new line */ | 1039 | | ECHONL /* disable echo new line */ |
| 1040 | | ICANON /* disable erase, kill, werase, and rprnt | 1040 | | ICANON /* disable erase, kill, werase, and rprnt |
| @@ -1200,7 +1200,7 @@ static void cypress_read_int_callback(struct urb *urb) | |||
| 1200 | 1200 | ||
| 1201 | /* hangup, as defined in acm.c... this might be a bad place for it | 1201 | /* hangup, as defined in acm.c... this might be a bad place for it |
| 1202 | * though */ | 1202 | * though */ |
| 1203 | if (tty && !(tty->termios->c_cflag & CLOCAL) && | 1203 | if (tty && !(tty->termios.c_cflag & CLOCAL) && |
| 1204 | !(priv->current_status & UART_CD)) { | 1204 | !(priv->current_status & UART_CD)) { |
| 1205 | dbg("%s - calling hangup", __func__); | 1205 | dbg("%s - calling hangup", __func__); |
| 1206 | tty_hangup(tty); | 1206 | tty_hangup(tty); |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index b5cd838093ef..afd9d2ec577b 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
| @@ -687,8 +687,8 @@ static void digi_set_termios(struct tty_struct *tty, | |||
| 687 | struct usb_serial_port *port, struct ktermios *old_termios) | 687 | struct usb_serial_port *port, struct ktermios *old_termios) |
| 688 | { | 688 | { |
| 689 | struct digi_port *priv = usb_get_serial_port_data(port); | 689 | struct digi_port *priv = usb_get_serial_port_data(port); |
| 690 | unsigned int iflag = tty->termios->c_iflag; | 690 | unsigned int iflag = tty->termios.c_iflag; |
| 691 | unsigned int cflag = tty->termios->c_cflag; | 691 | unsigned int cflag = tty->termios.c_cflag; |
| 692 | unsigned int old_iflag = old_termios->c_iflag; | 692 | unsigned int old_iflag = old_termios->c_iflag; |
| 693 | unsigned int old_cflag = old_termios->c_cflag; | 693 | unsigned int old_cflag = old_termios->c_cflag; |
| 694 | unsigned char buf[32]; | 694 | unsigned char buf[32]; |
| @@ -709,7 +709,7 @@ static void digi_set_termios(struct tty_struct *tty, | |||
| 709 | /* don't set RTS if using hardware flow control */ | 709 | /* don't set RTS if using hardware flow control */ |
| 710 | /* and throttling input */ | 710 | /* and throttling input */ |
| 711 | modem_signals = TIOCM_DTR; | 711 | modem_signals = TIOCM_DTR; |
| 712 | if (!(tty->termios->c_cflag & CRTSCTS) || | 712 | if (!(tty->termios.c_cflag & CRTSCTS) || |
| 713 | !test_bit(TTY_THROTTLED, &tty->flags)) | 713 | !test_bit(TTY_THROTTLED, &tty->flags)) |
| 714 | modem_signals |= TIOCM_RTS; | 714 | modem_signals |= TIOCM_RTS; |
| 715 | digi_set_modem_signals(port, modem_signals, 1); | 715 | digi_set_modem_signals(port, modem_signals, 1); |
| @@ -748,7 +748,7 @@ static void digi_set_termios(struct tty_struct *tty, | |||
| 748 | } | 748 | } |
| 749 | } | 749 | } |
| 750 | /* set parity */ | 750 | /* set parity */ |
| 751 | tty->termios->c_cflag &= ~CMSPAR; | 751 | tty->termios.c_cflag &= ~CMSPAR; |
| 752 | 752 | ||
| 753 | if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) { | 753 | if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) { |
| 754 | if (cflag&PARENB) { | 754 | if (cflag&PARENB) { |
| @@ -1124,8 +1124,8 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 1124 | 1124 | ||
| 1125 | /* set termios settings */ | 1125 | /* set termios settings */ |
| 1126 | if (tty) { | 1126 | if (tty) { |
| 1127 | not_termios.c_cflag = ~tty->termios->c_cflag; | 1127 | not_termios.c_cflag = ~tty->termios.c_cflag; |
| 1128 | not_termios.c_iflag = ~tty->termios->c_iflag; | 1128 | not_termios.c_iflag = ~tty->termios.c_iflag; |
| 1129 | digi_set_termios(tty, port, ¬_termios); | 1129 | digi_set_termios(tty, port, ¬_termios); |
| 1130 | } | 1130 | } |
| 1131 | return 0; | 1131 | return 0; |
| @@ -1500,7 +1500,7 @@ static int digi_read_oob_callback(struct urb *urb) | |||
| 1500 | 1500 | ||
| 1501 | rts = 0; | 1501 | rts = 0; |
| 1502 | if (tty) | 1502 | if (tty) |
| 1503 | rts = tty->termios->c_cflag & CRTSCTS; | 1503 | rts = tty->termios.c_cflag & CRTSCTS; |
| 1504 | 1504 | ||
| 1505 | if (tty && opcode == DIGI_CMD_READ_INPUT_SIGNALS) { | 1505 | if (tty && opcode == DIGI_CMD_READ_INPUT_SIGNALS) { |
| 1506 | spin_lock(&priv->dp_port_lock); | 1506 | spin_lock(&priv->dp_port_lock); |
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index cdf61dd07318..34e86383090a 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
| @@ -87,7 +87,7 @@ static int empeg_startup(struct usb_serial *serial) | |||
| 87 | 87 | ||
| 88 | static void empeg_init_termios(struct tty_struct *tty) | 88 | static void empeg_init_termios(struct tty_struct *tty) |
| 89 | { | 89 | { |
| 90 | struct ktermios *termios = tty->termios; | 90 | struct ktermios *termios = &tty->termios; |
| 91 | 91 | ||
| 92 | /* | 92 | /* |
| 93 | * The empeg-car player wants these particular tty settings. | 93 | * The empeg-car player wants these particular tty settings. |
diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 499b15fd82f1..79451ee12ca0 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c | |||
| @@ -173,10 +173,11 @@ static void f81232_set_termios(struct tty_struct *tty, | |||
| 173 | /* FIXME - Stubbed out for now */ | 173 | /* FIXME - Stubbed out for now */ |
| 174 | 174 | ||
| 175 | /* Don't change anything if nothing has changed */ | 175 | /* Don't change anything if nothing has changed */ |
| 176 | if (!tty_termios_hw_change(tty->termios, old_termios)) | 176 | if (!tty_termios_hw_change(&tty->termios, old_termios)) |
| 177 | return; | 177 | return; |
| 178 | 178 | ||
| 179 | /* Do the real work here... */ | 179 | /* Do the real work here... */ |
| 180 | tty_termios_copy_hw(&tty->termios, old_termios); | ||
| 180 | } | 181 | } |
| 181 | 182 | ||
| 182 | static int f81232_tiocmget(struct tty_struct *tty) | 183 | static int f81232_tiocmget(struct tty_struct *tty) |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index f906b3aec217..0c8d1c226273 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -2102,7 +2102,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
| 2102 | { | 2102 | { |
| 2103 | struct usb_device *dev = port->serial->dev; | 2103 | struct usb_device *dev = port->serial->dev; |
| 2104 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2104 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
| 2105 | struct ktermios *termios = tty->termios; | 2105 | struct ktermios *termios = &tty->termios; |
| 2106 | unsigned int cflag = termios->c_cflag; | 2106 | unsigned int cflag = termios->c_cflag; |
| 2107 | __u16 urb_value; /* will hold the new flags */ | 2107 | __u16 urb_value; /* will hold the new flags */ |
| 2108 | 2108 | ||
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index e1f5ccd1e8f8..f435575c4e6e 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
| @@ -1458,7 +1458,7 @@ static void edge_throttle(struct tty_struct *tty) | |||
| 1458 | } | 1458 | } |
| 1459 | 1459 | ||
| 1460 | /* if we are implementing RTS/CTS, toggle that line */ | 1460 | /* if we are implementing RTS/CTS, toggle that line */ |
| 1461 | if (tty->termios->c_cflag & CRTSCTS) { | 1461 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1462 | edge_port->shadowMCR &= ~MCR_RTS; | 1462 | edge_port->shadowMCR &= ~MCR_RTS; |
| 1463 | status = send_cmd_write_uart_register(edge_port, MCR, | 1463 | status = send_cmd_write_uart_register(edge_port, MCR, |
| 1464 | edge_port->shadowMCR); | 1464 | edge_port->shadowMCR); |
| @@ -1497,7 +1497,7 @@ static void edge_unthrottle(struct tty_struct *tty) | |||
| 1497 | return; | 1497 | return; |
| 1498 | } | 1498 | } |
| 1499 | /* if we are implementing RTS/CTS, toggle that line */ | 1499 | /* if we are implementing RTS/CTS, toggle that line */ |
| 1500 | if (tty->termios->c_cflag & CRTSCTS) { | 1500 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1501 | edge_port->shadowMCR |= MCR_RTS; | 1501 | edge_port->shadowMCR |= MCR_RTS; |
| 1502 | send_cmd_write_uart_register(edge_port, MCR, | 1502 | send_cmd_write_uart_register(edge_port, MCR, |
| 1503 | edge_port->shadowMCR); | 1503 | edge_port->shadowMCR); |
| @@ -1516,9 +1516,9 @@ static void edge_set_termios(struct tty_struct *tty, | |||
| 1516 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 1516 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
| 1517 | unsigned int cflag; | 1517 | unsigned int cflag; |
| 1518 | 1518 | ||
| 1519 | cflag = tty->termios->c_cflag; | 1519 | cflag = tty->termios.c_cflag; |
| 1520 | dbg("%s - clfag %08x iflag %08x", __func__, | 1520 | dbg("%s - clfag %08x iflag %08x", __func__, |
| 1521 | tty->termios->c_cflag, tty->termios->c_iflag); | 1521 | tty->termios.c_cflag, tty->termios.c_iflag); |
| 1522 | dbg("%s - old clfag %08x old iflag %08x", __func__, | 1522 | dbg("%s - old clfag %08x old iflag %08x", __func__, |
| 1523 | old_termios->c_cflag, old_termios->c_iflag); | 1523 | old_termios->c_cflag, old_termios->c_iflag); |
| 1524 | 1524 | ||
| @@ -1987,7 +1987,7 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial, | |||
| 1987 | tty = tty_port_tty_get(&edge_port->port->port); | 1987 | tty = tty_port_tty_get(&edge_port->port->port); |
| 1988 | if (tty) { | 1988 | if (tty) { |
| 1989 | change_port_settings(tty, | 1989 | change_port_settings(tty, |
| 1990 | edge_port, tty->termios); | 1990 | edge_port, &tty->termios); |
| 1991 | tty_kref_put(tty); | 1991 | tty_kref_put(tty); |
| 1992 | } | 1992 | } |
| 1993 | 1993 | ||
| @@ -2570,7 +2570,7 @@ static void change_port_settings(struct tty_struct *tty, | |||
| 2570 | return; | 2570 | return; |
| 2571 | } | 2571 | } |
| 2572 | 2572 | ||
| 2573 | cflag = tty->termios->c_cflag; | 2573 | cflag = tty->termios.c_cflag; |
| 2574 | 2574 | ||
| 2575 | switch (cflag & CSIZE) { | 2575 | switch (cflag & CSIZE) { |
| 2576 | case CS5: | 2576 | case CS5: |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 3936904c6419..765978ae752e 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
| @@ -1870,7 +1870,7 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 1870 | 1870 | ||
| 1871 | /* set up the port settings */ | 1871 | /* set up the port settings */ |
| 1872 | if (tty) | 1872 | if (tty) |
| 1873 | edge_set_termios(tty, port, tty->termios); | 1873 | edge_set_termios(tty, port, &tty->termios); |
| 1874 | 1874 | ||
| 1875 | /* open up the port */ | 1875 | /* open up the port */ |
| 1876 | 1876 | ||
| @@ -2272,13 +2272,13 @@ static void change_port_settings(struct tty_struct *tty, | |||
| 2272 | 2272 | ||
| 2273 | config = kmalloc (sizeof (*config), GFP_KERNEL); | 2273 | config = kmalloc (sizeof (*config), GFP_KERNEL); |
| 2274 | if (!config) { | 2274 | if (!config) { |
| 2275 | *tty->termios = *old_termios; | 2275 | tty->termios = *old_termios; |
| 2276 | dev_err(&edge_port->port->dev, "%s - out of memory\n", | 2276 | dev_err(&edge_port->port->dev, "%s - out of memory\n", |
| 2277 | __func__); | 2277 | __func__); |
| 2278 | return; | 2278 | return; |
| 2279 | } | 2279 | } |
| 2280 | 2280 | ||
| 2281 | cflag = tty->termios->c_cflag; | 2281 | cflag = tty->termios.c_cflag; |
| 2282 | 2282 | ||
| 2283 | config->wFlags = 0; | 2283 | config->wFlags = 0; |
| 2284 | 2284 | ||
| @@ -2362,7 +2362,7 @@ static void change_port_settings(struct tty_struct *tty, | |||
| 2362 | } else | 2362 | } else |
| 2363 | dbg("%s - OUTBOUND XON/XOFF is disabled", __func__); | 2363 | dbg("%s - OUTBOUND XON/XOFF is disabled", __func__); |
| 2364 | 2364 | ||
| 2365 | tty->termios->c_cflag &= ~CMSPAR; | 2365 | tty->termios.c_cflag &= ~CMSPAR; |
| 2366 | 2366 | ||
| 2367 | /* Round the baud rate */ | 2367 | /* Round the baud rate */ |
| 2368 | baud = tty_get_baud_rate(tty); | 2368 | baud = tty_get_baud_rate(tty); |
| @@ -2408,10 +2408,10 @@ static void edge_set_termios(struct tty_struct *tty, | |||
| 2408 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 2408 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
| 2409 | unsigned int cflag; | 2409 | unsigned int cflag; |
| 2410 | 2410 | ||
| 2411 | cflag = tty->termios->c_cflag; | 2411 | cflag = tty->termios.c_cflag; |
| 2412 | 2412 | ||
| 2413 | dbg("%s - clfag %08x iflag %08x", __func__, | 2413 | dbg("%s - clfag %08x iflag %08x", __func__, |
| 2414 | tty->termios->c_cflag, tty->termios->c_iflag); | 2414 | tty->termios.c_cflag, tty->termios.c_iflag); |
| 2415 | dbg("%s - old clfag %08x old iflag %08x", __func__, | 2415 | dbg("%s - old clfag %08x old iflag %08x", __func__, |
| 2416 | old_termios->c_cflag, old_termios->c_iflag); | 2416 | old_termios->c_cflag, old_termios->c_iflag); |
| 2417 | dbg("%s - port %d", __func__, port->number); | 2417 | dbg("%s - port %d", __func__, port->number); |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index fc09414c960f..5a96692b12a2 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
| @@ -381,7 +381,7 @@ static void ir_set_termios(struct tty_struct *tty, | |||
| 381 | ir_xbof = ir_xbof_change(xbof) ; | 381 | ir_xbof = ir_xbof_change(xbof) ; |
| 382 | 382 | ||
| 383 | /* Only speed changes are supported */ | 383 | /* Only speed changes are supported */ |
| 384 | tty_termios_copy_hw(tty->termios, old_termios); | 384 | tty_termios_copy_hw(&tty->termios, old_termios); |
| 385 | tty_encode_baud_rate(tty, baud, baud); | 385 | tty_encode_baud_rate(tty, baud, baud); |
| 386 | 386 | ||
| 387 | /* | 387 | /* |
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 22b1eb5040b7..bf3864045c18 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
| @@ -921,7 +921,7 @@ static void iuu_set_termios(struct tty_struct *tty, | |||
| 921 | { | 921 | { |
| 922 | const u32 supported_mask = CMSPAR|PARENB|PARODD; | 922 | const u32 supported_mask = CMSPAR|PARENB|PARODD; |
| 923 | struct iuu_private *priv = usb_get_serial_port_data(port); | 923 | struct iuu_private *priv = usb_get_serial_port_data(port); |
| 924 | unsigned int cflag = tty->termios->c_cflag; | 924 | unsigned int cflag = tty->termios.c_cflag; |
| 925 | int status; | 925 | int status; |
| 926 | u32 actual; | 926 | u32 actual; |
| 927 | u32 parity; | 927 | u32 parity; |
| @@ -930,7 +930,7 @@ static void iuu_set_termios(struct tty_struct *tty, | |||
| 930 | u32 newval = cflag & supported_mask; | 930 | u32 newval = cflag & supported_mask; |
| 931 | 931 | ||
| 932 | /* Just use the ospeed. ispeed should be the same. */ | 932 | /* Just use the ospeed. ispeed should be the same. */ |
| 933 | baud = tty->termios->c_ospeed; | 933 | baud = tty->termios.c_ospeed; |
| 934 | 934 | ||
| 935 | dbg("%s - enter c_ospeed or baud=%d", __func__, baud); | 935 | dbg("%s - enter c_ospeed or baud=%d", __func__, baud); |
| 936 | 936 | ||
| @@ -961,13 +961,13 @@ static void iuu_set_termios(struct tty_struct *tty, | |||
| 961 | * settings back over and then adjust them | 961 | * settings back over and then adjust them |
| 962 | */ | 962 | */ |
| 963 | if (old_termios) | 963 | if (old_termios) |
| 964 | tty_termios_copy_hw(tty->termios, old_termios); | 964 | tty_termios_copy_hw(&tty->termios, old_termios); |
| 965 | if (status != 0) /* Set failed - return old bits */ | 965 | if (status != 0) /* Set failed - return old bits */ |
| 966 | return; | 966 | return; |
| 967 | /* Re-encode speed, parity and csize */ | 967 | /* Re-encode speed, parity and csize */ |
| 968 | tty_encode_baud_rate(tty, baud, baud); | 968 | tty_encode_baud_rate(tty, baud, baud); |
| 969 | tty->termios->c_cflag &= ~(supported_mask|CSIZE); | 969 | tty->termios.c_cflag &= ~(supported_mask|CSIZE); |
| 970 | tty->termios->c_cflag |= newval | csize; | 970 | tty->termios.c_cflag |= newval | csize; |
| 971 | } | 971 | } |
| 972 | 972 | ||
| 973 | static void iuu_close(struct usb_serial_port *port) | 973 | static void iuu_close(struct usb_serial_port *port) |
| @@ -993,14 +993,14 @@ static void iuu_close(struct usb_serial_port *port) | |||
| 993 | 993 | ||
| 994 | static void iuu_init_termios(struct tty_struct *tty) | 994 | static void iuu_init_termios(struct tty_struct *tty) |
| 995 | { | 995 | { |
| 996 | *(tty->termios) = tty_std_termios; | 996 | tty->termios = tty_std_termios; |
| 997 | tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600 | 997 | tty->termios.c_cflag = CLOCAL | CREAD | CS8 | B9600 |
| 998 | | TIOCM_CTS | CSTOPB | PARENB; | 998 | | TIOCM_CTS | CSTOPB | PARENB; |
| 999 | tty->termios->c_ispeed = 9600; | 999 | tty->termios.c_ispeed = 9600; |
| 1000 | tty->termios->c_ospeed = 9600; | 1000 | tty->termios.c_ospeed = 9600; |
| 1001 | tty->termios->c_lflag = 0; | 1001 | tty->termios.c_lflag = 0; |
| 1002 | tty->termios->c_oflag = 0; | 1002 | tty->termios.c_oflag = 0; |
| 1003 | tty->termios->c_iflag = 0; | 1003 | tty->termios.c_iflag = 0; |
| 1004 | } | 1004 | } |
| 1005 | 1005 | ||
| 1006 | static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) | 1006 | static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) |
| @@ -1012,8 +1012,8 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 1012 | u32 actual; | 1012 | u32 actual; |
| 1013 | struct iuu_private *priv = usb_get_serial_port_data(port); | 1013 | struct iuu_private *priv = usb_get_serial_port_data(port); |
| 1014 | 1014 | ||
| 1015 | baud = tty->termios->c_ospeed; | 1015 | baud = tty->termios.c_ospeed; |
| 1016 | tty->termios->c_ispeed = baud; | 1016 | tty->termios.c_ispeed = baud; |
| 1017 | /* Re-encode speed */ | 1017 | /* Re-encode speed */ |
| 1018 | tty_encode_baud_rate(tty, baud, baud); | 1018 | tty_encode_baud_rate(tty, baud, baud); |
| 1019 | 1019 | ||
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index af0b70eaf032..7bcbb47e1449 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
| @@ -158,7 +158,7 @@ static void keyspan_set_termios(struct tty_struct *tty, | |||
| 158 | 158 | ||
| 159 | p_priv = usb_get_serial_port_data(port); | 159 | p_priv = usb_get_serial_port_data(port); |
| 160 | d_details = p_priv->device_details; | 160 | d_details = p_priv->device_details; |
| 161 | cflag = tty->termios->c_cflag; | 161 | cflag = tty->termios.c_cflag; |
| 162 | device_port = port->number - port->serial->minor; | 162 | device_port = port->number - port->serial->minor; |
| 163 | 163 | ||
| 164 | /* Baud rate calculation takes baud rate as an integer | 164 | /* Baud rate calculation takes baud rate as an integer |
| @@ -179,7 +179,7 @@ static void keyspan_set_termios(struct tty_struct *tty, | |||
| 179 | p_priv->flow_control = (cflag & CRTSCTS) ? flow_cts : flow_none; | 179 | p_priv->flow_control = (cflag & CRTSCTS) ? flow_cts : flow_none; |
| 180 | 180 | ||
| 181 | /* Mark/Space not supported */ | 181 | /* Mark/Space not supported */ |
| 182 | tty->termios->c_cflag &= ~CMSPAR; | 182 | tty->termios.c_cflag &= ~CMSPAR; |
| 183 | 183 | ||
| 184 | keyspan_send_setup(port, 0); | 184 | keyspan_send_setup(port, 0); |
| 185 | } | 185 | } |
| @@ -1086,7 +1086,7 @@ static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 1086 | 1086 | ||
| 1087 | device_port = port->number - port->serial->minor; | 1087 | device_port = port->number - port->serial->minor; |
| 1088 | if (tty) { | 1088 | if (tty) { |
| 1089 | cflag = tty->termios->c_cflag; | 1089 | cflag = tty->termios.c_cflag; |
| 1090 | /* Baud rate calculation takes baud rate as an integer | 1090 | /* Baud rate calculation takes baud rate as an integer |
| 1091 | so other rates can be generated if desired. */ | 1091 | so other rates can be generated if desired. */ |
| 1092 | baud_rate = tty_get_baud_rate(tty); | 1092 | baud_rate = tty_get_baud_rate(tty); |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index a4ac3cfeffc4..dcada8615fcf 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
| @@ -338,7 +338,7 @@ static void keyspan_pda_set_termios(struct tty_struct *tty, | |||
| 338 | 7[EOMS]1: 10 bit, b0/b7 is parity | 338 | 7[EOMS]1: 10 bit, b0/b7 is parity |
| 339 | 7[EOMS]2: 11 bit, b0/b7 is parity, extra bit always (mark?) | 339 | 7[EOMS]2: 11 bit, b0/b7 is parity, extra bit always (mark?) |
| 340 | 340 | ||
| 341 | HW flow control is dictated by the tty->termios->c_cflags & CRTSCTS | 341 | HW flow control is dictated by the tty->termios.c_cflags & CRTSCTS |
| 342 | bit. | 342 | bit. |
| 343 | 343 | ||
| 344 | For now, just do baud. */ | 344 | For now, just do baud. */ |
| @@ -353,7 +353,7 @@ static void keyspan_pda_set_termios(struct tty_struct *tty, | |||
| 353 | } | 353 | } |
| 354 | /* Only speed can change so copy the old h/w parameters | 354 | /* Only speed can change so copy the old h/w parameters |
| 355 | then encode the new speed */ | 355 | then encode the new speed */ |
| 356 | tty_termios_copy_hw(tty->termios, old_termios); | 356 | tty_termios_copy_hw(&tty->termios, old_termios); |
| 357 | tty_encode_baud_rate(tty, speed, speed); | 357 | tty_encode_baud_rate(tty, speed, speed); |
| 358 | } | 358 | } |
| 359 | 359 | ||
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 5bed59cd5776..def9ad258715 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
| @@ -311,12 +311,12 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 311 | 311 | ||
| 312 | /* set up termios structure */ | 312 | /* set up termios structure */ |
| 313 | spin_lock_irqsave(&priv->lock, flags); | 313 | spin_lock_irqsave(&priv->lock, flags); |
| 314 | priv->termios.c_iflag = tty->termios->c_iflag; | 314 | priv->termios.c_iflag = tty->termios.c_iflag; |
| 315 | priv->termios.c_oflag = tty->termios->c_oflag; | 315 | priv->termios.c_oflag = tty->termios.c_oflag; |
| 316 | priv->termios.c_cflag = tty->termios->c_cflag; | 316 | priv->termios.c_cflag = tty->termios.c_cflag; |
| 317 | priv->termios.c_lflag = tty->termios->c_lflag; | 317 | priv->termios.c_lflag = tty->termios.c_lflag; |
| 318 | for (i = 0; i < NCCS; i++) | 318 | for (i = 0; i < NCCS; i++) |
| 319 | priv->termios.c_cc[i] = tty->termios->c_cc[i]; | 319 | priv->termios.c_cc[i] = tty->termios.c_cc[i]; |
| 320 | priv->cfg.pktlen = cfg->pktlen; | 320 | priv->cfg.pktlen = cfg->pktlen; |
| 321 | priv->cfg.baudrate = cfg->baudrate; | 321 | priv->cfg.baudrate = cfg->baudrate; |
| 322 | priv->cfg.databits = cfg->databits; | 322 | priv->cfg.databits = cfg->databits; |
| @@ -445,9 +445,9 @@ static void klsi_105_set_termios(struct tty_struct *tty, | |||
| 445 | struct ktermios *old_termios) | 445 | struct ktermios *old_termios) |
| 446 | { | 446 | { |
| 447 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | 447 | struct klsi_105_private *priv = usb_get_serial_port_data(port); |
| 448 | unsigned int iflag = tty->termios->c_iflag; | 448 | unsigned int iflag = tty->termios.c_iflag; |
| 449 | unsigned int old_iflag = old_termios->c_iflag; | 449 | unsigned int old_iflag = old_termios->c_iflag; |
| 450 | unsigned int cflag = tty->termios->c_cflag; | 450 | unsigned int cflag = tty->termios.c_cflag; |
| 451 | unsigned int old_cflag = old_termios->c_cflag; | 451 | unsigned int old_cflag = old_termios->c_cflag; |
| 452 | struct klsi_105_port_settings *cfg; | 452 | struct klsi_105_port_settings *cfg; |
| 453 | unsigned long flags; | 453 | unsigned long flags; |
| @@ -560,7 +560,7 @@ static void klsi_105_set_termios(struct tty_struct *tty, | |||
| 560 | if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD)) | 560 | if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD)) |
| 561 | || (cflag & CSTOPB) != (old_cflag & CSTOPB)) { | 561 | || (cflag & CSTOPB) != (old_cflag & CSTOPB)) { |
| 562 | /* Not currently supported */ | 562 | /* Not currently supported */ |
| 563 | tty->termios->c_cflag &= ~(PARENB|PARODD|CSTOPB); | 563 | tty->termios.c_cflag &= ~(PARENB|PARODD|CSTOPB); |
| 564 | #if 0 | 564 | #if 0 |
| 565 | priv->last_lcr = 0; | 565 | priv->last_lcr = 0; |
| 566 | 566 | ||
| @@ -587,7 +587,7 @@ static void klsi_105_set_termios(struct tty_struct *tty, | |||
| 587 | || (iflag & IXON) != (old_iflag & IXON) | 587 | || (iflag & IXON) != (old_iflag & IXON) |
| 588 | || (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { | 588 | || (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { |
| 589 | /* Not currently supported */ | 589 | /* Not currently supported */ |
| 590 | tty->termios->c_cflag &= ~CRTSCTS; | 590 | tty->termios.c_cflag &= ~CRTSCTS; |
| 591 | /* Drop DTR/RTS if no flow control otherwise assert */ | 591 | /* Drop DTR/RTS if no flow control otherwise assert */ |
| 592 | #if 0 | 592 | #if 0 |
| 593 | if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS)) | 593 | if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS)) |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index fafeabb64c55..bf5c74965d34 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
| @@ -191,11 +191,11 @@ static void kobil_release(struct usb_serial *serial) | |||
| 191 | static void kobil_init_termios(struct tty_struct *tty) | 191 | static void kobil_init_termios(struct tty_struct *tty) |
| 192 | { | 192 | { |
| 193 | /* Default to echo off and other sane device settings */ | 193 | /* Default to echo off and other sane device settings */ |
| 194 | tty->termios->c_lflag = 0; | 194 | tty->termios.c_lflag = 0; |
| 195 | tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE); | 195 | tty->termios.c_iflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE); |
| 196 | tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF; | 196 | tty->termios.c_iflag |= IGNBRK | IGNPAR | IXOFF; |
| 197 | /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */ | 197 | /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */ |
| 198 | tty->termios->c_oflag &= ~ONLCR; | 198 | tty->termios.c_oflag &= ~ONLCR; |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port) | 201 | static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port) |
| @@ -581,14 +581,14 @@ static void kobil_set_termios(struct tty_struct *tty, | |||
| 581 | struct kobil_private *priv; | 581 | struct kobil_private *priv; |
| 582 | int result; | 582 | int result; |
| 583 | unsigned short urb_val = 0; | 583 | unsigned short urb_val = 0; |
| 584 | int c_cflag = tty->termios->c_cflag; | 584 | int c_cflag = tty->termios.c_cflag; |
| 585 | speed_t speed; | 585 | speed_t speed; |
| 586 | 586 | ||
| 587 | priv = usb_get_serial_port_data(port); | 587 | priv = usb_get_serial_port_data(port); |
| 588 | if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || | 588 | if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || |
| 589 | priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { | 589 | priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { |
| 590 | /* This device doesn't support ioctl calls */ | 590 | /* This device doesn't support ioctl calls */ |
| 591 | *tty->termios = *old; | 591 | tty_termios_copy_hw(&tty->termios, old); |
| 592 | return; | 592 | return; |
| 593 | } | 593 | } |
| 594 | 594 | ||
| @@ -612,7 +612,7 @@ static void kobil_set_termios(struct tty_struct *tty, | |||
| 612 | urb_val |= SUSBCR_SPASB_EvenParity; | 612 | urb_val |= SUSBCR_SPASB_EvenParity; |
| 613 | } else | 613 | } else |
| 614 | urb_val |= SUSBCR_SPASB_NoParity; | 614 | urb_val |= SUSBCR_SPASB_NoParity; |
| 615 | tty->termios->c_cflag &= ~CMSPAR; | 615 | tty->termios.c_cflag &= ~CMSPAR; |
| 616 | tty_encode_baud_rate(tty, speed, speed); | 616 | tty_encode_baud_rate(tty, speed, speed); |
| 617 | 617 | ||
| 618 | result = usb_control_msg(port->serial->dev, | 618 | result = usb_control_msg(port->serial->dev, |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index a71fa0aa0406..df98cffdba65 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
| @@ -454,7 +454,7 @@ static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 454 | * either. | 454 | * either. |
| 455 | */ | 455 | */ |
| 456 | spin_lock_irqsave(&priv->lock, flags); | 456 | spin_lock_irqsave(&priv->lock, flags); |
| 457 | if (tty && (tty->termios->c_cflag & CBAUD)) | 457 | if (tty && (tty->termios.c_cflag & CBAUD)) |
| 458 | priv->control_state = TIOCM_DTR | TIOCM_RTS; | 458 | priv->control_state = TIOCM_DTR | TIOCM_RTS; |
| 459 | else | 459 | else |
| 460 | priv->control_state = 0; | 460 | priv->control_state = 0; |
| @@ -634,7 +634,7 @@ static void mct_u232_set_termios(struct tty_struct *tty, | |||
| 634 | { | 634 | { |
| 635 | struct usb_serial *serial = port->serial; | 635 | struct usb_serial *serial = port->serial; |
| 636 | struct mct_u232_private *priv = usb_get_serial_port_data(port); | 636 | struct mct_u232_private *priv = usb_get_serial_port_data(port); |
| 637 | struct ktermios *termios = tty->termios; | 637 | struct ktermios *termios = &tty->termios; |
| 638 | unsigned int cflag = termios->c_cflag; | 638 | unsigned int cflag = termios->c_cflag; |
| 639 | unsigned int old_cflag = old_termios->c_cflag; | 639 | unsigned int old_cflag = old_termios->c_cflag; |
| 640 | unsigned long flags; | 640 | unsigned long flags; |
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index d47eb06fe463..2b0627b5fe2c 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c | |||
| @@ -130,12 +130,6 @@ static void metrousb_read_int_callback(struct urb *urb) | |||
| 130 | 130 | ||
| 131 | /* Set the data read from the usb port into the serial port buffer. */ | 131 | /* Set the data read from the usb port into the serial port buffer. */ |
| 132 | tty = tty_port_tty_get(&port->port); | 132 | tty = tty_port_tty_get(&port->port); |
| 133 | if (!tty) { | ||
| 134 | dev_err(&port->dev, "%s - bad tty pointer - exiting\n", | ||
| 135 | __func__); | ||
| 136 | return; | ||
| 137 | } | ||
| 138 | |||
| 139 | if (tty && urb->actual_length) { | 133 | if (tty && urb->actual_length) { |
| 140 | /* Loop through the data copying each byte to the tty layer. */ | 134 | /* Loop through the data copying each byte to the tty layer. */ |
| 141 | tty_insert_flip_string(tty, data, urb->actual_length); | 135 | tty_insert_flip_string(tty, data, urb->actual_length); |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index a07dd3c8cfef..012f67b2e4cc 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
| @@ -1349,7 +1349,7 @@ static void mos7720_throttle(struct tty_struct *tty) | |||
| 1349 | } | 1349 | } |
| 1350 | 1350 | ||
| 1351 | /* if we are implementing RTS/CTS, toggle that line */ | 1351 | /* if we are implementing RTS/CTS, toggle that line */ |
| 1352 | if (tty->termios->c_cflag & CRTSCTS) { | 1352 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1353 | mos7720_port->shadowMCR &= ~UART_MCR_RTS; | 1353 | mos7720_port->shadowMCR &= ~UART_MCR_RTS; |
| 1354 | write_mos_reg(port->serial, port->number - port->serial->minor, | 1354 | write_mos_reg(port->serial, port->number - port->serial->minor, |
| 1355 | MCR, mos7720_port->shadowMCR); | 1355 | MCR, mos7720_port->shadowMCR); |
| @@ -1383,7 +1383,7 @@ static void mos7720_unthrottle(struct tty_struct *tty) | |||
| 1383 | } | 1383 | } |
| 1384 | 1384 | ||
| 1385 | /* if we are implementing RTS/CTS, toggle that line */ | 1385 | /* if we are implementing RTS/CTS, toggle that line */ |
| 1386 | if (tty->termios->c_cflag & CRTSCTS) { | 1386 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1387 | mos7720_port->shadowMCR |= UART_MCR_RTS; | 1387 | mos7720_port->shadowMCR |= UART_MCR_RTS; |
| 1388 | write_mos_reg(port->serial, port->number - port->serial->minor, | 1388 | write_mos_reg(port->serial, port->number - port->serial->minor, |
| 1389 | MCR, mos7720_port->shadowMCR); | 1389 | MCR, mos7720_port->shadowMCR); |
| @@ -1604,8 +1604,8 @@ static void change_port_settings(struct tty_struct *tty, | |||
| 1604 | lStop = 0x00; /* 1 stop bit */ | 1604 | lStop = 0x00; /* 1 stop bit */ |
| 1605 | lParity = 0x00; /* No parity */ | 1605 | lParity = 0x00; /* No parity */ |
| 1606 | 1606 | ||
| 1607 | cflag = tty->termios->c_cflag; | 1607 | cflag = tty->termios.c_cflag; |
| 1608 | iflag = tty->termios->c_iflag; | 1608 | iflag = tty->termios.c_iflag; |
| 1609 | 1609 | ||
| 1610 | /* Change the number of bits */ | 1610 | /* Change the number of bits */ |
| 1611 | switch (cflag & CSIZE) { | 1611 | switch (cflag & CSIZE) { |
| @@ -1753,11 +1753,11 @@ static void mos7720_set_termios(struct tty_struct *tty, | |||
| 1753 | 1753 | ||
| 1754 | dbg("%s\n", "setting termios - ASPIRE"); | 1754 | dbg("%s\n", "setting termios - ASPIRE"); |
| 1755 | 1755 | ||
| 1756 | cflag = tty->termios->c_cflag; | 1756 | cflag = tty->termios.c_cflag; |
| 1757 | 1757 | ||
| 1758 | dbg("%s - cflag %08x iflag %08x", __func__, | 1758 | dbg("%s - cflag %08x iflag %08x", __func__, |
| 1759 | tty->termios->c_cflag, | 1759 | tty->termios.c_cflag, |
| 1760 | RELEVANT_IFLAG(tty->termios->c_iflag)); | 1760 | RELEVANT_IFLAG(tty->termios.c_iflag)); |
| 1761 | 1761 | ||
| 1762 | dbg("%s - old cflag %08x old iflag %08x", __func__, | 1762 | dbg("%s - old cflag %08x old iflag %08x", __func__, |
| 1763 | old_termios->c_cflag, | 1763 | old_termios->c_cflag, |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 2f6da1e89bfa..402c32d7accb 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
| @@ -1651,7 +1651,7 @@ static void mos7840_throttle(struct tty_struct *tty) | |||
| 1651 | return; | 1651 | return; |
| 1652 | } | 1652 | } |
| 1653 | /* if we are implementing RTS/CTS, toggle that line */ | 1653 | /* if we are implementing RTS/CTS, toggle that line */ |
| 1654 | if (tty->termios->c_cflag & CRTSCTS) { | 1654 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1655 | mos7840_port->shadowMCR &= ~MCR_RTS; | 1655 | mos7840_port->shadowMCR &= ~MCR_RTS; |
| 1656 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, | 1656 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, |
| 1657 | mos7840_port->shadowMCR); | 1657 | mos7840_port->shadowMCR); |
| @@ -1694,7 +1694,7 @@ static void mos7840_unthrottle(struct tty_struct *tty) | |||
| 1694 | } | 1694 | } |
| 1695 | 1695 | ||
| 1696 | /* if we are implementing RTS/CTS, toggle that line */ | 1696 | /* if we are implementing RTS/CTS, toggle that line */ |
| 1697 | if (tty->termios->c_cflag & CRTSCTS) { | 1697 | if (tty->termios.c_cflag & CRTSCTS) { |
| 1698 | mos7840_port->shadowMCR |= MCR_RTS; | 1698 | mos7840_port->shadowMCR |= MCR_RTS; |
| 1699 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, | 1699 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, |
| 1700 | mos7840_port->shadowMCR); | 1700 | mos7840_port->shadowMCR); |
| @@ -2000,8 +2000,8 @@ static void mos7840_change_port_settings(struct tty_struct *tty, | |||
| 2000 | lStop = LCR_STOP_1; | 2000 | lStop = LCR_STOP_1; |
| 2001 | lParity = LCR_PAR_NONE; | 2001 | lParity = LCR_PAR_NONE; |
| 2002 | 2002 | ||
| 2003 | cflag = tty->termios->c_cflag; | 2003 | cflag = tty->termios.c_cflag; |
| 2004 | iflag = tty->termios->c_iflag; | 2004 | iflag = tty->termios.c_iflag; |
| 2005 | 2005 | ||
| 2006 | /* Change the number of bits */ | 2006 | /* Change the number of bits */ |
| 2007 | if (cflag & CSIZE) { | 2007 | if (cflag & CSIZE) { |
| @@ -2161,10 +2161,10 @@ static void mos7840_set_termios(struct tty_struct *tty, | |||
| 2161 | 2161 | ||
| 2162 | dbg("%s", "setting termios - "); | 2162 | dbg("%s", "setting termios - "); |
| 2163 | 2163 | ||
| 2164 | cflag = tty->termios->c_cflag; | 2164 | cflag = tty->termios.c_cflag; |
| 2165 | 2165 | ||
| 2166 | dbg("%s - clfag %08x iflag %08x", __func__, | 2166 | dbg("%s - clfag %08x iflag %08x", __func__, |
| 2167 | tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); | 2167 | tty->termios.c_cflag, RELEVANT_IFLAG(tty->termios.c_iflag)); |
| 2168 | dbg("%s - old clfag %08x old iflag %08x", __func__, | 2168 | dbg("%s - old clfag %08x old iflag %08x", __func__, |
| 2169 | old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag)); | 2169 | old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag)); |
| 2170 | dbg("%s - port %d", __func__, port->number); | 2170 | dbg("%s - port %d", __func__, port->number); |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 5976b65ab6ee..9f555560bfbf 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
| @@ -404,10 +404,10 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty) | |||
| 404 | 404 | ||
| 405 | static void oti6858_init_termios(struct tty_struct *tty) | 405 | static void oti6858_init_termios(struct tty_struct *tty) |
| 406 | { | 406 | { |
| 407 | *(tty->termios) = tty_std_termios; | 407 | tty->termios = tty_std_termios; |
| 408 | tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; | 408 | tty->termios.c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; |
| 409 | tty->termios->c_ispeed = 38400; | 409 | tty->termios.c_ispeed = 38400; |
| 410 | tty->termios->c_ospeed = 38400; | 410 | tty->termios.c_ospeed = 38400; |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | static void oti6858_set_termios(struct tty_struct *tty, | 413 | static void oti6858_set_termios(struct tty_struct *tty, |
| @@ -425,7 +425,7 @@ static void oti6858_set_termios(struct tty_struct *tty, | |||
| 425 | return; | 425 | return; |
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | cflag = tty->termios->c_cflag; | 428 | cflag = tty->termios.c_cflag; |
| 429 | 429 | ||
| 430 | spin_lock_irqsave(&priv->lock, flags); | 430 | spin_lock_irqsave(&priv->lock, flags); |
| 431 | divisor = priv->pending_setup.divisor; | 431 | divisor = priv->pending_setup.divisor; |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 13b8dd6481f5..2b9108a8ea64 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
| @@ -260,16 +260,16 @@ static void pl2303_set_termios(struct tty_struct *tty, | |||
| 260 | serial settings even to the same values as before. Thus | 260 | serial settings even to the same values as before. Thus |
| 261 | we actually need to filter in this specific case */ | 261 | we actually need to filter in this specific case */ |
| 262 | 262 | ||
| 263 | if (!tty_termios_hw_change(tty->termios, old_termios)) | 263 | if (!tty_termios_hw_change(&tty->termios, old_termios)) |
| 264 | return; | 264 | return; |
| 265 | 265 | ||
| 266 | cflag = tty->termios->c_cflag; | 266 | cflag = tty->termios.c_cflag; |
| 267 | 267 | ||
| 268 | buf = kzalloc(7, GFP_KERNEL); | 268 | buf = kzalloc(7, GFP_KERNEL); |
| 269 | if (!buf) { | 269 | if (!buf) { |
| 270 | dev_err(&port->dev, "%s - out of memory.\n", __func__); | 270 | dev_err(&port->dev, "%s - out of memory.\n", __func__); |
| 271 | /* Report back no change occurred */ | 271 | /* Report back no change occurred */ |
| 272 | *tty->termios = *old_termios; | 272 | tty->termios = *old_termios; |
| 273 | return; | 273 | return; |
| 274 | } | 274 | } |
| 275 | 275 | ||
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 151670b6b72a..7df9cdb053ed 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c | |||
| @@ -275,7 +275,7 @@ static void qt2_set_termios(struct tty_struct *tty, | |||
| 275 | { | 275 | { |
| 276 | struct usb_device *dev = port->serial->dev; | 276 | struct usb_device *dev = port->serial->dev; |
| 277 | struct qt2_port_private *port_priv; | 277 | struct qt2_port_private *port_priv; |
| 278 | struct ktermios *termios = tty->termios; | 278 | struct ktermios *termios = &tty->termios; |
| 279 | u16 baud; | 279 | u16 baud; |
| 280 | unsigned int cflag = termios->c_cflag; | 280 | unsigned int cflag = termios->c_cflag; |
| 281 | u16 new_lcr = 0; | 281 | u16 new_lcr = 0; |
| @@ -406,7 +406,7 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 406 | port_priv->device_port = (u8) device_port; | 406 | port_priv->device_port = (u8) device_port; |
| 407 | 407 | ||
| 408 | if (tty) | 408 | if (tty) |
| 409 | qt2_set_termios(tty, port, tty->termios); | 409 | qt2_set_termios(tty, port, &tty->termios); |
| 410 | 410 | ||
| 411 | return 0; | 411 | return 0; |
| 412 | 412 | ||
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 0274710cced5..b14ebbd73567 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
| @@ -382,7 +382,7 @@ static int sierra_send_setup(struct usb_serial_port *port) | |||
| 382 | static void sierra_set_termios(struct tty_struct *tty, | 382 | static void sierra_set_termios(struct tty_struct *tty, |
| 383 | struct usb_serial_port *port, struct ktermios *old_termios) | 383 | struct usb_serial_port *port, struct ktermios *old_termios) |
| 384 | { | 384 | { |
| 385 | tty_termios_copy_hw(tty->termios, old_termios); | 385 | tty_termios_copy_hw(&tty->termios, old_termios); |
| 386 | sierra_send_setup(port); | 386 | sierra_send_setup(port); |
| 387 | } | 387 | } |
| 388 | 388 | ||
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index cad608984710..ab68a4d74d61 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c | |||
| @@ -316,10 +316,10 @@ static void spcp8x5_dtr_rts(struct usb_serial_port *port, int on) | |||
| 316 | static void spcp8x5_init_termios(struct tty_struct *tty) | 316 | static void spcp8x5_init_termios(struct tty_struct *tty) |
| 317 | { | 317 | { |
| 318 | /* for the 1st time call this function */ | 318 | /* for the 1st time call this function */ |
| 319 | *(tty->termios) = tty_std_termios; | 319 | tty->termios = tty_std_termios; |
| 320 | tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL; | 320 | tty->termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL; |
| 321 | tty->termios->c_ispeed = 115200; | 321 | tty->termios.c_ispeed = 115200; |
| 322 | tty->termios->c_ospeed = 115200; | 322 | tty->termios.c_ospeed = 115200; |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | /* set the serial param for transfer. we should check if we really need to | 325 | /* set the serial param for transfer. we should check if we really need to |
| @@ -330,7 +330,7 @@ static void spcp8x5_set_termios(struct tty_struct *tty, | |||
| 330 | struct usb_serial *serial = port->serial; | 330 | struct usb_serial *serial = port->serial; |
| 331 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | 331 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); |
| 332 | unsigned long flags; | 332 | unsigned long flags; |
| 333 | unsigned int cflag = tty->termios->c_cflag; | 333 | unsigned int cflag = tty->termios.c_cflag; |
| 334 | unsigned int old_cflag = old_termios->c_cflag; | 334 | unsigned int old_cflag = old_termios->c_cflag; |
| 335 | unsigned short uartdata; | 335 | unsigned short uartdata; |
| 336 | unsigned char buf[2] = {0, 0}; | 336 | unsigned char buf[2] = {0, 0}; |
| @@ -340,7 +340,7 @@ static void spcp8x5_set_termios(struct tty_struct *tty, | |||
| 340 | 340 | ||
| 341 | 341 | ||
| 342 | /* check that they really want us to change something */ | 342 | /* check that they really want us to change something */ |
| 343 | if (!tty_termios_hw_change(tty->termios, old_termios)) | 343 | if (!tty_termios_hw_change(&tty->termios, old_termios)) |
| 344 | return; | 344 | return; |
| 345 | 345 | ||
| 346 | /* set DTR/RTS active */ | 346 | /* set DTR/RTS active */ |
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 3fee23bf0c14..cf2d30cf7588 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c | |||
| @@ -216,7 +216,7 @@ static void ssu100_set_termios(struct tty_struct *tty, | |||
| 216 | struct ktermios *old_termios) | 216 | struct ktermios *old_termios) |
| 217 | { | 217 | { |
| 218 | struct usb_device *dev = port->serial->dev; | 218 | struct usb_device *dev = port->serial->dev; |
| 219 | struct ktermios *termios = tty->termios; | 219 | struct ktermios *termios = &tty->termios; |
| 220 | u16 baud, divisor, remainder; | 220 | u16 baud, divisor, remainder; |
| 221 | unsigned int cflag = termios->c_cflag; | 221 | unsigned int cflag = termios->c_cflag; |
| 222 | u16 urb_value = 0; /* will hold the new flags */ | 222 | u16 urb_value = 0; /* will hold the new flags */ |
| @@ -322,7 +322,7 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 322 | dbg("%s - set uart failed", __func__); | 322 | dbg("%s - set uart failed", __func__); |
| 323 | 323 | ||
| 324 | if (tty) | 324 | if (tty) |
| 325 | ssu100_set_termios(tty, port, tty->termios); | 325 | ssu100_set_termios(tty, port, &tty->termios); |
| 326 | 326 | ||
| 327 | return usb_serial_generic_open(tty, port); | 327 | return usb_serial_generic_open(tty, port); |
| 328 | } | 328 | } |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index a4404f5ad68e..f502a16aac21 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
| @@ -520,7 +520,7 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 520 | } | 520 | } |
| 521 | 521 | ||
| 522 | if (tty) | 522 | if (tty) |
| 523 | ti_set_termios(tty, port, tty->termios); | 523 | ti_set_termios(tty, port, &tty->termios); |
| 524 | 524 | ||
| 525 | dbg("%s - sending TI_OPEN_PORT", __func__); | 525 | dbg("%s - sending TI_OPEN_PORT", __func__); |
| 526 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, | 526 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, |
| @@ -562,7 +562,7 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 562 | usb_clear_halt(dev, port->read_urb->pipe); | 562 | usb_clear_halt(dev, port->read_urb->pipe); |
| 563 | 563 | ||
| 564 | if (tty) | 564 | if (tty) |
| 565 | ti_set_termios(tty, port, tty->termios); | 565 | ti_set_termios(tty, port, &tty->termios); |
| 566 | 566 | ||
| 567 | dbg("%s - sending TI_OPEN_PORT (2)", __func__); | 567 | dbg("%s - sending TI_OPEN_PORT (2)", __func__); |
| 568 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, | 568 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, |
| @@ -831,8 +831,8 @@ static void ti_set_termios(struct tty_struct *tty, | |||
| 831 | int port_number = port->number - port->serial->minor; | 831 | int port_number = port->number - port->serial->minor; |
| 832 | unsigned int mcr; | 832 | unsigned int mcr; |
| 833 | 833 | ||
| 834 | cflag = tty->termios->c_cflag; | 834 | cflag = tty->termios.c_cflag; |
| 835 | iflag = tty->termios->c_iflag; | 835 | iflag = tty->termios.c_iflag; |
| 836 | 836 | ||
| 837 | dbg("%s - cflag %08x, iflag %08x", __func__, cflag, iflag); | 837 | dbg("%s - cflag %08x, iflag %08x", __func__, cflag, iflag); |
| 838 | dbg("%s - old clfag %08x, old iflag %08x", __func__, | 838 | dbg("%s - old clfag %08x, old iflag %08x", __func__, |
| @@ -871,7 +871,7 @@ static void ti_set_termios(struct tty_struct *tty, | |||
| 871 | } | 871 | } |
| 872 | 872 | ||
| 873 | /* CMSPAR isn't supported by this driver */ | 873 | /* CMSPAR isn't supported by this driver */ |
| 874 | tty->termios->c_cflag &= ~CMSPAR; | 874 | tty->termios.c_cflag &= ~CMSPAR; |
| 875 | 875 | ||
| 876 | if (cflag & PARENB) { | 876 | if (cflag & PARENB) { |
| 877 | if (cflag & PARODD) { | 877 | if (cflag & PARODD) { |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 27483f91a4a3..aa4b0d775992 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
| @@ -207,7 +207,7 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty) | |||
| 207 | if (retval) | 207 | if (retval) |
| 208 | goto error_get_interface; | 208 | goto error_get_interface; |
| 209 | 209 | ||
| 210 | retval = tty_standard_install(driver, tty); | 210 | retval = tty_port_install(&port->port, driver, tty); |
| 211 | if (retval) | 211 | if (retval) |
| 212 | goto error_init_termios; | 212 | goto error_init_termios; |
| 213 | 213 | ||
| @@ -305,8 +305,7 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
| 305 | * Do the resource freeing and refcount dropping for the port. | 305 | * Do the resource freeing and refcount dropping for the port. |
| 306 | * Avoid freeing the console. | 306 | * Avoid freeing the console. |
| 307 | * | 307 | * |
| 308 | * Called asynchronously after the last tty kref is dropped, | 308 | * Called asynchronously after the last tty kref is dropped. |
| 309 | * and the tty layer has already done the tty_shutdown(tty); | ||
| 310 | */ | 309 | */ |
| 311 | static void serial_cleanup(struct tty_struct *tty) | 310 | static void serial_cleanup(struct tty_struct *tty) |
| 312 | { | 311 | { |
| @@ -423,7 +422,7 @@ static void serial_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
| 423 | if (port->serial->type->set_termios) | 422 | if (port->serial->type->set_termios) |
| 424 | port->serial->type->set_termios(tty, port, old); | 423 | port->serial->type->set_termios(tty, port, old); |
| 425 | else | 424 | else |
| 426 | tty_termios_copy_hw(tty->termios, old); | 425 | tty_termios_copy_hw(&tty->termios, old); |
| 427 | } | 426 | } |
| 428 | 427 | ||
| 429 | static int serial_break(struct tty_struct *tty, int break_state) | 428 | static int serial_break(struct tty_struct *tty, int break_state) |
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 6855d5ed0331..72b678d90831 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
| @@ -67,7 +67,7 @@ void usb_wwan_set_termios(struct tty_struct *tty, | |||
| 67 | struct usb_wwan_intf_private *intfdata = port->serial->private; | 67 | struct usb_wwan_intf_private *intfdata = port->serial->private; |
| 68 | 68 | ||
| 69 | /* Doesn't support option setting */ | 69 | /* Doesn't support option setting */ |
| 70 | tty_termios_copy_hw(tty->termios, old_termios); | 70 | tty_termios_copy_hw(&tty->termios, old_termios); |
| 71 | 71 | ||
| 72 | if (intfdata->send_setup) | 72 | if (intfdata->send_setup) |
| 73 | intfdata->send_setup(port); | 73 | intfdata->send_setup(port); |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 473635e7f5db..b36077de72b9 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
| @@ -724,7 +724,7 @@ static void firm_setup_port(struct tty_struct *tty) | |||
| 724 | { | 724 | { |
| 725 | struct usb_serial_port *port = tty->driver_data; | 725 | struct usb_serial_port *port = tty->driver_data; |
| 726 | struct whiteheat_port_settings port_settings; | 726 | struct whiteheat_port_settings port_settings; |
| 727 | unsigned int cflag = tty->termios->c_cflag; | 727 | unsigned int cflag = tty->termios.c_cflag; |
| 728 | 728 | ||
| 729 | port_settings.port = port->number + 1; | 729 | port_settings.port = port->number + 1; |
| 730 | 730 | ||
diff --git a/firmware/Makefile b/firmware/Makefile index 344713b11669..fdc9ff045ef8 100644 --- a/firmware/Makefile +++ b/firmware/Makefile | |||
| @@ -40,7 +40,6 @@ fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.2.1a.fw \ | |||
| 40 | bnx2/bnx2-mips-06-6.2.1.fw \ | 40 | bnx2/bnx2-mips-06-6.2.1.fw \ |
| 41 | bnx2/bnx2-rv2p-06-6.0.15.fw | 41 | bnx2/bnx2-rv2p-06-6.0.15.fw |
| 42 | fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin | 42 | fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin |
| 43 | fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin | ||
| 44 | fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \ | 43 | fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \ |
| 45 | cxgb3/t3c_psram-1.1.0.bin \ | 44 | cxgb3/t3c_psram-1.1.0.bin \ |
| 46 | cxgb3/t3fw-7.10.0.bin \ | 45 | cxgb3/t3fw-7.10.0.bin \ |
diff --git a/firmware/intelliport2.bin.ihex b/firmware/intelliport2.bin.ihex deleted file mode 100644 index e9cfe8cb2b21..000000000000 --- a/firmware/intelliport2.bin.ihex +++ /dev/null | |||
| @@ -1,2147 +0,0 @@ | |||
| 1 | :100000003C4237180201030000000000000000001D | ||
| 2 | :10001000576564204465632030312031323A3234F0 | ||
| 3 | :100020003A33302031393939000000000000000037 | ||
| 4 | :10003000E96C0F426547694E6E496E47206F462056 | ||
| 5 | :10004000634F6445CC135A15E8167618041A921BB0 | ||
| 6 | :10005000201DAE1E3C20CA215823E6247426022807 | ||
| 7 | :1000600090291E2BAC2C3A2EC82F5631E432723414 | ||
| 8 | :1000700000368E371C39AA3A383CC63D543FE24020 | ||
| 9 | :100080007042FE438C451A47A848364AC44B524D2D | ||
| 10 | :10009000E04E6E50FC518A531855A6563458C2593A | ||
| 11 | :1000A000505BDE5C6C5EFA5F88611663A464326646 | ||
| 12 | :1000B000C0674E69DC6A6A6CF86D866F1471A27253 | ||
| 13 | :1000C0003074BE754C776C778C77AC7733DB8ADC19 | ||
| 14 | :1000D0005333DB250700750A8A1E080183E30CEB06 | ||
| 15 | :1000E00020903C01750A8A1E080180E3C0EB129043 | ||
| 16 | :1000F0008A1E0D013C02750680E30CEB049080E340 | ||
| 17 | :10010000C053508B1EBA138EDBE86A65558BEC53D7 | ||
| 18 | :100110001E2BC08ED88B5E04C1E304035E06D1E3C0 | ||
| 19 | :100120002E8B9F44008D472A1E5A1F5B5DC3558B43 | ||
| 20 | :10013000EC531E2BC08ED88B5E04C1E304035E0615 | ||
| 21 | :10014000D1E32E8B9F44008D47341E5A1F5B5DC345 | ||
| 22 | :10015000FB558BEC53515256571E061E0733C08E6B | ||
| 23 | :10016000D88B5E04268A47592503008BF0D1E62EF2 | ||
| 24 | :100170008BB4C400C1E0042602471AD1E08BE82EFC | ||
| 25 | :100180008BAE4400892C268A471C88440F268A4758 | ||
| 26 | :100190001D884410268A471E884411268A471F88D6 | ||
| 27 | :1001A0004412268A4720884413268A472388441409 | ||
| 28 | :1001B000268A4724884415268A475A88440E33C025 | ||
| 29 | :1001C00089440689440888440B88440AB021B464F1 | ||
| 30 | :1001D000894404894402B05588440D88440CE86A77 | ||
| 31 | :1001E00000725BE8C900E8C110894408807C0F01F7 | ||
| 32 | :1001F0007429E82B02E87F02807C0F03741DE8A9B4 | ||
| 33 | :10020000108BF82B44083DA00F7210897C0833C076 | ||
| 34 | :1002100087440685C07504C6440AFF8A440A84C020 | ||
| 35 | :10022000750BB80800E86A4AE8A90173BFE84F01F6 | ||
| 36 | :100230008166487FFF83667ABFB002E8040E8A4475 | ||
| 37 | :100240000A98071F5F5E5A595B5DC3814E48800064 | ||
| 38 | :10025000B040E83D4AE88940732AE84D108BD8B099 | ||
| 39 | :1002600005E82E4AF6462702751AE83D102BC33DD5 | ||
| 40 | :10027000581B72EB8166487FFFB002E8C40DC6448C | ||
| 41 | :100280000A01F9C3834E7A40F8C3FBB001E8024A81 | ||
| 42 | :10029000FAE8991EE40A84C075F0B04EE60AFBB095 | ||
| 43 | :1002A00001E8EE49FAE8851EE40A84C075F0C3FA55 | ||
| 44 | :1002B000E87A1EE4EC884416E4E4884417E4F888FD | ||
| 45 | :1002C0004418E4F0884419E41088441AE41288447D | ||
| 46 | :1002D0001BE41488441CE43488441DE43688441E1E | ||
| 47 | :1002E000E4D824018AE0E4DA24020AC488441F8A9C | ||
| 48 | :1002F0004410E8CD1F8A4411E835218A4412E88968 | ||
| 49 | :10030000218A4413E84321C686A10000E414241086 | ||
| 50 | :10031000E614E412243DE6128A44153C01721E776D | ||
| 51 | :1003200016B011E634B013E636E4140C10E614E40B | ||
| 52 | :10033000120C40E612EB06E4120C02E6128A440F9D | ||
| 53 | :100340003C0174063C02740AEB0EE4120C08E6123F | ||
| 54 | :10035000EB06E4120C10E612E82FFF8A44143C026C | ||
| 55 | :100360007508B05588440C88440DB021B4648944A4 | ||
| 56 | :1003700004894402E40C0C10E60CE8ED39FBC3E8F8 | ||
| 57 | :100380005F3F7308FBB00AE80849EBF3FAE89D1DEC | ||
| 58 | :100390008A64168A441789869400E6E48AC4E6ECE7 | ||
| 59 | :1003A0008A64188A441989869600E6F08AC4E6F8B9 | ||
| 60 | :1003B0008A441AE6108A441BE6128A441CE6148A10 | ||
| 61 | :1003C000441DE6348A441EE6368A441FE6D8E6DA3F | ||
| 62 | :1003D000E9B7FE90FA8A440EE6FEE402A80175052C | ||
| 63 | :1003E00033C0FBF8C333C0E400FBF9C38A64148054 | ||
| 64 | :1003F000FC02742BFEC0FEC780FF4E721C74098085 | ||
| 65 | :10040000FF507308B00AEB17B00DEB1302DC32FF9C | ||
| 66 | :1004100080FB7F7C02B3218AC33C7F7C02B021C376 | ||
| 67 | :10042000FA807C0B047602FBC38B46243D080072E5 | ||
| 68 | :10043000F68E46028B7E228A440C8B5C02AAE8ABC5 | ||
| 69 | :10044000FFAAE8A7FFAAE8A3FFAAE89FFF88440C39 | ||
| 70 | :10045000895C0280440B04897E22836E24048346D7 | ||
| 71 | :100460001A04807E26027406806626FDFBC360B0F7 | ||
| 72 | :10047000FDE8023F61FBC3FA807C0F037509C644A7 | ||
| 73 | :100480000B00E8E538FBC3C47E148B4E3A85C97572 | ||
| 74 | :1004900035268B0D4747E3EA3B7E047622B80200FF | ||
| 75 | :1004A00039462E7707C7462E0000EB138B5E2C894A | ||
| 76 | :1004B0005E0426C70700004343895E2C29462E852B | ||
| 77 | :1004C000C978CE894E3A8A440D8B5C04268A25472A | ||
| 78 | :1004D0003AC47516FE4C0BFF4406E80FFFE2ED88A8 | ||
| 79 | :1004E000440D895C04894E3AEBA7C6440AFEE879BC | ||
| 80 | :1004F00038FBC390E8B30D8AE88A0ECB13B3078AA2 | ||
| 81 | :10050000C1EEEB00EC3AC1750902CDFECB75F0EB04 | ||
| 82 | :100510000C90880ECB138AE8BBFFFFF9C3880ECB83 | ||
| 83 | :1005200013F8C390BB3F3F8A8E9E00BAFE00EC8A50 | ||
| 84 | :10053000E832C122C37502F8C3F9C390E8E5FF733E | ||
| 85 | :1005400001C3BAD000BB03038A8E9F00EC8AE83255 | ||
| 86 | :10055000C122C37502F8C3F9C39033C08ED88EC0D0 | ||
| 87 | :10056000803EC813007507B00AE82647EBF2FB335C | ||
| 88 | :10057000DB8A1EC913434383FB7E760733DBB0025D | ||
| 89 | :10058000E80F472E8BAF4400837E080074E7881E77 | ||
| 90 | :10059000C913B002E8FB46FAF7463840007414E885 | ||
| 91 | :1005A000961BE87FFF721C33D28A969F0083C20E8F | ||
| 92 | :1005B000EB0C90E8771BE883FF7208BA4800E83339 | ||
| 93 | :1005C000FF73AB23CB898E9A0089969C00FE86B57B | ||
| 94 | :1005D00000C606C81300B00AE8670AFBEB891018CA | ||
| 95 | :1005E000082833C0A005018AC824407524C7067CAA | ||
| 96 | :1005F000128E45C70642120100C606541202B00808 | ||
| 97 | :10060000F6C1017402B004A34612A24C12A29412C5 | ||
| 98 | :10061000C3C7067C12B645A00F0184C0750E6A00E0 | ||
| 99 | :100620001FC60693121E9C0EE8B10C90C70644121A | ||
| 100 | :100630000100A342128BD8C1E304881E9412BEE2CB | ||
| 101 | :10064000052BF08BC833DB8BFB2EAC888548128AD8 | ||
| 102 | :10065000D80C05E6FE8AE0EB00E4FE32C4A83F7445 | ||
| 103 | :1006600003E99E00E400888550128AE02430BA1025 | ||
| 104 | :10067000FF3C30741280FC04740ABA0403F60608C6 | ||
| 105 | :1006800001FE7403BA080F88954C1202FA32C0F6C4 | ||
| 106 | :10069000C4087402B001888558128AC43C35745B62 | ||
| 107 | :1006A0003C3674573C3474533C04744F3C14744BC4 | ||
| 108 | :1006B0003C157447A8407425C685541204D1E7B48C | ||
| 109 | :1006C000038AC389855C128AC38AE380CC01898549 | ||
| 110 | :1006D0006412D1EF47E203EB1A90E96CFFC6855430 | ||
| 111 | :1006E0001202D1E78AE68AC30C0489855C12D1EF35 | ||
| 112 | :1006F00047E2E733C08AC7A34612C3C68554120631 | ||
| 113 | :10070000EBBBC68554120033C08885501288854CD7 | ||
| 114 | :100710001288855812EBA6C7462602128B461E8900 | ||
| 115 | :1007200046008946228B4620894624C7461A000087 | ||
| 116 | :10073000C3C7463C8000C7463801001E568B763042 | ||
| 117 | :100740008976048976148E5E0633C089044646890C | ||
| 118 | :10075000762C89463A8B4632484889462E5E1FC31E | ||
| 119 | :1007600033C089464889464AC74646AE0189464E47 | ||
| 120 | :100770008B46448946508B4642894640894608C389 | ||
| 121 | :1007800033C0894676894678C7467A1000561E8B54 | ||
| 122 | :10079000767089761089760C8E5E12C70400008B05 | ||
| 123 | :1007A00046728946741F5EC3895618895602895657 | ||
| 124 | :1007B0000689560A89560E8956128956168BD84BC9 | ||
| 125 | :1007C0004BC1E302BF0200897E1E03FB897E30031A | ||
| 126 | :1007D000FB897E4203FB897E7083EB08895E20895A | ||
| 127 | :1007E0005E32895E44895E7250E82BFFE871FFE853 | ||
| 128 | :1007F0003FFFE88BFF58C3B83075C1E8040E5B03B8 | ||
| 129 | :10080000C3A3BA13833E4212007407803E941200C1 | ||
| 130 | :10081000750E6A001FC60693121E9C0EE8BD0A9054 | ||
| 131 | :10082000B8307AC1E80440A3C0132B061201F7D8F0 | ||
| 132 | :1008300033D28BCA8A0E9412F7F13D8000770E6A8C | ||
| 133 | :10084000001FC6069312259C0EE8900A90483DFFB3 | ||
| 134 | :10085000077203B8FF07A3C21333C98A0E94123379 | ||
| 135 | :10086000F6B800092E8BAC440089464C404646E25F | ||
| 136 | :10087000F38A0E941233F68B16C013A1C2132E8B7B | ||
| 137 | :10088000AC4400E822FF03D04646E2F2C333C02E58 | ||
| 138 | :100890008BAD44008946084747E2F4C35133C00A90 | ||
| 139 | :1008A000C22E8BAD440089869E00814E38002047C1 | ||
| 140 | :1008B00047FEC480FC04720432E4FEC0E2E35983C4 | ||
| 141 | :1008C000E9107405F7D9E8C4FFC35133C00AC22E3A | ||
| 142 | :1008D0008BAD440089869E00834E3840474780C4D4 | ||
| 143 | :1008E00010790432E4FEC0E2E65983E9107405F79A | ||
| 144 | :1008F000D9E899FFC3E8D2FFC38D089C08CA08F560 | ||
| 145 | :10090000088B0E421233F6515633DB8BCB8A944858 | ||
| 146 | :10091000128A8C4C128A9C54128BFEC1E70585DB2F | ||
| 147 | :100920007502B1102EFF97F9085E5946E2D9C3014E | ||
| 148 | :10093000CC03D000E802D000E801D000E800D000ED | ||
| 149 | :10094000E804D0A8DA00DC00DE01D803CC03CC0335 | ||
| 150 | :10095000CC04D0A8DA20DC00DE03CC03CC03CC002E | ||
| 151 | :10096000D803CC03CC03CC03CC03CC03CC03CC0303 | ||
| 152 | :10097000CC03CC03CC03CC03CC03CC03CC03CC03FF | ||
| 153 | :10098000CC04D000DA20DC03DE01D803CC03CC0396 | ||
| 154 | :10099000CC03CC00D800CC00D0000056521E0E1F55 | ||
| 155 | :1009A000BE2F0933D2FCAD85C0740D8AD4EEAD855F | ||
| 156 | :1009B000C074058AD4EEEBEE1F5A5EC3E48084C097 | ||
| 157 | :1009C00074167814B027E6FCB011E634E4FC3C273A | ||
| 158 | :1009D0007506E4117502F8C3F9C383C206B0BFEE11 | ||
| 159 | :1009E00083EA02B010EE8886AF00B01183C204EE35 | ||
| 160 | :1009F00083C202EEB01383C202EE83C202EE2EA1C6 | ||
| 161 | :100A00004C2D8986940083EA0EEE83C2028AC4EEDE | ||
| 162 | :100A100083C204B003EE8886A80083EA0432C0EEE5 | ||
| 163 | :100A200083C202B089EE8886A6000C06EEB040B400 | ||
| 164 | :100A30003889461CC74636380083C20432C0EE8867 | ||
| 165 | :100A400086A700C383C206B0BFEE83EA02EC3A86F3 | ||
| 166 | :100A5000AF00752483C204EC3C11751C83C206EC04 | ||
| 167 | :100A60003C13751483EA088A86A800EE83EA02EC38 | ||
| 168 | :100A700024C03CC07502F8C3F9C333C98BD18BF1D4 | ||
| 169 | :100A80008A0E9412C1E9022E8BAC4400F74638005E | ||
| 170 | :100A900020740E8A869E00E6FE32C0E68042E8FAA6 | ||
| 171 | :100AA000FE83C608E2E185D27403E80508C333C9B2 | ||
| 172 | :100AB0008BF18A0E94122E8BAC4400F7463840001E | ||
| 173 | :100AC0007406E87316E812FF4646E2EAC333C98BA0 | ||
| 174 | :100AD000F18A0E9412C1E9022E8BAC4400F746381D | ||
| 175 | :100AE00000207416E84616E8D2FE730E6A001FC690 | ||
| 176 | :100AF0000693121C9C0EE8E3079083C608E2D9C354 | ||
| 177 | :100B000033C98BF18A0E94122E8BAC4400F7463811 | ||
| 178 | :100B100040007416E82116E82AFF730E6A001FC60B | ||
| 179 | :100B20000693121C9C0EE8B307904646E2DAC30C0B | ||
| 180 | :100B300000001000131200001400283C001B3E00AF | ||
| 181 | :100B4000002A00002C0000420014D80000DA000047 | ||
| 182 | :100B50003400113600133800113A001300005650CB | ||
| 183 | :100B600052BE2F0B2EAD85C07406922EACEEEBF468 | ||
| 184 | :100B70005A585EC3532EA16022E6E4E6F08AC4E62A | ||
| 185 | :100B8000ECE6F8E8D8FFB04BE610B050E612B0380B | ||
| 186 | :100B9000E614E8AE15B046E60AE8A715B01AE60A6C | ||
| 187 | :100BA000E8A015B022E60AE89915E8FD068BD8E41E | ||
| 188 | :100BB00016A8047518E8F2062BC33D320072F06ADD | ||
| 189 | :100BC000001FC6069312239C0EE8100790E8DA0671 | ||
| 190 | :100BD0002BC33D2400771BB031E6FC565155B910AC | ||
| 191 | :100BE000002E8BAC4400814E3880004646E2F25D18 | ||
| 192 | :100BF000595EE869FFE84B15B046E60AE844155B24 | ||
| 193 | :100C0000C333F68B0E42122E8BAC4400F7463800ED | ||
| 194 | :100C1000207406E81715E85BFF83C620E2E9C38B62 | ||
| 195 | :100C2000C20504008946282EA14C2D89868E008994 | ||
| 196 | :100C300086900089869200C686A3000AC686C300F5 | ||
| 197 | :100C4000035283C2048A86A6000C06EE5A83C202AF | ||
| 198 | :100C5000B005EE8886A500C3E803FFE8E514B042BE | ||
| 199 | :100C6000E60AF74638800074062EA19C22EB042E7B | ||
| 200 | :100C7000A16C22C7461C0C008986940089869600C8 | ||
| 201 | :100C800089868E008986900089869200E6F0E6E4E7 | ||
| 202 | :100C90008AC4E6F8E6ECC686C30003E8A514B01AD9 | ||
| 203 | :100CA000E60AB0108886A500E60CC333C98BF18A2A | ||
| 204 | :100CB0000E94122E8BAC4400F7463840007406E8C0 | ||
| 205 | :100CC0007614E85AFF4646E2EAC333C98BF18A0E2E | ||
| 206 | :100CD00094122E8BAC4400F7463800207406E84C82 | ||
| 207 | :100CE00014E874FF4646E2EAC390833E441200755E | ||
| 208 | :100CF00014B001BA0601EE2AC0EEB002EEB004EE66 | ||
| 209 | :100D0000B80002EB0FBA0601B040EEB801008A0E3F | ||
| 210 | :100D10000E01D3E0A38812C3A18812A384122D2050 | ||
| 211 | :100D200000A38A122D2000A38212C706861220007B | ||
| 212 | :100D3000C70680123200C3833E44120074768B0EC5 | ||
| 213 | :100D4000421233F68AA4541284E4745F8A844812EF | ||
| 214 | :100D50000C04E6FEF6C4047425B01BBA0000EEEBEA | ||
| 215 | :100D6000002AC0BA0200EEEB00B003EEEB0032C086 | ||
| 216 | :100D7000BA0200EEEB00BA0000B000EEEB2DB01F9F | ||
| 217 | :100D8000BA0000EEEB002AC0BA0200EEEB00B0039E | ||
| 218 | :100D9000EEEB00D1E68A845D12D1EEF6D0BA020005 | ||
| 219 | :100DA000EEEB00BA0000B00AEEEB00E404EB00E466 | ||
| 220 | :100DB0000446E290C390B81400BA3EFFEFB80600B4 | ||
| 221 | :100DC000BA32FFEFB80F00BA34FFEFBA36FFEF8345 | ||
| 222 | :100DD0003E4412007516B81100BA38FFEFB8120081 | ||
| 223 | :100DE000BA3AFFEFB81B00BA3CFFEFC3B81100BA24 | ||
| 224 | :100DF00038FFEFB81200BA3AFFEFB81B00BA3CFF59 | ||
| 225 | :100E0000EFC3B8FC00BA28FFEFFB833E4412007426 | ||
| 226 | :100E100007B8CC00BA28FFEFC300FFFF202428FF4B | ||
| 227 | :100E20002CFFFF303438FFFF3C903C0F770EBB198E | ||
| 228 | :100E30000E2ED73CFF74058AD8F8C3902ADBF9C37D | ||
| 229 | :100E4000833E4412007427A00601802606013080EC | ||
| 230 | :100E50003E0601307518B90200BFC413BA0601EC92 | ||
| 231 | :100E6000A82075F8BA0401EDABE2F1EB1690B904D5 | ||
| 232 | :100E700000BFC413BA0601ECA82075F8BA0401EC4F | ||
| 233 | :100E8000AAE2F1FA90BEC413AD80E43F80FC027484 | ||
| 234 | :100E90000E6A001FC60693120A9C0EE83E0490AD2F | ||
| 235 | :100EA0003C0F75ED8AC4E881FF72E6881E1A01C600 | ||
| 236 | :100EB000068E1200B0000A061A01BA0001EEC6063C | ||
| 237 | :100EC0008F1240833E4412007506B80C00EB04906C | ||
| 238 | :100ED000B84C00BA28FFEFC3833E4412007501C32B | ||
| 239 | :100EE000A150120B0652120AC4A80874F2A00F01F6 | ||
| 240 | :100EF0002AE450FF36BA131FE8505683C4026A0032 | ||
| 241 | :100F00001F33C0A3BC13A00F01A3BE138B1EBC13C1 | ||
| 242 | :100F10008A875012F687501208740D24078AE0BEA3 | ||
| 243 | :100F2000CC00A0BC13E8943DFF06BC13FF0EBE131B | ||
| 244 | :100F300075DAC3901E33C08ED8B001E8543D1FC38C | ||
| 245 | :100F400033C98BF18A0E94122E8BAC4400C74662D3 | ||
| 246 | :100F50003844C7467CFC3BC7467EE23BC7868000E0 | ||
| 247 | :100F6000EC3CE8AB16C686C00011837E080074070F | ||
| 248 | :100F70005156E833335E594646E2CDC333C98BF14F | ||
| 249 | :100F80008BF98A0E9412C1E902E3132E8BAC440054 | ||
| 250 | :100F90008A869E0088856C1283C60847E2EDC3FAF4 | ||
| 251 | :100FA000FCB0C0BA0001EE33C08ED88EC08ED0BF68 | ||
| 252 | :100FB0001601B9CC772BCFD1E9F3ABBC4012E8D9FD | ||
| 253 | :100FC00002E8703CBECC0FE8F23CF49033C08ED8FF | ||
| 254 | :100FD0008EC08ED0F6060A0180740BBE3555E8DB54 | ||
| 255 | :100FE0003CB001E8AC3CE8B300E8F6F5E808F8E806 | ||
| 256 | :100FF0000FF9E885FAE8B6FAE8EFFCE8C210E80372 | ||
| 257 | :101000003CE8B2FDE830FDE85402C6068F12C0E8A5 | ||
| 258 | :10101000BBFAE8EBFAE8E9FBE8AFFCE88DFCE81F77 | ||
| 259 | :10102000FFE858FFE8DBFDE816FE33C0BE5A05E8CE | ||
| 260 | :101030008A3CE8A3FEE8E0FCFBBEA444E87D3CE972 | ||
| 261 | :10104000CA2D56988BF08B425285C07527C74252E5 | ||
| 262 | :10105000010053368B9C2C01F6C301750C36896850 | ||
| 263 | :10106000523689AC2C015B5EC33689AC2C013689C3 | ||
| 264 | :10107000AC1C015B5EC356988BF033ED368B841C41 | ||
| 265 | :1010800001A80175158BE833C08742523689841C4C | ||
| 266 | :1010900001A80174053689842C015EC3565133F6CC | ||
| 267 | :1010A000B80100B9080089841C0189842C014646D6 | ||
| 268 | :1010B000E2F4595EC390BB01008BE8FF4E6E740AE8 | ||
| 269 | :1010C0008BDD8B4658A80174F0C38B4648A90800F5 | ||
| 270 | :1010D0007445F7463840007427E85C1080C2068AE1 | ||
| 271 | :1010E00086A80024BF8886A800EE60B0FEE886329D | ||
| 272 | :1010F00061B002E84CFF8B464824F7894648EB175D | ||
| 273 | :10110000E82A10814E2600408A86A5000C028886B7 | ||
| 274 | :10111000A500E60C8B4648A904007414B002E8212F | ||
| 275 | :10112000FF8B464824FB89464860B0DFE8473261C0 | ||
| 276 | :1011300033C0874658F6C301750B36894758A80156 | ||
| 277 | :10114000750DE974FFA32201A8017503E96AFF89FF | ||
| 278 | :101150001E3201C3BB01008BE8F74638400074150E | ||
| 279 | :10116000E8D50F80C20AECA840750A8BDD8B465685 | ||
| 280 | :10117000A80174E3C38B462680E4FE80CC02894636 | ||
| 281 | :1011800026B002E8BCFE33C0874656F6C301750A96 | ||
| 282 | :1011900036894756A801750BEBBDA32001A8017540 | ||
| 283 | :1011A00002EBB4891E3001C3601E062BC08ED8A08E | ||
| 284 | :1011B000901284C07549A12201A8017503E8F6FECA | ||
| 285 | :1011C000A12001A8017503E88AFFA1AC13487805A6 | ||
| 286 | :1011D0007445A3AC13A1AE134878057451A3AE13A4 | ||
| 287 | :1011E000A1B0134878057463A3B013A17E124078B0 | ||
| 288 | :1011F00003A37E12B80080BA22FFEF071F61CFA0C1 | ||
| 289 | :101200009112403C02720B33C0A29112FF167C1265 | ||
| 290 | :10121000EBA4A29112EB9FA08E1232068F12A28E27 | ||
| 291 | :10122000120A061A01BA0001EEB82C01EBA4833EA3 | ||
| 292 | :101230008412107211BA28FFED0C81EFE85337BA0F | ||
| 293 | :1012400028FFED247EEFB80400EB92C6068D120154 | ||
| 294 | :10125000E83F37C6068D1200A1B213EB8B908A1EB1 | ||
| 295 | :101260000B012AFF6BC319BA62FFEFB80A00BA601C | ||
| 296 | :10127000FFEFB801E0BA66FFEFB8FFFFBA52FFEF29 | ||
| 297 | :10128000B809C0BA56FFEFC706AC132C01C706AEAB | ||
| 298 | :10129000130400C606911200C3908A1E0B012AFF98 | ||
| 299 | :1012A0006BC305D1E8A31801C39052BA50FFED5AA1 | ||
| 300 | :1012B000C39053518B1E1801B9320590E2FE4B7555 | ||
| 301 | :1012C000F7595BC3B080BA00010A061A01EEC39059 | ||
| 302 | :1012D000B040EBF2B0C0EBEEB000EBEAFA60061EF5 | ||
| 303 | :1012E000162BDB8EDB2EA1BA4C2EA3924CA09312B0 | ||
| 304 | :1012F000988BE889262D7A803ECA13007403E96B27 | ||
| 305 | :1013000042E8C0FFE8ABFFE8A8FFB020C606901295 | ||
| 306 | :1013100000FF167C128BFD83FF0A7211E8B9FFE80B | ||
| 307 | :1013200090FFE8ABFFE88AFF83EF0AEBEA0BFF745C | ||
| 308 | :101330000FE8A4FFE87BFFE89AFFE875FF4F75F11F | ||
| 309 | :10134000E895FFE86CFFEBB98A86A50024FDEE88DE | ||
| 310 | :1013500086A500C38A86A6000C02EEC38B7638F7FA | ||
| 311 | :10136000C6010074EF8B4E368B462E3BC173028B49 | ||
| 312 | :10137000C82BC189462E014E34C47E0426010D8B34 | ||
| 313 | :101380007E2C83EA04F36C8EC1897E2C3B463C7232 | ||
| 314 | :1013900012F7C62000750B83CE20897638B000E89E | ||
| 315 | :1013A000A0FCC3F7C60400741B8BD883CE108976CB | ||
| 316 | :1013B000388A86A70024FE8886A70083C208EE83A9 | ||
| 317 | :1013C000EA088BC33D40007201C3814E380004839C | ||
| 318 | :1013D000C2028A86A50024FA8886A500EEC38A8602 | ||
| 319 | :1013E000A6000C02EEC3F74638010074F18B4E2EB6 | ||
| 320 | :1013F00032DB8ABEA30083C206C476048B7E2C83B4 | ||
| 321 | :10140000F908722CECA80174168AE083EA0AEC83CE | ||
| 322 | :10141000C20A84E77551AAFEC34983F90873E5320D | ||
| 323 | :10142000FF26011C015E34897604894E2E897E2CAC | ||
| 324 | :101430003B4E3C7211F64638207401C3834E38206F | ||
| 325 | :10144000B000E8FDFBC3F64638047415834E38102F | ||
| 326 | :101450008A86A70024FE8886A70083EA02EE83C25C | ||
| 327 | :10146000023D4000725DC332FF26031C85DB740918 | ||
| 328 | :1014700026891C8BF74747494980E41E80CCC0264B | ||
| 329 | :101480008904F6C41074278B7638F7C60010740BE5 | ||
| 330 | :1014900050FE86B200B00AE8A8FB58F7C6000174F7 | ||
| 331 | :1014A0000DE882268B76388B4E2E8B7E04AB8BF725 | ||
| 332 | :1014B00033C0AB32DB8ABEA300494983F9087217F7 | ||
| 333 | :1014C000E941FF814E38000483C2F88A86A50024D2 | ||
| 334 | :1014D000FA8886A500EEC3E945FF83C208EC88863A | ||
| 335 | :1014E000AA00C0E8048AE08AC88686A90032E08B98 | ||
| 336 | :1014F0005E3E84E3744F8AC18B4E26F6C504740C9D | ||
| 337 | :10150000A808740580E1BFEB0380C940F6C50874E4 | ||
| 338 | :101510000CA802740580E17FEB0380C980884E2609 | ||
| 339 | :101520008BF08A86A50084C97408A802741524FD6E | ||
| 340 | :10153000EB06A802750D0C028886A50083EA0AEE68 | ||
| 341 | :1015400083C20A8BC684E77501C3C686BA0001B0A0 | ||
| 342 | :101550000EE8EEFAF74638000274EE837E2E06722D | ||
| 343 | :10156000E88AA6AA00C45E048B7E2CB0FFAAB00253 | ||
| 344 | :10157000AB26830703836E2E03897E2CF646382024 | ||
| 345 | :101580007401C3834E3820B000E8B6FAC39083EAF2 | ||
| 346 | :1015900008E9B4FD83C2068B5E26F6C3C075EF8BE7 | ||
| 347 | :1015A0004E1CEC8886A40083EA0AA82075028ACD26 | ||
| 348 | :1015B00032ED8B461A3BC87318014E2A2BC189465F | ||
| 349 | :1015C0001AC57600F36E8ED98976003D2000723000 | ||
| 350 | :1015D000C385C074318BC801462AC57600F36E8E70 | ||
| 351 | :1015E000D980CB02895E26E832F1F6C701751683F1 | ||
| 352 | :1015F000C202E853FDF6C710750BB002E843FAC308 | ||
| 353 | :10160000F6C70174F0C380CB02895E26F6C7017469 | ||
| 354 | :10161000DE83C202E831FDF686A40040740B80E749 | ||
| 355 | :10162000FE80CF02895E26EBCCB004E814FAC3C07A | ||
| 356 | :10163000C2C8CAC4C6CCCED0D2D8DAD4D6DCDE90EA | ||
| 357 | :10164000E90E01E4C48AE0E4C48BD083F90872F0A7 | ||
| 358 | :1016500026833F0074048BDF49498BFB8ADE83E3DA | ||
| 359 | :101660000F2E8AA72F16ABF6C4107424F7C60010ED | ||
| 360 | :10167000740B50FE86B200B00AE8C6F958F7C600EF | ||
| 361 | :1016800001740DE8A0248B76388B4E2E8B7E04AB34 | ||
| 362 | :10169000897E0433C0AB4949894E2E897E2C8BC18B | ||
| 363 | :1016A000EB4E90EB9E90E4D684C07963E6D08AC876 | ||
| 364 | :1016B00025030003D8D1E32E8BAF4400888EAE0003 | ||
| 365 | :1016C0008B4E2EC45E048B7E2C8B7638E4862407EA | ||
| 366 | :1016D0003C0375CFE41C913BC173028BC82BC189BD | ||
| 367 | :1016E000462E014E3426010FBAC400F36C897E2CBD | ||
| 368 | :1016F0003B463C721CF7C62000750B83CE208976D2 | ||
| 369 | :1017000038B000E83CF98A86AE00243FE6D6C3F93B | ||
| 370 | :10171000C3F7C60A007435F7C61000752F83CE10C4 | ||
| 371 | :10172000897638F7C60200740E50E4D824FEE6D855 | ||
| 372 | :1017300058F7C6080074155051B9E803E40A84C08C | ||
| 373 | :10174000E0FA84C07504B024E60A59583D4000739D | ||
| 374 | :10175000B58A86A50024EF8886A500E60C81CE1008 | ||
| 375 | :1017600004897638EBA00008040C0109050D020A73 | ||
| 376 | :10177000060E030B070F004080C02060A0E0105051 | ||
| 377 | :1017800090D03070B0F0E4D2E6D08AC825030003D0 | ||
| 378 | :10179000D8D1E32E8BAF4400888EAE00E4D8C0E8E9 | ||
| 379 | :1017A000048BD82E8A8766178AE08AC88686A900A5 | ||
| 380 | :1017B00032E0E4988B5E3E84E374548AC18B4E26FB | ||
| 381 | :1017C000F6C504740CA808740580E1BFEB0380C95A | ||
| 382 | :1017D00040F6C508740CA802740580E17FEB038015 | ||
| 383 | :1017E000C980884E268BF08A86A500F6C1FD740854 | ||
| 384 | :1017F000A806741924F9EB0FA8067511F6C5017532 | ||
| 385 | :10180000040C04EB020C028886A500E60C8BC6844F | ||
| 386 | :10181000E775098A86AE00243FE6D2C3C686BA00C1 | ||
| 387 | :1018200001B00EE81CF8F74638000274E6837E2EFD | ||
| 388 | :101830000672E08A86A9008AE08686AA008AC832F3 | ||
| 389 | :10184000C480C90B22C1C0E4040AE0C45E048B7EDC | ||
| 390 | :101850002CB0FFAAB002AB26830703836E2E038948 | ||
| 391 | :101860007E2CF646382075AB834E3820B000E8D188 | ||
| 392 | :10187000F7EBA090E41224DFE61281E3FE9F895E7D | ||
| 393 | :1018800026836648F7EB7390F6C72075E7E4120CE1 | ||
| 394 | :1018900020E61232C0E6C6B083E6C680CF20895E5D | ||
| 395 | :1018A000268A86A5000C028886A500E60CEB7490BB | ||
| 396 | :1018B000F6C74075D3E4120C20E61232C0E6C6B07B | ||
| 397 | :1018C00081E6C680E7DF80CB01895E26B006E8713D | ||
| 398 | :1018D000F7908A86A50024F9E60C8886A500EB43DC | ||
| 399 | :1018E000E4D4E6D08BF825030003D8D1E32E8BAFE8 | ||
| 400 | :1018F00044008B5E26F6C76075B6F6C3C075D3BAD2 | ||
| 401 | :10190000C6008B4E1C8B461A3BC8731E014E2A2BF9 | ||
| 402 | :10191000C189461AC57600F36E8ED98976003D20BE | ||
| 403 | :1019200000723D8BC7243FE6D4C385C074398BC891 | ||
| 404 | :1019300001462AC57600F36E8ED983CB02895E26D6 | ||
| 405 | :10194000E8D9EDF6C70175398A86A50024F9E60CB9 | ||
| 406 | :101950008886A500F6C71075CAB002E8E4F6EBC3A6 | ||
| 407 | :10196000F6C70174EFEBBCF6C70174DC8A86A500EC | ||
| 408 | :10197000A802741181E3FFFE81CB0002895E26EB91 | ||
| 409 | :10198000C78A86A50024FB0C02E60C8886A500EB1E | ||
| 410 | :101990009290FDF7DF7FFEFBEFBF0004000405041B | ||
| 411 | :1019A00005040104000405040504060406040504F6 | ||
| 412 | :1019B00005040604060405040504020400040504E5 | ||
| 413 | :1019C00005040104000405040504060406040504D6 | ||
| 414 | :1019D00005040604060405040504070407040504B9 | ||
| 415 | :1019E00005040704070405040504060406040504A9 | ||
| 416 | :1019F0000504060406040504050407040704050499 | ||
| 417 | :101A00000504070407040504050406040604050488 | ||
| 418 | :101A10000504060406040504050403040004050483 | ||
| 419 | :101A20000504010400040504050406040604050475 | ||
| 420 | :101A30000504060406040504050402040004050464 | ||
| 421 | :101A40000504010400040504050406040604050455 | ||
| 422 | :101A50000504060406040504050407040704050438 | ||
| 423 | :101A60000504070407040504050406040604050428 | ||
| 424 | :101A70000504060406040504050407040704050418 | ||
| 425 | :101A80000504070407040504050406040604050408 | ||
| 426 | :101A90000504060406040504050433DB8AD88A8796 | ||
| 427 | :101AA0006C12E6FEC1E302E4CEA8047509A8027434 | ||
| 428 | :101AB00003E92CFEF9C35053E8CBFC5B58A8027431 | ||
| 429 | :101AC00003E91CFEF8C333DB8AD88A876C12E6FE72 | ||
| 430 | :101AD000C1E302E9D0FB9A1AC61A00000200040012 | ||
| 431 | :101AE00002000600020004000200080002000400D8 | ||
| 432 | :101AF000020006000200040002000A0002000400C6 | ||
| 433 | :101B000002000600020004000200080002000400B7 | ||
| 434 | :101B1000020006000200040002000C0002000400A3 | ||
| 435 | :101B20000200060002000400020008000200040097 | ||
| 436 | :101B3000020006000200040002000A000200040085 | ||
| 437 | :101B40000200060002000400020008000200040077 | ||
| 438 | :101B5000020006000200040002000E000200040061 | ||
| 439 | :101B60000200060002000400020008000200040057 | ||
| 440 | :101B7000020006000200040002000A000200040045 | ||
| 441 | :101B80000200060002000400020008000200040037 | ||
| 442 | :101B9000020006000200040002000C000200040023 | ||
| 443 | :101BA0000200060002000400020008000200040017 | ||
| 444 | :101BB000020006000200040002000A000200040005 | ||
| 445 | :101BC00002000600020004000200080002000400F7 | ||
| 446 | :101BD00002000600020004000200C390DA1494150B | ||
| 447 | :101BE0005C13E613DA1BDA1BE613DA1B8B94641220 | ||
| 448 | :101BF000C1E604A80174355033C08AC2E6FEE4A0F1 | ||
| 449 | :101C000085C074278BD82E8A9FDA1A52562E8BA83D | ||
| 450 | :101C100044008B5628ECA801750D8886AD00240E73 | ||
| 451 | :101C20008AD82EFF97DC1B5E5AEBCD58A80274367B | ||
| 452 | :101C300083C61033C08AC6E6FEE4A085C074278B35 | ||
| 453 | :101C4000D82E8A9FDA1A52562E8BA844008B56281B | ||
| 454 | :101C5000ECA801750D8886AD00240E8AD82EFF975A | ||
| 455 | :101C6000DC1B5E5AEBCDC39032E48BD88BD02E8A2E | ||
| 456 | :101C70009F9A192E2297921956528AC3240303C69B | ||
| 457 | :101C800080E304D0EB2EFF97D61A585EA955007555 | ||
| 458 | :101C9000D9C3601E062BC08ED8A15C12E6FEE400FC | ||
| 459 | :101CA00022C4740833F6E8BFFFEBEE90E40407E4C7 | ||
| 460 | :101CB000041FB80080BA22FFEF61CF90601E062B90 | ||
| 461 | :101CC000C08ED8A15E12E6FEE40022C47408BE04F1 | ||
| 462 | :101CD00000E894FFEBEDE40407E4041FB80080BAC9 | ||
| 463 | :101CE00022FFEF61CF90601E062BC08ED8A15C1240 | ||
| 464 | :101CF000E6FEE40022C4741833F6E86BFFA160121C | ||
| 465 | :101D0000E6FEE40022C474E5BE0800E85AFFEBDDFD | ||
| 466 | :101D1000A16012E6FEE40022C475EDE40407E404C9 | ||
| 467 | :101D2000A15C12E6FEE4041FE404B80080BA22FFBE | ||
| 468 | :101D3000EF61CF90601E062BC08ED8A15E12E6FE2A | ||
| 469 | :101D4000E40022C47419BE0400E81CFFA16212E67C | ||
| 470 | :101D5000FEE40022C474E4BE0C00E80BFFEBDCA13F | ||
| 471 | :101D60006212E6FEE40022C475EDE40407E404A177 | ||
| 472 | :101D70005E12E6FEE4041FE404B80080BA22FFEF1E | ||
| 473 | :101D800061CF601E062BC08ED8A15C12E6FEE480F7 | ||
| 474 | :101D900084C4740833F6E853FEEBEE90B80080BAC2 | ||
| 475 | :101DA00022FFEF071F61CF90601E062BC08ED8A1C7 | ||
| 476 | :101DB0005E12E6FEE48084C47408BE0200E82CFED5 | ||
| 477 | :101DC000EBEDB80080BA22FFEF071F61CF90601ED5 | ||
| 478 | :101DD000062BC08ED8A16012E6FEE48084C474088D | ||
| 479 | :101DE000BE0400E806FEEBEDB80080BA22FFEF0764 | ||
| 480 | :101DF0001F61CF90601E062BC08ED8A16212E6FE36 | ||
| 481 | :101E0000E48084C47408BE0600E8E0FDEBEDB80091 | ||
| 482 | :101E100080BA22FFEF071F61CF90601E062BC08E95 | ||
| 483 | :101E2000D8A15C12E6FEE40022C4741833F6E83749 | ||
| 484 | :101E3000FEA16012E6FEE48084C474E5BE0400E8FE | ||
| 485 | :101E4000AAFDEBDDA16012E6FEE48084C475EDA17D | ||
| 486 | :101E50005C12E6FEE40407E4041FB80080BA22FF27 | ||
| 487 | :101E6000EF61CF90601E062BC08ED8A15E12E6FEF9 | ||
| 488 | :101E7000E40022C47419BE0400E8ECFDA16212E67D | ||
| 489 | :101E8000FEE48084C474E4BE0600E85FFDEBDCA1E0 | ||
| 490 | :101E90006212E6FEE48084C475EDA15E12E6FEE403 | ||
| 491 | :101EA0000407E4041FB80080BA22FFEF61CF601E70 | ||
| 492 | :101EB000062BC08ED8A15C12E6FEE48084C47418A0 | ||
| 493 | :101EC00033F6E827FDA16012E6FEE40022C474E5C3 | ||
| 494 | :101ED000BE0800E892FDEBDDA16012E6FEE4002200 | ||
| 495 | :101EE000C475EDE40407E4041FB80080BA22FFEFD4 | ||
| 496 | :101EF00061CF601E062BC08ED8A15E12E6FEE48084 | ||
| 497 | :101F000084C47419BE0200E8E2FCA16212E6FEE499 | ||
| 498 | :101F10000022C474E4BE0C00E84DFDEBDCA16212AB | ||
| 499 | :101F2000E6FEE40022C475EDE40407E4041FB800F3 | ||
| 500 | :101F300080BA22FFEF61CF90601E062BC08ED8A121 | ||
| 501 | :101F40005C12E6FEE48084C4741833F6E89DFCA1BC | ||
| 502 | :101F50006012E6FEE48084C474E5BE0400E88CFCF4 | ||
| 503 | :101F6000EBDDA16012E6FEE48084C475ED071FB8C6 | ||
| 504 | :101F70000080BA22FFEF61CF601E062BC08ED8A171 | ||
| 505 | :101F80005E12E6FEE48084C47419BE0200E85CFCC4 | ||
| 506 | :101F9000A16212E6FEE48084C474E4BE0600E84B4D | ||
| 507 | :101FA000FCEBDCA16212E6FEE48084C475ED071F41 | ||
| 508 | :101FB000B80080BA22FFEF61CF90601E062BC08E62 | ||
| 509 | :101FC000D8902AC0E6FEE4CEA801741433DBE8D52D | ||
| 510 | :101FD000F6EBEF90B80080BA22FFEF071F61CF90B9 | ||
| 511 | :101FE000F60605010175EDB001E6FEE4CEA8017428 | ||
| 512 | :101FF000E3BB0400E8AFF6EBC990601E062BC08E71 | ||
| 513 | :10200000D890FB90FA2AC0E6FEE4CEA802741333FF | ||
| 514 | :10201000DBE8CCF8EBECB80080BA22FFEF071F61D9 | ||
| 515 | :10202000CF90A80474F033DBE85BF7EBD590601E2B | ||
| 516 | :10203000062BC08ED890FB90FAB001E6FEE4CEA845 | ||
| 517 | :10204000027415BB0400E897F8EBEB90B80080BA77 | ||
| 518 | :1020500022FFEF071F61CF90A80474F0BB0400E8D3 | ||
| 519 | :1020600024F7EBD26A001FC6069312099C0EE86B98 | ||
| 520 | :10207000F2906A001FC6069312299C0EE85DF2904A | ||
| 521 | :10208000722072207220CE1D921CE61C1A1E722035 | ||
| 522 | :10209000821DAE1E381F7220821D72207220381FD2 | ||
| 523 | :1020A000722072207220F41DBC1C341D641E72202C | ||
| 524 | :1020B000A81DF21E781F7220A81D72207220781FA2 | ||
| 525 | :1020C000FCB940008CCBB864202BFFAB93AB93E200 | ||
| 526 | :1020D000FAC7064C00A811833E4412007520C706BB | ||
| 527 | :1020E0003C00084BC7063000BA1FC7063400FA1F71 | ||
| 528 | :1020F000F6060501017506C70638002E20C3C7067F | ||
| 529 | :102100003C00564B33DB8A1E5412C1E302021E56BA | ||
| 530 | :10211000122E8B878020A330008A1E5512C1E30245 | ||
| 531 | :10212000021E57122E8B87A020A33400C38B869EDD | ||
| 532 | :1021300000E6FE86C4E6D0C38B869E00E6FE33D260 | ||
| 533 | :102140008AD4C351B91027E40A909084C07405E280 | ||
| 534 | :10215000F659F9C359F8C384C0781E518AE88AC871 | ||
| 535 | :10216000B80100D3E0098698003AAEA00059751076 | ||
| 536 | :10217000E8A9E5834E2602F9C39889869800EBF01A | ||
| 537 | :10218000F8C384C07812518AE08AC8B80100D3E04D | ||
| 538 | :1021900059F7D021869800C3C78698000000C383F2 | ||
| 539 | :1021A000C2048A86A6000C04EE83EA04C3E893FF07 | ||
| 540 | :1021B0007204B082E60AC38B4626A8FD74118A8693 | ||
| 541 | :1021C000A500A806740824F98886A500E60CC3F6C5 | ||
| 542 | :1021D000C401740A8A86A50024FB0C02EB0CA80239 | ||
| 543 | :1021E000750F8A86A50024FD0C043A86A50075D8D3 | ||
| 544 | :1021F000C38A86A500EBCFE4D833DB8AD8C0EB04D2 | ||
| 545 | :102200002E8A9F6617889EA9008B5E2680E33FF684 | ||
| 546 | :10221000C7047407A810750380CB40F6C70874077D | ||
| 547 | :10222000A880750380CB40885E268A86A500F6C309 | ||
| 548 | :10223000FD740DA806740824F98886A500E60CC371 | ||
| 549 | :10224000F6C70174040C02EBF0F6C30275E90C0446 | ||
| 550 | :10225000EBE7C404C4048504590448044104C303DF | ||
| 551 | :10226000820341038202570241028201410182003E | ||
| 552 | :1022700041004E02AD0157012D002B002700210027 | ||
| 553 | :102280001600F404F404A3046F045B045104F40383 | ||
| 554 | :10229000A3035103A3026D025102A3015101A30044 | ||
| 555 | :1022A00051006202D9016D01380036003100290069 | ||
| 556 | :1022B0001B005157BF0200EB0F905156BF0100EBBE | ||
| 557 | :1022C00007905156BF0300903C197602B017988BC7 | ||
| 558 | :1022D000F08A82C4002AE48BF083FE187346D1E6AC | ||
| 559 | :1022E0002E8B8C5222F74638800074052E8B8C8200 | ||
| 560 | :1022F00022F7C7020074123B8E9400740C898E94EE | ||
| 561 | :10230000008AC5E6EC8AC1E6E4F7C7010074123B17 | ||
| 562 | :102310008E9600740C898E96008AC5E6F88AC1E60E | ||
| 563 | :10232000F05E59C377068B8E8E00EBC58B8E9000C6 | ||
| 564 | :10233000EBBFD503F6003E0010000400CA043301D1 | ||
| 565 | :102340004D00140005000103050709000102030404 | ||
| 566 | :1023500080841E00A02526000000608BF033FF2E35 | ||
| 567 | :10236000A150232E8B165223BB3223F74638800010 | ||
| 568 | :10237000740C2EA154232E8B165623BB3C23B90577 | ||
| 569 | :10238000002E3B31730A4747E2F7B8FFFFEB1D9081 | ||
| 570 | :10239000D1EF2E8A8D46232AEDD1EAD1D8E2FAF781 | ||
| 571 | :1023A000F6050200C1E8022E8AA54B232EA358236E | ||
| 572 | :1023B000612EA15823C3080020008000000260099C | ||
| 573 | :1023C0000800200080000002000800000100020058 | ||
| 574 | :1023D0000300040052565785C074053D0109760379 | ||
| 575 | :1023E000B80109BF5B01F7463880007403BFB20132 | ||
| 576 | :1023F00033F62E3B84B62376044646EBF5F7E72EFC | ||
| 577 | :102400008BBCC02303C783D200D1E7F7F72E8AA481 | ||
| 578 | :10241000CA235F5E5AC3E43E80BEC30003750CF757 | ||
| 579 | :10242000467A200074050C80E63EC3247FE63EC356 | ||
| 580 | :1024300024038886C3008AE0E41024FC0AC4E61062 | ||
| 581 | :10244000808EA10042E8CEFFC390568BF083E60752 | ||
| 582 | :10245000D1E62EFFA458249068246C2470247424A0 | ||
| 583 | :102460007824872487248724B400EB0EB4C0EB0AB9 | ||
| 584 | :10247000B440EB06B420EB02B4A0E410241F0AC45D | ||
| 585 | :10248000E610808EA100425EC3903C0277128AE083 | ||
| 586 | :10249000E41024F3C0E4020AC4E610808EA10042D6 | ||
| 587 | :1024A000C3908B5E3884C0741F3C02742083CB08B9 | ||
| 588 | :1024B0008B462E3B463C770CE888FC7207B024E63E | ||
| 589 | :1024C0000A83CB10895E38C383E3F7EBF7F7C310B9 | ||
| 590 | :1024D0000074F5E86DFC72EC8A86C000E638B02323 | ||
| 591 | :1024E000E60AEBE08B5E388B462E3B463CE4D87721 | ||
| 592 | :1024F0000B24FE80CB12E6D8895E38C30C0180CB5A | ||
| 593 | :1025000002EBF35033DBC1E804250F0F8AD82E8A83 | ||
| 594 | :102510008766178ADC2E8AA7661709463E58C3507D | ||
| 595 | :1025200033DBC1E804250F0F8AD82E8A8766178A05 | ||
| 596 | :10253000DC2E8AA76617F7D021463E58C38B463E4D | ||
| 597 | :1025400033DB8AD80ADC2E8A877617E62C8AE0E409 | ||
| 598 | :102550002A240F0AC4E62A8A86A50084E4750DA8F9 | ||
| 599 | :10256000807411247F8886A500E60CC3A8807504BA | ||
| 600 | :102570000C80EBF1C31E6033C933D233F68ED98D94 | ||
| 601 | :10258000BEFD00578B0584C074168BD1428BFE4F65 | ||
| 602 | :10259000780938A3E40074084F79F788A2E400466C | ||
| 603 | :1025A0005F83C7094183F91072D989B6860089967D | ||
| 604 | :1025B0008400611FC353C7466600008B4664A94070 | ||
| 605 | :1025C00000740DB300A980007402B37F889EC1001F | ||
| 606 | :1025D00032DBA90200740380CB40A9004074038061 | ||
| 607 | :1025E000CB02A90080740380CB01A9301E74038044 | ||
| 608 | :1025F000CBBCA90020740380CB08A904017403801C | ||
| 609 | :10260000CB10A90800740380CB20889EC2005BC356 | ||
| 610 | :102610000651575016078DBEC400B91F0033C0AA1B | ||
| 611 | :1026200040E2FC8B86920089868E00898690005855 | ||
| 612 | :102630005F5907C3E4D8C0E80453250F008BD82E98 | ||
| 613 | :102640008A8766178886A9005AC30886AC00C686A2 | ||
| 614 | :10265000BA0001B00EE8EAE9C3AD36A3B413AD3653 | ||
| 615 | :10266000A3B613AD36A3B81383E90636F706B6133F | ||
| 616 | :102670000F00C38A4626F74648800074020C108873 | ||
| 617 | :1026800086BD0032C0837E1A00750E8B5E4043808B | ||
| 618 | :10269000E3FE3B5E0875020C01837E3A00750D1E59 | ||
| 619 | :1026A000C55E148B1F1F85DB75020C02F7463810C0 | ||
| 620 | :1026B0000074020C048B5E7AF7C3020074020C08EB | ||
| 621 | :1026C000F7C3040074020C10F7C3080074020C2056 | ||
| 622 | :1026D000F7C3400074020C408886BF00C3906A00B4 | ||
| 623 | :1026E0001FC60693120D9C0EE8F1EB90B002E6DADD | ||
| 624 | :1026F000F8C333C0E6DAF8C3B001E6D8F8C333C094 | ||
| 625 | :10270000E6D8F8C3B0FFE84EFAE8A1FAF8C3AC493E | ||
| 626 | :10271000E8AFFBF8C390AC49E815FDF8C390AC49AD | ||
| 627 | :10272000E867FDF8C390AC49E81FFDF8C390AC49D9 | ||
| 628 | :10273000E634F8C3AC49E636F8C3AC493C02771F2F | ||
| 629 | :1027400084C0751DE41424EFE614E412243FE6125D | ||
| 630 | :10275000E416A8047409E8EAF97204B018E60AF865 | ||
| 631 | :10276000C38AE0E4140C10E614E4120CC0F6C401B1 | ||
| 632 | :102770007402247FE612F8C3AC49E825FDF8C39043 | ||
| 633 | :10278000B80040E87DFDE8B4FDE8A8FEB001E8B976 | ||
| 634 | :10279000FEF8C390B80040E885FDE8A0FDF8C390BE | ||
| 635 | :1027A000B80010E85DFDE894FDE888FEB008E899FF | ||
| 636 | :1027B000FEF8C390B80010E865FDE880FDF8C3900E | ||
| 637 | :1027C000B80080E83DFDE874FDE868FEB002E879F5 | ||
| 638 | :1027D000FEF8C390B80080E845FDE860FDF8C390BE | ||
| 639 | :1027E000B80020E81DFDE854FDE848FEB004E859B3 | ||
| 640 | :1027F000FEF8C390B80020E825FDE840FDF8C3903E | ||
| 641 | :10280000AC49E84814E43C24E70AC4E63CF8C39029 | ||
| 642 | :10281000B8FC3B89467CE43C0C18E63CF8C3E41267 | ||
| 643 | :102820000C02E612F8C3E41224FDEBF6E8B5FCF85E | ||
| 644 | :10283000C390836638FDF8C3AC49A8017406834E83 | ||
| 645 | :102840007A20EB0483667ADFE8CBFBF8C3908A86B4 | ||
| 646 | :10285000A5000C0224FB8886A500E60C814E26010B | ||
| 647 | :1028600020AC4932E489466E834E48084946F9C394 | ||
| 648 | :102870008A86A5000C0224FB8886A500E60C814E02 | ||
| 649 | :10288000260120ACB40AF6E4EBD8E8FA13E43C24C1 | ||
| 650 | :10289000F80AC4E63CF8C390AD4949894664A901E9 | ||
| 651 | :1028A00000741B8BD883E3FA751AA90400740FE433 | ||
| 652 | :1028B0003E0C02E63EB83844894662F8C390E43ED6 | ||
| 653 | :1028C00024FCEBEFE43E24FCE63EE8E8FCB8AA403A | ||
| 654 | :1028D000EBE6E86EF87205B018E60AF8C390AC496A | ||
| 655 | :1028E000E8CFF9F8C390AC49E8CFF9F8C390E868AD | ||
| 656 | :1028F000FD750632C0E6DAF8C3B002E6DA36A0B4F7 | ||
| 657 | :102900001324103410E8160136A1B413A901007481 | ||
| 658 | :1029100005E8FCFEEB0EA90200740432C0EB02B025 | ||
| 659 | :1029200001E8DEFE36A1B413E8B513E43C24F80A4E | ||
| 660 | :10293000C4E63C36A1B413C1E805250100E8FAFE5F | ||
| 661 | :1029400036A0B5132410E859FB32C0368A26B513D9 | ||
| 662 | :10295000F6C4047409FEC0F6C4087402FEC0E8DBC5 | ||
| 663 | :10296000FD36A1B613250F00E857F936A1B613C1FD | ||
| 664 | :10297000E804250300E8B8FA36A1B613C1E8052536 | ||
| 665 | :102980000200E805FB36A1B613F6C401750432C097 | ||
| 666 | :10299000EB0980E402D0ECB0022AC4E8ACFA36F6C7 | ||
| 667 | :1029A00006B713407405E883FEEB03E884FE36F6B1 | ||
| 668 | :1029B00006B713207405E865FEEB03E868FEF8C36C | ||
| 669 | :1029C000E4120C01E612F8C3E41224FEEBF6E41460 | ||
| 670 | :1029D00024F00C05E614E42A24F00C06E62AF8C3D9 | ||
| 671 | :1029E000E42A24F0E62AE41424F00C07E614F8C3E1 | ||
| 672 | :1029F000AD4949E864F989868E00F8C3AD4949E8D4 | ||
| 673 | :102A000058F989869000F8C3834E2604E8A8F7F8A1 | ||
| 674 | :102A1000C390836626FBE89EF7F8C390AC4984C058 | ||
| 675 | :102A2000750DE41024EFE610808EA10042F8C3E497 | ||
| 676 | :102A3000100C10EBF190AC493C02760232C0C0E0C1 | ||
| 677 | :102A400004A82074020C0824188AE0E41224E70A7F | ||
| 678 | :102A5000C4E612808EA10044F8C3AC498886C00049 | ||
| 679 | :102A6000F8C3AC49E63AF8C3AC4984C07408E41230 | ||
| 680 | :102A70000C04E612F8C3E41224FBEBF6AC49E8D6EA | ||
| 681 | :102A8000F67303E827F7F8C3E412A802740424FDE0 | ||
| 682 | :102A9000E612B8F000E887FA816626FFF3E857F7F8 | ||
| 683 | :102AA000E89AFAF8C390B88000E857FA804E2708F1 | ||
| 684 | :102AB000E844F7E887FAF8C3B88000E861FA81666D | ||
| 685 | :102AC00026FFF7E831F7E874FAF8C390B81000E889 | ||
| 686 | :102AD00031FA804E2704E81EF7E861FAF8C3B8100F | ||
| 687 | :102AE00000E83BFA816626FFFBE80BF7E84EFAF8B0 | ||
| 688 | :102AF000C39033C0AC493C017304B001EB063C0CFD | ||
| 689 | :102B00007602B00C89461CF8C390814E2600208ABC | ||
| 690 | :102B100086A5000C0224FB8886A500E60C834E26C1 | ||
| 691 | :102B200001F8C390814E2600408A86A5000C0288D9 | ||
| 692 | :102B300086A500E60CF8C390AC4950E805F658723B | ||
| 693 | :102B400008E638B023E60AF8C3F9C390AC50ADE804 | ||
| 694 | :102B500082F85AF6C201741239869600740C89867E | ||
| 695 | :102B60009600E6F086E0E6F886E0F6C202741039D8 | ||
| 696 | :102B7000869400740A89869400E6E486E0E6EC8395 | ||
| 697 | :102B8000E903C390E4168886BC00E8E6FA33DBE488 | ||
| 698 | :102B90000CA806740380CB01A810740380CB02A894 | ||
| 699 | :102BA00080740380CB04E4128AE024180AD8E4DAA3 | ||
| 700 | :102BB000F6C4027407A840750380CB20A8027509EB | ||
| 701 | :102BC000E42AA80F740380CB40F74638020074094A | ||
| 702 | :102BD000E4D8A801750380CB80889EBE00FE86B431 | ||
| 703 | :102BE00000B00AE85CE4F8C3AC493C027441771FCA | ||
| 704 | :102BF00050E84FF558720C84C0740AB012E60A808F | ||
| 705 | :102C00004E3801F8C3B011E60A806638FEF8C38B6F | ||
| 706 | :102C1000463825FFF7894638A9000475E68A86A557 | ||
| 707 | :102C200000A81075DE0C108886A500E60CF8C3819C | ||
| 708 | :102C30004E3800088A86A500A81074C724EFEBE779 | ||
| 709 | :102C4000AD49493C0172113C0C770D508AE0E41407 | ||
| 710 | :102C500025F00F0AC4E614588AC484C07402E64200 | ||
| 711 | :102C6000F8C3E8CFF9FE86B900B00EE8D4E3F8C3A4 | ||
| 712 | :102C70003A86AF00741F8886AF008AE080C206B033 | ||
| 713 | :102C8000BFEE80EA028AC4EE8A86A80080C202EE05 | ||
| 714 | :102C900080EA068AC4C38B463E85C08A86A5007436 | ||
| 715 | :102CA00012A808750D0C088886A50080C202EE8067 | ||
| 716 | :102CB000EA02C3A80874FB24F7EBEC8B462684C019 | ||
| 717 | :102CC00074168A86A500A802740D24FD8886A500C6 | ||
| 718 | :102CD00083C202EE83EA02C38A86A500A80275F7C2 | ||
| 719 | :102CE0000C02EBE85283C20CECC0E8048886A90011 | ||
| 720 | :102CF0008B5E2680E33FF6C7047407A8087503803F | ||
| 721 | :102D0000CB40F6C7087407A802750380CB80885EA5 | ||
| 722 | :102D1000268A86A50084DB7410A802740A24FD8824 | ||
| 723 | :102D200086A50083EA0AEE5AC3A80275FA0C02EBE4 | ||
| 724 | :102D3000EE90FFFF00480030BA20C41A00180012BD | ||
| 725 | :102D4000000C0006000300028001C000600030009B | ||
| 726 | :102D50001800CD0100018000100010000E000C00D2 | ||
| 727 | :102D6000080000000000060004000300020001004B | ||
| 728 | :102D70005251563C1E7747988BF08A82C40032E449 | ||
| 729 | :102D800083FE18743D83FE19743E83FE1E772FD197 | ||
| 730 | :102D9000E62E8B8C322D3B8E94007422898E94000B | ||
| 731 | :102DA00083C2068A86A8008AE00C80EE83EA068A3F | ||
| 732 | :102DB000C1EE83C2028AC5EE83C2048AC4EE5E59A4 | ||
| 733 | :102DC0005AC38B8E8E00EBCE8B8E9000EBC8525187 | ||
| 734 | :102DD0003D05007703B805008BC8BA0200B800D0E3 | ||
| 735 | :102DE000F7F1050100D1E8595AC38B467AA820743F | ||
| 736 | :102DF0000B80BEC3000375040C01EB0224FE894660 | ||
| 737 | :102E00007AC324038886C3008AA6A8008ADC80E4EB | ||
| 738 | :102E1000FC0AC43AC3740B8886A80083C206EE83FA | ||
| 739 | :102E2000EA06E8C5FFC30008183828903C04772359 | ||
| 740 | :102E300032E48BD82E8A87262E8AA6A8008ADC80C8 | ||
| 741 | :102E4000E4C70AC43AC3740B8886A80083C206EE9E | ||
| 742 | :102E500083EA06C384C07402B0048AA6A8008ADC90 | ||
| 743 | :102E600080E4FB0AC43AC3740B8886A80083C206B8 | ||
| 744 | :102E7000EE83EA06C3908B5E3884C074343C0274DF | ||
| 745 | :102E80003B8A86AF000C04E8E6FD8B462E3B463CB1 | ||
| 746 | :102E9000771BF7C30004751581CB000483C2028A37 | ||
| 747 | :102EA00086A50024FA8886A500EE83EA02895E38AA | ||
| 748 | :102EB000C38A86AF0024FBE8B6FDEBF1F7C3100030 | ||
| 749 | :102EC00074EFEBED83C20CEC83EA0CC0E804888657 | ||
| 750 | :102ED000A900C3908A86A7000C018886A7008BDA18 | ||
| 751 | :102EE00080C208EE8BD3F8C38A86A70024FEEBEAE3 | ||
| 752 | :102EF0008A86A7000C02EBE28A86A70024FDEBDAA3 | ||
| 753 | :102F0000B0FFE852F2E897F2F8C3AC49E861FEF886 | ||
| 754 | :102F1000C390AC49E8EBFEF8C390AC49E835FFF844 | ||
| 755 | :102F2000C390AC49E805FFF8C3905283C206B0BF16 | ||
| 756 | :102F3000EE5283C202AC49EE5A8A86A800EE5AF8D5 | ||
| 757 | :102F4000C3905283C206B0BFEE5283C206EBE69036 | ||
| 758 | :102F5000AC493C02770D84C0750B8A86AF0024FD16 | ||
| 759 | :102F6000E80DFDF8C3508A86AF000C02E801FD5B56 | ||
| 760 | :102F700083C2088A86A700F6C301740C24DF888602 | ||
| 761 | :102F8000A700EE83EA08F8C30C20EBF2AC49E8E5B1 | ||
| 762 | :102F9000FEF8C390B80040E869F5E8F9FCE824FFC2 | ||
| 763 | :102FA000B001E8A5F6F8C390B80040E871F5E8E58F | ||
| 764 | :102FB000FCF8C390B80010E849F5E8D9FCE804FF34 | ||
| 765 | :102FC000B008E885F6F8C390B80010E851F5E8C5F8 | ||
| 766 | :102FD000FCF8C390B80080E829F5E8B9FCE8E4FE05 | ||
| 767 | :102FE000B002E865F6F8C390B80080E831F5E8A5CE | ||
| 768 | :102FF000FCF8C390B80020E809F5E899FCE8C4FEA5 | ||
| 769 | :10300000B004E845F6F8C390B80020E811F5E8856B | ||
| 770 | :10301000FCF8C390AC49E8340CF8C390B8FC3B8989 | ||
| 771 | :10302000467CF8C38A86AF000C80E843FCF8C39066 | ||
| 772 | :103030008A86AF00247FEBF28A86AF000C40E82F2F | ||
| 773 | :10304000FCF8C3908A86AF0024BFEBF2AC49A8011C | ||
| 774 | :103050007407834E7A20EB059083667ADFE88AFD59 | ||
| 775 | :10306000F8C383C2068A86A8000C408886A800EEB2 | ||
| 776 | :1030700083EA06AC4932E489466E834E2601834ECC | ||
| 777 | :103080004808B006E8BBDF4946F9C39083C2068A08 | ||
| 778 | :1030900086A8000C408886A800EE83EA06ACB40A35 | ||
| 779 | :1030A000F6E4EBD0E8E00BF8C390AD4949894664FB | ||
| 780 | :1030B000A9010074198BD883E3FA750AA904007476 | ||
| 781 | :1030C0000DB8E23FEB0BE8ECF4B8AA40EB03B838DC | ||
| 782 | :1030D00044894662F8C38A86AF00A802740A24FDB8 | ||
| 783 | :1030E000E88DFB0C02E888FBF8C3AC49E881FCF8EA | ||
| 784 | :1030F000C390AC49E879FCF8C390E85CF57505E845 | ||
| 785 | :10310000E6FDF8C3E8CDFD36A0B41324103410E872 | ||
| 786 | :10311000260136A1B413A901007405E8FEFEEB0EEA | ||
| 787 | :10312000A90200740432C0EB02B001E8E8FE36A147 | ||
| 788 | :10313000B413E8AB0B36A1B413C1E805250100E8D0 | ||
| 789 | :103140000CFF36A0B5132410E82BFD32C0368A26BA | ||
| 790 | :10315000B513F6C4047409FEC0F6C4087402FEC0B8 | ||
| 791 | :10316000E8EFFD36A1B613250F00E803FC36A1B643 | ||
| 792 | :1031700013C1E804250300E888FC36A1B613C1E8B2 | ||
| 793 | :1031800005250200E8CDFC36A1B613F6C40175048E | ||
| 794 | :1031900032C0EB0980E402D0ECB0022AC4E88CFC17 | ||
| 795 | :1031A00036F606B713407405E88DFEEB03E894FE8F | ||
| 796 | :1031B00036F606B713207405E869FEEB03E870FEE7 | ||
| 797 | :1031C000F8C3F8C38B4638A9040075230D040089A1 | ||
| 798 | :1031D000463883C2088B462E3B463C7314834E38D8 | ||
| 799 | :1031E000108A86A70024FE8886A700EE83EA08F8E6 | ||
| 800 | :1031F000C38A86A7000C01EBEE908B4638A9040029 | ||
| 801 | :10320000740625FBFF894638F8C3AD4949E8BEFB83 | ||
| 802 | :1032100089868E00F8C3AD4949E8B2FB89869000E3 | ||
| 803 | :10322000F8C3834E2604E892FAF8C390836626FB1F | ||
| 804 | :10323000E888FAF8C390AC4984C07507808EA30073 | ||
| 805 | :1032400004F8C380A6A300FBF8C3AC4983C2083CC2 | ||
| 806 | :1032500002760232C03C017412770B8A86A70024E2 | ||
| 807 | :10326000EF8886A700EE83EA08F8C38A86A7000CD9 | ||
| 808 | :1032700010EBEE905283C206B0BFEE5283C204AC94 | ||
| 809 | :1032800049EE5A8A86A800EE5AF8C3905283C206C5 | ||
| 810 | :10329000B0BFEE5283C208EBE690AC49F8C3AC492C | ||
| 811 | :1032A000E8B4EE7303E8F7EEF8C38A86AF00247F34 | ||
| 812 | :1032B000E8BDF9B8F000E866F2816626FFF3E8237E | ||
| 813 | :1032C000FAE8D2F9F8C3B88000E837F2804E270850 | ||
| 814 | :1032D000E811FAE8C0F9F8C3B88000E841F2816665 | ||
| 815 | :1032E00026FFF7E8FEF9E8ADF9F8C390B81000E85A | ||
| 816 | :1032F00011F2804E2704E8EBF9E89AF9F8C3B81008 | ||
| 817 | :1033000000E8FFF1816626FFFBE8D8F9F8C3AC4975 | ||
| 818 | :10331000F8C383C2068A86A8000C408886A800EEFF | ||
| 819 | :1033200083EA06F8C39083C2068A86A80024BFEB0E | ||
| 820 | :10333000EA90AC498AE080C20AEC80EA0AA82074CC | ||
| 821 | :10334000058AC4EEF8C30651578B4E24E3344989ED | ||
| 822 | :103350004E24FF461A8E46028B7E228AC4AA897E9C | ||
| 823 | :10336000228B462624FD89462675298A86A500A833 | ||
| 824 | :1033700002752180C2020C028886A500EE80EA0256 | ||
| 825 | :10338000EB12C47E003B7E1E760A4F268825897E7E | ||
| 826 | :1033900000FF461A5F5907F8C390ACAD83E9038577 | ||
| 827 | :1033A000C074053D00207205B8FFFFEB03C1E003C8 | ||
| 828 | :1033B0003B8694007426898694008BD85283C2067B | ||
| 829 | :1033C0008A86A8008AE00C80EE83EA068AC3EE8330 | ||
| 830 | :1033D000C2028AC7EE83C2048AC4EE5AF8C3B08818 | ||
| 831 | :1033E0008886BC00E88CF233DB8A86A500A80274CC | ||
| 832 | :1033F0000380CB01A805740380CB02A80874038066 | ||
| 833 | :10340000CB04F686A70010740380CB108A86A9002F | ||
| 834 | :10341000F6C304750A83C20CEC83EA0CC0E8048A84 | ||
| 835 | :10342000E08A86AF00A8807408F6C401750380CBDB | ||
| 836 | :1034300020F686A70002750AF74638040074038058 | ||
| 837 | :10344000CB40889EBE00FE86B400B00AE8F3DBF8ED | ||
| 838 | :10345000C3FE86B400B00AE8E8DBF8C3AC493C021E | ||
| 839 | :103460007437771084C07406804E3801F8C38066C4 | ||
| 840 | :1034700038FEF8C38B463825FFF7894638A9000483 | ||
| 841 | :1034800075EA8A86A500A80175E20C0583C2028848 | ||
| 842 | :1034900086A500EE83EA02F8C3814E3800088A86CA | ||
| 843 | :1034A000A500A80174C624FAEBE2AD4949F8C3901F | ||
| 844 | :1034B000E811FAFE86B900B00EE886DBF8C3B0FF6B | ||
| 845 | :1034C000E8BFECF8C39083667AFBB000E873DBF8E2 | ||
| 846 | :1034D000C390AC49E853D9721136881E1A0136A040 | ||
| 847 | :1034E0008E120AC352BA0001EE5AF8C3AC4932E454 | ||
| 848 | :1034F00036A38612050600368B1E88122BD8368915 | ||
| 849 | :103500001E8A12F8C390AD8BD8AD83E90403C32B98 | ||
| 850 | :103510004676894678F7467A0200740A83667AFD11 | ||
| 851 | :10352000B80000E81CDBF8C3061607AC49250F00FD | ||
| 852 | :103530006BC0098DBEFD0003F8AC49250F00AA85BC | ||
| 853 | :10354000C074082BC8518BC8F3A459E827F0E8448D | ||
| 854 | :103550000307F8C333C0AC4936A3B21336A3B01384 | ||
| 855 | :10356000F8C383667AEFE82C03F8C390834E7A1091 | ||
| 856 | :10357000EBF4E89BF0F8C390AD3C19770E3C19775B | ||
| 857 | :103580000A8BF881E7FF0088A6C400F8C390834E39 | ||
| 858 | :103590002620AC4932E4D1E08BD8C1E30203C389D1 | ||
| 859 | :1035A000466E834E4804B006E897DA4946F9C39060 | ||
| 860 | :1035B000FE86B300B00AE889DAF8C39033C0AC499C | ||
| 861 | :1035C0006BC00A89868A00F8C390AC4932E43D0A90 | ||
| 862 | :1035D000007705B80A00EB083D5A007203B85A009C | ||
| 863 | :1035E00051F7D80564008BC88B4644F7E1B96400F5 | ||
| 864 | :1035F000F7F189464659F8C3AC49E885EBF8C39022 | ||
| 865 | :10360000AC4984C07507816638FFFDF8C3814E3828 | ||
| 866 | :103610000002F74638400075088A86A9008886AA05 | ||
| 867 | :1036200000F8C3905156E87F0C5E59F8C390FE86AF | ||
| 868 | :10363000B600B00AE80BDAF8C390FE86B700B00A0D | ||
| 869 | :10364000E8FFD9F8C390FE86B800B00AE8F3D9F8CD | ||
| 870 | :10365000C39000905155AC2EA2523633C9AD8BF9B0 | ||
| 871 | :10366000C1E705A9010074232E8BAD4400837E08B9 | ||
| 872 | :103670000074182E803E523601740960B004E8BB15 | ||
| 873 | :103680000C61EB0760B0FBE8EC0C614747D1E875D3 | ||
| 874 | :10369000D24183F90472C65D5983E905F746384083 | ||
| 875 | :1036A000007405E887EAF8C3E88DEAF8C39036C6E7 | ||
| 876 | :1036B00006C81301F8C333C0AC4936A38012AC4925 | ||
| 877 | :1036C000362B068812F7D836A38212F8C390DE266E | ||
| 878 | :1036D000DE26EC26F226F826FE2604270E271627DD | ||
| 879 | :1036E0001E2726272E273427BE34C634D2343A2745 | ||
| 880 | :1036F000782780279427A027B427C027D427E0273E | ||
| 881 | :10370000F42700281028EC34DE261E2826282C2832 | ||
| 882 | :10371000322838284E288A28063528359828BE2889 | ||
| 883 | :10372000D228DE28E628543562356C35EE28C029CB | ||
| 884 | :10373000C829CE29E02972357835F029FC298E3543 | ||
| 885 | :10374000082A122A1C2AB035362ABC355A2A622A7F | ||
| 886 | :10375000682ACA357C2AF835882AA62AB82ACC2AAB | ||
| 887 | :10376000DE2AF22A00360A2B242B2436382B4C2B47 | ||
| 888 | :10377000842B2E363A3646365436E82BAE36402C5D | ||
| 889 | :10378000622CB6367028DE26DE26D42EE82EF02EE9 | ||
| 890 | :10379000F82E002F0A2F122F1A2F222F2A2F422FF6 | ||
| 891 | :1037A000BE34C634D234502F8C2F942FA82FB42F70 | ||
| 892 | :1037B000C82FD42FE82FF42F083014301C30EC34ED | ||
| 893 | :1037C000DE2624303030383044304C306230A43083 | ||
| 894 | :1037D00006352835AA30CE30D630EA30F2305435AE | ||
| 895 | :1037E00062356C35FA30C231C231C431FA317235CA | ||
| 896 | :1037F00078350A3216328E3522322C323632B035D6 | ||
| 897 | :103800004A32BC3574328C329A32CA359E32F8351F | ||
| 898 | :10381000AA32C632D832EC32FE320E3300361233C0 | ||
| 899 | :103820002633243632339A33DE332E363A36463652 | ||
| 900 | :1038300054365C34AE36AA34B034B6368C30E32815 | ||
| 901 | :10384000F7463840007532E8E3E833C0AC493D5BE9 | ||
| 902 | :103850000077198BD8D1E32EFF97CE36720B85C92E | ||
| 903 | :1038600075E88B4648E81A0CC34E41C36A001FC670 | ||
| 904 | :103870000693120C9C0EE863DAE8BCE833C0AC494E | ||
| 905 | :103880003D5B0077E78BD8D1E32EFF97863772D95F | ||
| 906 | :1038900085C975E8C3F7467A1000750F83BE8400AA | ||
| 907 | :1038A000007408B8483A89868000C381BE8000EC65 | ||
| 908 | :1038B0003C74F783BE8800007505B8EC3CEBE7F775 | ||
| 909 | :1038C000467A080075401E608B8E88003B4E7477E8 | ||
| 910 | :1038D000333B4E78772EC47E108BDF26033D47475F | ||
| 911 | :1038E00033C08ED88DB6F4008BC1F7467A010075CF | ||
| 912 | :1038F0001DF3A4260107294678014676294674B0AF | ||
| 913 | :103900000CE83ED7611FC78688000000EBACE3E3FC | ||
| 914 | :103910005090AC247FAAE2FA58EBD8908B8E8800A6 | ||
| 915 | :10392000E3468B9E8A0085DB743EBA50FFED2B8602 | ||
| 916 | :1039300082003BC372378DB6F400C47E108BDF2645 | ||
| 917 | :10394000033D47478BC1161FF7467A01007524F3E4 | ||
| 918 | :10395000A4260107294678014676294674C7868839 | ||
| 919 | :10396000000000B00CE8DAD683667AF7C3B000E84E | ||
| 920 | :10397000D0D6C3E3DC50AC247FAAE2FA58EBD29055 | ||
| 921 | :103980001E6033C08ED88DB6FD008B8688008B9666 | ||
| 922 | :1039900084003A0475108BDE468BC88DBEF400F3AC | ||
| 923 | :1039A000A674668BF39083C6094A75E68DB6FD0052 | ||
| 924 | :1039B0008B9684003A0473108BDE468BC88DBEF460 | ||
| 925 | :1039C00000F3A674768BF39083C6094A75E68DB62C | ||
| 926 | :1039D000F400ACF7467A01007402247F1EC55E1025 | ||
| 927 | :1039E0008B37884002468937FF4E78FF4676FF4E78 | ||
| 928 | :1039F000741F8B8E880049898E8800E3438DB6F44E | ||
| 929 | :103A0000008BFE46F3A4E97DFFC576108B1C85DB99 | ||
| 930 | :103A1000740803F383C60383E6FE8B8684002BC2FF | ||
| 931 | :103A2000B48089044646C7040000897610834E7A24 | ||
| 932 | :103A300004C78688000000611FF9C333C0611FC33B | ||
| 933 | :103A4000B08084C0611FC3908B4E782B8E88007627 | ||
| 934 | :103A50002789B68C008B5E743BCB72028BCB3BC844 | ||
| 935 | :103A600072028BC88BC1E34433D28EC28BD183BE2A | ||
| 936 | :103A70008800007406E98E0033C0C38B5E10031FFC | ||
| 937 | :103A8000434352F7467A0100752AAC8DBEE4008BA1 | ||
| 938 | :103A90008E8600F2AE74348807434A75ED588B5E0B | ||
| 939 | :103AA0001001072946780146762946748BC62B8675 | ||
| 940 | :103AB0008C00C390AC8DBEE4008B8E8600F2AE7499 | ||
| 941 | :103AC0000A247F8807434A75EBEBD28886F400C747 | ||
| 942 | :103AD0008688000100582BC2740E8B5E10010729E6 | ||
| 943 | :103AE000467801467629467440E894FE72BE4A75CF | ||
| 944 | :103AF0001583BE8A000074B4BA50FFED8986820037 | ||
| 945 | :103B0000834E7A08EBA68DBEF40003BE8800A4FFA6 | ||
| 946 | :103B1000868800E86AFE729479064A748FE95BFF32 | ||
| 947 | :103B20004A74CEEBE19050E811CC8B467439467262 | ||
| 948 | :103B300074271E565133C9C5760CAD74107809032D | ||
| 949 | :103B4000C805010024FE03F03B761076ED294E7681 | ||
| 950 | :103B5000014E78E837CC595E1F58C390C47E1026BA | ||
| 951 | :103B60008B1D83C30326891D4B03FBAB91AAB803AE | ||
| 952 | :103B700000294678014676294674C390C47E1026F3 | ||
| 953 | :103B80008B1D4326891D4303FBAAFF4E78FF467613 | ||
| 954 | :103B9000FF4E74C3E8E5FFC38081848582838687F6 | ||
| 955 | :103BA00050538ADC83E30ED1EB2E8A87983B08863C | ||
| 956 | :103BB000B000FE86B100B00AE887D45B58C3508AD3 | ||
| 957 | :103BC000C8B8FF00E895FF58C3908A86BB00E8ABF1 | ||
| 958 | :103BD000FFC3E8CBFFE8F2FFC390E8C3FFE8B4FF00 | ||
| 959 | :103BE000C39033C0E895FFC3B8FF0033C9E86CFF4A | ||
| 960 | :103BF000C390B8FF01B110E862FFC390C3FC3BE281 | ||
| 961 | :103C00003BF23BF23BFC3BE23BE83BE83BFC3BE26C | ||
| 962 | :103C10003BE83BE83BFC3BE23BE23BE23B00100085 | ||
| 963 | :103C20000000100000001000000010000000100054 | ||
| 964 | :103C3000000010000000100000001000000008004C | ||
| 965 | :103C40000000080000000800000008000051538B2D | ||
| 966 | :103C50004E3881E1FFEEA804740481C900018AE0B6 | ||
| 967 | :103C600080E4032418D0E40AC433DB8AD82E8B877F | ||
| 968 | :103C7000FD3B89467C2E0B8F1D3C894E38D1EB2EA7 | ||
| 969 | :103C80008AA73D3C5B59C3AC493C01721D74203C82 | ||
| 970 | :103C900003722374283C08722B74303C20723774F2 | ||
| 971 | :103CA0003ABBDA3B32E4895E7EC3BBA03BEBF5BB9B | ||
| 972 | :103CB000943BB401EBF0BBFC3BB402EBE9BBE23B51 | ||
| 973 | :103CC000B403EBE2BBBE3BB404EBDBBBCA3BAC4989 | ||
| 974 | :103CD0008886BB00EBCEBBD23BEBF3BBFC3BEBC41B | ||
| 975 | :103CE000A9040075D1A9080075DAEBD18B5E748B3D | ||
| 976 | :103CF0004E783BCB72028BCB3BC872028BC88BC118 | ||
| 977 | :103D0000E32CC47E108BDF26033D4747F7467A013C | ||
| 978 | :103D100000751CF7C70100740249A4D1E9F3A5732B | ||
| 979 | :103D200001A4260107294678014676294674C35026 | ||
| 980 | :103D300053BB7F7FF7C70100740549AC22C3AAD1EA | ||
| 981 | :103D4000E9E31D9CAD23C3AB497414AD23C3AB4958 | ||
| 982 | :103D5000740DAD23C3AB497406AD23C3ABE2E59D3F | ||
| 983 | :103D60007304AC22C3AB5B58EBB8E8CEC98B5E38AA | ||
| 984 | :103D7000F7C310047501C3F7C340007405E8B8E346 | ||
| 985 | :103D8000EB03E8A8E3816638EFFBF6C310743CF65A | ||
| 986 | :103D9000C3027406E4D80C01E6D8F6C30474118398 | ||
| 987 | :103DA000C2088A86A7000C01EE8886A70083EA086D | ||
| 988 | :103DB000F6C308740FE88BE3720A8A86C000E638FF | ||
| 989 | :103DC000B023E60AF7C300047501C3F7C300087502 | ||
| 990 | :103DD000F98A86A500F6C340750DA81075EC0C1085 | ||
| 991 | :103DE0008886A500E60CC3A80175DF83C2020C0516 | ||
| 992 | :103DF000EE8886A500C3B000E847D2EB0FB002E81A | ||
| 993 | :103E0000900EEB08836638DF834E7A0233C08ED87B | ||
| 994 | :103E1000FAA0921240A292123C05721EC60692129D | ||
| 995 | :103E200000FBB001E86B0EFAA1260123062A01A8C7 | ||
| 996 | :103E3000017507E8E207E8610990B000E837D2FBB6 | ||
| 997 | :103E400085ED74B9FAF7467A460075C08B46783D21 | ||
| 998 | :103E50000A0072B08B4E7483F950729A836638DF11 | ||
| 999 | :103E6000C576148B463A85C07558AD85C0750FE888 | ||
| 1000 | :103E7000F8FEF7467A08007493E8A0FAEB8E3B76DA | ||
| 1001 | :103E8000047621B90200394E2E7705C7462E000070 | ||
| 1002 | :103E9000568B762C897604C7040000464689762C1A | ||
| 1003 | :103EA000294E2E5E85C07917F6C4107405FF567C26 | ||
| 1004 | :103EB000EB03FF567E897614B00CE885D1EB86893A | ||
| 1005 | :103EC000463AFF96800029463A897614B00CE8718C | ||
| 1006 | :103ED000D1E971FF0000000000000000080410029A | ||
| 1007 | :103EE00001200000000000000000000000000000B1 | ||
| 1008 | :103EF00000000000808080808080808080808080C2 | ||
| 1009 | :103F000080808080808080808080808080808080B1 | ||
| 1010 | :103F100080808080808080808080808080808080A1 | ||
| 1011 | :103F20008080808080808080808080808080808091 | ||
| 1012 | :103F30008080808080C0C0C0C0C0C0C0C0C0C0C0C1 | ||
| 1013 | :103F4000C0C0C0C0C0C0C0C0C0C0C0C0C0C0C080B1 | ||
| 1014 | :103F500080808000808080808080808080808080E1 | ||
| 1015 | :103F60008080808080808080808080808080808051 | ||
| 1016 | :103F70008080808080808080808080808080808041 | ||
| 1017 | :103F80008080808080808080808080808080808031 | ||
| 1018 | :103F90008080808080808080808080808080808021 | ||
| 1019 | :103FA0008080808080808080808080808080808011 | ||
| 1020 | :103FB0008080808080808080808080808080808001 | ||
| 1021 | :103FC00080808080808080808080808080808080F1 | ||
| 1022 | :103FD000808080804E417841D041F44106421842B1 | ||
| 1023 | :103FE000C3908E46028B7E22897E6C806627FD8B75 | ||
| 1024 | :103FF000562483FA0472E983EA028BD93BCA76021B | ||
| 1025 | :104000008BCAB00A57518BFEF2AE8BC1595F751E39 | ||
| 1026 | :1040100050402BC874062BD12BD9F3A4594B4A4AD4 | ||
| 1027 | :10402000B00DAAA43BCA76028BCAE313EBD42BD9FA | ||
| 1028 | :10403000F7C601007402A449D1E9F3A57301A4896C | ||
| 1029 | :104040007E222B7E6C297E24017E1A8BCB807E26DD | ||
| 1030 | :10405000027405806626FDC360B0FDE8180361C3E5 | ||
| 1031 | :10406000C390E87C0272F990834E26208B466A89C1 | ||
| 1032 | :10407000466E8B46480D040025BFFF894648B006B2 | ||
| 1033 | :10408000E8BFCFC3897E222B7E6C017E1A297E2455 | ||
| 1034 | :10409000807E26027405836626FDC360B0FDE8D5E8 | ||
| 1035 | :1040A0000261C3908ABEC200EB24F7464840007507 | ||
| 1036 | :1040B000B18E46028B7E22897E6C8B562483EA0A5F | ||
| 1037 | :1040C000789E03D7806627FD33C08ABEC200E3B462 | ||
| 1038 | :1040D0003BFA77B0AC49932E8A87D43E9322DF75A2 | ||
| 1039 | :1040E00017AAE3A03BFA779CAC49932E8A87D43E6B | ||
| 1040 | :1040F0009322DF7503AAEBD6F6C37F7505FF4666EC | ||
| 1041 | :10410000EBDFF6C340750C8BD883EB08D1E32EFFB1 | ||
| 1042 | :10411000A7D43FFF46662C20EBC785C0742C894688 | ||
| 1043 | :104120006A834E4840897E222B7E6C017E1A297E4E | ||
| 1044 | :1041300024807E26027408836626FDE8A301C360FE | ||
| 1045 | :10414000B0FDE8310261E89801C3E957FF908B5E4A | ||
| 1046 | :10415000664B7803895E66AA8B5E64F7C3002075A0 | ||
| 1047 | :1041600003E940FFF7C3400074088A86C100AAE94A | ||
| 1048 | :1041700032FFB83200EBA3908B5E66895E6883C322 | ||
| 1049 | :104180000880E3F8895E668B5E6481E3001881FB3A | ||
| 1050 | :104190000018742DAA85DB7425F746644000751855 | ||
| 1051 | :1041A00081FB0010740C8B46662B4668C1E004E965 | ||
| 1052 | :1041B00068FFB86400E962FF8A86C100AAAAE9E341 | ||
| 1053 | :1041C000FE518B4E662B4E68B020F3AA59E9D4FEFF | ||
| 1054 | :1041D0008B5E66895E688B5E64F7C324007410C7CB | ||
| 1055 | :1041E00046660000F7C304007405B00DAAB00AAA21 | ||
| 1056 | :1041F000EB489090AAF7466400407406B8D007E9EF | ||
| 1057 | :1042000018FFE99FFE90AAF7466400807406B8D0B4 | ||
| 1058 | :1042100007E906FFE98DFE908B5E66895E6885DBA7 | ||
| 1059 | :10422000750C8B5E64F7C310007406E976FE8B5E36 | ||
| 1060 | :1042300064F7C308007427B00AAAF7C32000751FEB | ||
| 1061 | :10424000F7C300017503E95BFEF7C340007506B8CC | ||
| 1062 | :104250006400E9C5FE8A86C100AAAAE946FEAAC78B | ||
| 1063 | :1042600046660000F7C3000674F1F7C340007419F6 | ||
| 1064 | :104270008A86C10081E3000681FB00047206760293 | ||
| 1065 | :10428000AAAAAAAAAAAAE91BFE81E3000681FB004A | ||
| 1066 | :1042900004720E7606B89600E97FFEB86400E979EC | ||
| 1067 | :1042A000FE8B4668E973FE90368B0EDA1283F93284 | ||
| 1068 | :1042B000731D1E0633C08ED88EC08D764CBFDC12A7 | ||
| 1069 | :1042C00003F9A5A5A583C106890EDA12071FC3B09D | ||
| 1070 | :1042D00008E86ECDC390836648FEE893C4E8C8FF43 | ||
| 1071 | :1042E000C3F6462702750F9CFA837E1A0074098074 | ||
| 1072 | :1042F0004E27019DF9C3F8C35052F7463840007469 | ||
| 1073 | :104300001DE834DE83C20AECA840752783EA088AD8 | ||
| 1074 | :1043100086A5000C028886A500EE5A58EBD1E80C61 | ||
| 1075 | :10432000DE8A86A50024FB0C028886A500E60C5ACE | ||
| 1076 | :1043300058EBBC804E27025A589DF8C30846269C6D | ||
| 1077 | :10434000FA8A8EA500F7463840007514F6C1067447 | ||
| 1078 | :1043500023E8D9DD8AC124F98886A500E60C9DC32F | ||
| 1079 | :10436000F6C102740FE8D0DD83C2028AC124FD8841 | ||
| 1080 | :1043700086A500EE9DC38B5E2622C3884626740167 | ||
| 1081 | :10438000C3806627FD9CFA8A8EA500F74638400058 | ||
| 1082 | :104390007516F6C104750FE893DD8AC124FD0C047F | ||
| 1083 | :1043A0008886A500E60C9DC3F6C10275F9E888DD94 | ||
| 1084 | :1043B00083C20AECA820750E83EA088AC10C028821 | ||
| 1085 | :1043C00086A500EE9DC383EA0A33C98A4E1C8B463C | ||
| 1086 | :1043D0001A3BC8731B014E2A2BC189461A1EC5768B | ||
| 1087 | :1043E00000F36E1F89760083C2028A86A500EBCD9A | ||
| 1088 | :1043F00085C0741201462A8BC81EC57600F36E1F55 | ||
| 1089 | :10440000897600894E1AF6C701752380CB02895E32 | ||
| 1090 | :1044100026E808C383C2028A86A50024FDEE8886AA | ||
| 1091 | :10442000A500F6C7107505B002E816CC9DC383C27F | ||
| 1092 | :10443000028A86A500EB86908BD18B46243BC876FA | ||
| 1093 | :10444000028BC82BD12BC18BD9E322806627FD8E2E | ||
| 1094 | :1044500046028B7E22F7C601007402A449D1E9F31B | ||
| 1095 | :10446000A57301A4897E22894624015E1A8BCA8025 | ||
| 1096 | :104470007E26027405806626FDC360B0FDE8F6FE68 | ||
| 1097 | :1044800061C350E40A84C0750A8686A10084C074A2 | ||
| 1098 | :104490000AE60A580C20894648F9C35824DF8946A1 | ||
| 1099 | :1044A00048F8C390FBB002E8E807FAE82E01FBB039 | ||
| 1100 | :1044B00001E8DE07FAB002E8BCCBFB85ED74E5FA53 | ||
| 1101 | :1044C0008E5E0AFB90FA8B46488B7640A88C75DE90 | ||
| 1102 | :1044D000A820741A50E855DC58E8A6FF7310B00203 | ||
| 1103 | :1044E000E85FCBEBC99025FF008BC8EB3690A801A5 | ||
| 1104 | :1044F00075224683E6FE3B76087479AD8AFCB3F0FC | ||
| 1105 | :1045000022FB3AFB74E03ABEA000742EE8D2FD73A1 | ||
| 1106 | :1045100077EB9B908AE024FC8846488B4E4AF6C491 | ||
| 1107 | :1045200002741DE8BBFD7286E813F3897640E393BD | ||
| 1108 | :10453000834E4803894E4AE974FF25FF0F8BC890CC | ||
| 1109 | :104540008B86980085C0741A518A8EA000C0E90439 | ||
| 1110 | :10455000BA0100D3E25923C2740803F1897640E915 | ||
| 1111 | :1045600061FFFF5662E3F5834E4801894E4A897622 | ||
| 1112 | :1045700040E93AFF814E2600108B46503B46467775 | ||
| 1113 | :1045800003E852FDE927FF9088BEA000EBAC0A06C5 | ||
| 1114 | :1045900090128AE0BA0601B004EEEC84C07512B045 | ||
| 1115 | :1045A00004EE8AC4EE32E4A8807406C706841200C2 | ||
| 1116 | :1045B0000088269012C30A0690128AE0BA0601EC1F | ||
| 1117 | :1045C000A80175EDBA08018AC4EE32E4A88074E14E | ||
| 1118 | :1045D000C7068412000088269012C39036F706247E | ||
| 1119 | :1045E0000101007530368B0EDA1280F936732633EE | ||
| 1120 | :1045F000C08EC08ED8BFDC1203F9B008E877CA8538 | ||
| 1121 | :10460000ED740E8D764CA5A5A580C10680F9367295 | ||
| 1122 | :10461000E9890EDA12C3C390F7062601010075F688 | ||
| 1123 | :104620008B0E201385C975EE33C08EC08ED8BF2483 | ||
| 1124 | :1046300013B93600B00AE83DCA85ED7506E91201E6 | ||
| 1125 | :10464000E90A0133DB8A464C8AA6B300FECC780E19 | ||
| 1126 | :1046500088A6B3000ADCB40AAB83E90276E28AA634 | ||
| 1127 | :10466000B200FECC780E88A6B2000ADCB408AB8398 | ||
| 1128 | :10467000E90276CC8AA6B100FECC78188ABEB000DA | ||
| 1129 | :10468000750488A6B00088A6B1000ADC8AE7AB836F | ||
| 1130 | :10469000E90276AC8AA6B400FECC781F88A6B400E6 | ||
| 1131 | :1046A0000ADCB40BAB8A86BC008AA6BD00AB8B8645 | ||
| 1132 | :1046B000BE00AB83E90676888A464C8AA6B600FE21 | ||
| 1133 | :1046C000CC781988A6B6000ADCB40CABE8DBCBAB1F | ||
| 1134 | :1046D0008B462AAB83E90676748A464C8AA6B700D5 | ||
| 1135 | :1046E000FECC781988A6B7000ADCB40DABE8BACBCB | ||
| 1136 | :1046F000AB8B4634AB83E90676538A464C8AA6B820 | ||
| 1137 | :1047000000FECC781988A6B8000ADCB40EABA15024 | ||
| 1138 | :1047100012ABA15212AB83E90676328A464C8AA6C6 | ||
| 1139 | :10472000B500FECC781888A6B5000ADCB40FAB8BB8 | ||
| 1140 | :10473000869A00AB8B869C00AB83E906760F84DB00 | ||
| 1141 | :104740007503E9EFFEB00AE8F8C8E9E7FEB00AE849 | ||
| 1142 | :10475000F0C8F7D983C1368BC10D800086C4A3226F | ||
| 1143 | :10476000134141890E2013C3A184122BC17211A3DE | ||
| 1144 | :104770008412BE2213D1E9F36F90890E2013F8C37F | ||
| 1145 | :10478000F9C3C381EF6A1374F98BC70D800086C427 | ||
| 1146 | :10479000A368134747893E6613C3F7062A01010041 | ||
| 1147 | :1047A00075E08B0E6613E30780F92077D54949330E | ||
| 1148 | :1047B000C08EC08ED8BF6A138BF703F983C6343B13 | ||
| 1149 | :1047C000FE77C0B00EE8AEC885ED74B78A464C8A55 | ||
| 1150 | :1047D000B6B900FECE781588B6B9008AA6A90080C1 | ||
| 1151 | :1047E000CCC0AB84F67405B00EE856C88AB6BA00E1 | ||
| 1152 | :1047F000FECE78CB8A9EA9008ABEAB008A563F8A3D | ||
| 1153 | :10480000F332F70AB6AC00C686AC000022F2744B55 | ||
| 1154 | :10481000F6C608740FB402F6C3087502B403AB8081 | ||
| 1155 | :10482000E6F77437F6C601740FB400F6C3017502DB | ||
| 1156 | :10483000B401AB80E6FE7423F6C602740FB404F62E | ||
| 1157 | :10484000C3027502B405AB80E6FD740FF6C60474AE | ||
| 1158 | :104850000AB406F6C3047502B407ABC686BA0000F4 | ||
| 1159 | :10486000889EAB00E958FF90A184122BC17211A35E | ||
| 1160 | :104870008412BE6813D1E9F36F90890E6613F8C3F2 | ||
| 1161 | :10488000F9C3A1841241412BC17223A384128BC1AD | ||
| 1162 | :10489000484832E40C8086C4EF9090909090BEDC43 | ||
| 1163 | :1048A000124949D1E9F36F90890EDA12F8C3F9C3BE | ||
| 1164 | :1048B0008AC88A464CB40183EB06EF9090909090A2 | ||
| 1165 | :1048C000B80100EF90909090908AC1EF90909090F6 | ||
| 1166 | :1048D00090E99700E9AC0033C08ED8891E8412C3DA | ||
| 1167 | :1048E000368B1E8412FB90FAB00CE889C785ED74F4 | ||
| 1168 | :1048F000E6C5760C83FB1472DBFB90FAAD85C078BD | ||
| 1169 | :10490000AF74E28BFE03F8368B0E86123BC1770242 | ||
| 1170 | :104910008BC883EB043BD977028BCB33C08A464CE0 | ||
| 1171 | :10492000EF90909090908BC1EF90909090904180FC | ||
| 1172 | :10493000E1FE2BD951D1E9F36F90598BC74024FE8A | ||
| 1173 | :104940003BC674272BFE4E4E538B5E103BF3721307 | ||
| 1174 | :10495000031F83C30380E3FEC7070000836E740256 | ||
| 1175 | :10496000895E105B893C89760CEB8989760C3976F7 | ||
| 1176 | :104970001077817208833C007403E977FFE80DBE6D | ||
| 1177 | :10498000E962FF36891E8412B00CE8B5C633C08ECA | ||
| 1178 | :10499000D8C3A184123D10007277BA04013B068887 | ||
| 1179 | :1049A000127506C7067E1200008B0EDA12E30BE8C2 | ||
| 1180 | :1049B000D0FE7257C7067E12FF7F8B0E2013E30BCB | ||
| 1181 | :1049C000E8A5FD7246C7067E12FF7F8B0E6613E3D5 | ||
| 1182 | :1049D0000BE894FE7235C7067E12FF7FA12801A95D | ||
| 1183 | :1049E00001007503E8F9FE803E8D1200751DA1845B | ||
| 1184 | :1049F000123D200076153B0682127609A17E123BFD | ||
| 1185 | :104A0000068012720C800E901280C3B080FF167C5C | ||
| 1186 | :104A100012C3800E901240C36A001FC6069312177D | ||
| 1187 | :104A20009C0EE8B7C86A001FC6069312209C0EE8C9 | ||
| 1188 | :104A3000AAC86A001FC6069312169C0EE89DC8906D | ||
| 1189 | :104A4000BA0601ECA82075CAFB90FABA0401ED90F1 | ||
| 1190 | :104A5000909090903A06941277BE33DB8AD8D1E3D7 | ||
| 1191 | :104A60002E8BAF4400C47E0885FF74B9F6C4C075B0 | ||
| 1192 | :104A70005532C0C1E00280E4F08BF0ED9090909050 | ||
| 1193 | :104A80009085C074BB8BC84180E1FE0BC68B5E5025 | ||
| 1194 | :104A90004B4B2BD9789CAB8BC1404001464ED1E9A2 | ||
| 1195 | :104AA000F36D90895E50897E088B462680E4EF89FD | ||
| 1196 | :104AB0004626F6C401750CF746480C007505B00291 | ||
| 1197 | :104AC000E87FC5E97AFF86C48BC883E13F4180E176 | ||
| 1198 | :104AD000FEE30A3C807209243FB4F0EBB0E960FFCA | ||
| 1199 | :104AE000253F0033FF8EC7BF96128BF7D1E9F36DD8 | ||
| 1200 | :104AF000908BC8E848EDE947FF906A001FC606930F | ||
| 1201 | :104B0000121B9C0EE8D5C790601E0633C08ED88E4F | ||
| 1202 | :104B1000C0BA0601ECA80474E1B006EEECA28C1257 | ||
| 1203 | :104B2000A8407411A18812A38412C6068D1200E851 | ||
| 1204 | :104B300060FEA08C12A8807403E804FFB80080BA5D | ||
| 1205 | :104B400022FFEF071F61CF906A001FC60693121B5A | ||
| 1206 | :104B50009C0EE887C790601E0633C08ED88EC0BA00 | ||
| 1207 | :104B60000601ECA80474E1BA0801ECA28C12A8407A | ||
| 1208 | :104B70007411A18812A38412C6068D1200E812FED9 | ||
| 1209 | :104B8000A08C12A8807403E8B6FEB80080BA22FF99 | ||
| 1210 | :104B9000EF071F61CF90EE86E0EE86E0EC86E0EC5A | ||
| 1211 | :104BA00086E080E1FEF36C9080E1FEF36E900500FC | ||
| 1212 | :104BB0007547A84B05007548A84B0500A348A84BAE | ||
| 1213 | :104BC00005003549A84B06009848964B0600BA48A0 | ||
| 1214 | :104BD000964B0600C348964B0600CB48964B060002 | ||
| 1215 | :104BE0002049964B06002849964B06004E4A9C4B9E | ||
| 1216 | :104BF00006007B4A9C4B05009E4AA24B0500EC4AEE | ||
| 1217 | :104C0000A24B00001E06833E4412007409A0060158 | ||
| 1218 | :104C100024303C30741A8CC88ED88EC0BBAE4B8BFF | ||
| 1219 | :104C20000FE30D8B7F028B7704F3A483C306EBEFB6 | ||
| 1220 | :104C3000071FC39033C0A33E01B90C01BE40018BD6 | ||
| 1221 | :104C4000FE81C6B40F89048BC62BF13BC777F6A350 | ||
| 1222 | :104C50003C01C3901E0660368B2E3E018B5E003BEE | ||
| 1223 | :104C6000EB742B8B7602891C89770236A13C018973 | ||
| 1224 | :104C7000460036892E3C018BEBFF4E0674088B6E86 | ||
| 1225 | :104C800000FF4E0675F836892E3E018B66046107DB | ||
| 1226 | :104C90001FC31E0660368B2E3E0198894606896624 | ||
| 1227 | :104CA000043B6E0074108B6E00FF4E0675F836895B | ||
| 1228 | :104CB0002E3E018B660461071FC3C3901E06609CD5 | ||
| 1229 | :104CC000FA33ED8EDD8B2E3C0185ED743D8B4E006D | ||
| 1230 | :104CD000890E3C018BCC8DA60A01561E06608966A2 | ||
| 1231 | :104CE00004C746080F1AC7460601008B1E3E018501 | ||
| 1232 | :104CF000DB741D8BC58707894600895E028BD889C6 | ||
| 1233 | :104D00006F028BE19D61071FF8C39D61071FF9C307 | ||
| 1234 | :104D1000892E3E01896E00896E0287E19D8BE1EB51 | ||
| 1235 | :104D2000E4000D0A5465726D696E616C73207375D1 | ||
| 1236 | :104D300070706F727465643A0D0A312920414E53C8 | ||
| 1237 | :104D40004920636F6D70617469626C650D0A322968 | ||
| 1238 | :104D500020577973652033300D0A506C6561736597 | ||
| 1239 | :104D60002073656C6563743A20000D0A636F646597 | ||
| 1240 | :104D7000207365676D656E743D000D0A4D6F6E6939 | ||
| 1241 | :104D8000746F722076322E350A0D0A3E000D0A50DD | ||
| 1242 | :104D90006172646F6E3F000D0A4E6F206164647231 | ||
| 1243 | :104DA00065737320737065636966696564000D0AD5 | ||
| 1244 | :104DB0003A000D0A004C6F633D000D0A4641544114 | ||
| 1245 | :104DC0004C204552524F523D000D0A4D6F6E697492 | ||
| 1246 | :104DD0006F7220636F6D6D616E64733A2D0D0A20E2 | ||
| 1247 | :104DE0002020442C645B5B787878783A5D7878781A | ||
| 1248 | :104DF000785D202D2064756D70206D656D6F727902 | ||
| 1249 | :104E00000D0A2020204C2C6C5B5B787878783A5D1A | ||
| 1250 | :104E1000787878785D202D2064756D702073696EC8 | ||
| 1251 | :104E2000676C65206C696E650D0A202020452C6535 | ||
| 1252 | :104E30005B5B787878783A5D787878785D202D209B | ||
| 1253 | :104E400065646974206D656D6F72790D0A2020208C | ||
| 1254 | :104E5000462C665B5B78787878205D787878785D2A | ||
| 1255 | :104E6000202D2066696C6C206D656D6F72792070E5 | ||
| 1256 | :104E70006172616772617068730D0A202020495B5E | ||
| 1257 | :104E8000787878785D202020202020202020202D78 | ||
| 1258 | :104E900020776F726420696E7075742066726F6D12 | ||
| 1259 | :104EA00020706F72740D0A202020695B7878787802 | ||
| 1260 | :104EB0005D202020202020202020202D20627974B9 | ||
| 1261 | :104EC0006520696E7075742066726F6D20706F72E8 | ||
| 1262 | :104ED000740D0A2020204F78787878207878202068 | ||
| 1263 | :104EE000202020202020202D206F757470757420C4 | ||
| 1264 | :104EF000776F726420746F20706F72740D0A2020B7 | ||
| 1265 | :104F0000206F787878782078782020202020202042 | ||
| 1266 | :104F100020202D206F75747075742062797465205F | ||
| 1267 | :104F2000746F20706F72740D0A202020475B5B78CD | ||
| 1268 | :104F30007878783A5D787878785D2020202D206721 | ||
| 1269 | :104F40006F746F20616464726573730D0A20202092 | ||
| 1270 | :104F5000575B5B787878783A5D787878785D202050 | ||
| 1271 | :104F6000202D207761746368206120776F72640D53 | ||
| 1272 | :104F70000A20202043202020202020202020202024 | ||
| 1273 | :104F800020202020202D20696E7465727275707447 | ||
| 1274 | :104F900073206F66660D0A202020532020202020D9 | ||
| 1275 | :104FA00020202020202020202020202D20696E7409 | ||
| 1276 | :104FB00065727275707473206F6E0D0A20202073F5 | ||
| 1277 | :104FC00020202020202020202020202020202020E1 | ||
| 1278 | :104FD0002D2073696E676C6520737465700D0A20EF | ||
| 1279 | :104FE000202042787878782020202020202020203F | ||
| 1280 | :104FF0002020202D20627265616B706F696E7420B5 | ||
| 1281 | :105000007365740D0A20202062202020202020209B | ||
| 1282 | :105010002020202020202020202D20627265616B1E | ||
| 1283 | :10502000706F696E7420636C6561720D0A202020B8 | ||
| 1284 | :10503000522020202020202020202020202020203E | ||
| 1285 | :10504000202D207265737461727420627265616BC9 | ||
| 1286 | :10505000706F696E740D0A2020207220202020209D | ||
| 1287 | :1050600020202020202020202020202D2072656755 | ||
| 1288 | :105070006973746572732061742062726B70740D51 | ||
| 1289 | :105080000A202020582C78206E202020202020204C | ||
| 1290 | :1050900020202020202D206578616D696E652063B9 | ||
| 1291 | :1050A00068616E6E656C206E0D0A202020482C3FD2 | ||
| 1292 | :1050B00020202020202020202020202020202D20E3 | ||
| 1293 | :1050C00074686973206D657373616765001B5B327B | ||
| 1294 | :1050D0004A1B5B313B3148414E5349205465726D48 | ||
| 1295 | :1050E000696E616C0D0A0A001B5B4B001B5B4A007A | ||
| 1296 | :1050F0001B5B324A1B5B313B3148001B5B44201B6E | ||
| 1297 | :105100005B44001B5B313B373248001B5B003B00BC | ||
| 1298 | :1051100048001B5B73001B5B75001B7A2B0B7F1B0E | ||
| 1299 | :105120007A2E0C7F1B7A2D087F1B7A2C0A7F1B7A24 | ||
| 1300 | :1051300022087F1A57797365203330205465726DC9 | ||
| 1301 | :10514000696E616C0D0A001B54001B59001A001E89 | ||
| 1302 | :105150000008200800001B3D0000001B46000D0059 | ||
| 1303 | :105160003F4464456546664767486849694F6F43F1 | ||
| 1304 | :1051700063537342625272577758784C6C3C60D4D8 | ||
| 1305 | :1051800057D45750585058D659D659B459B4593C99 | ||
| 1306 | :10519000603C606C57485726570657905790579871 | ||
| 1307 | :1051A00057485F0C5F585F335F405FA057A057FEC2 | ||
| 1308 | :1051B00059FE59DC57DC5788619861C061CC61D8D1 | ||
| 1309 | :1051C00061F66102622262F8564A625862605920B2 | ||
| 1310 | :1051D00020666C6167733D00202061783D002020CF | ||
| 1311 | :1051E00062783D00202063783D00202064783D00F7 | ||
| 1312 | :1051F000202063733D00202064733D0020206573F0 | ||
| 1313 | :105200003D00202073733D00202064693D00202074 | ||
| 1314 | :1052100073693D00202062703D00202073703D00C6 | ||
| 1315 | :10522000202069703D00206368616E656C3D002040 | ||
| 1316 | :105230002020207365673D002074695F7374723DA0 | ||
| 1317 | :10524000002074695F746F733D002074695F6D6145 | ||
| 1318 | :10525000783D002074695F6261733D002074695F6E | ||
| 1319 | :1052600073697A3D002074695F7374663D00207431 | ||
| 1320 | :10527000695F726F6F3D002074695F666C673D0007 | ||
| 1321 | :105280002074695F746F743D002072695F70636E93 | ||
| 1322 | :105290003D002072695F7374723D002072695F7314 | ||
| 1323 | :1052A00074663D002072695F726F6F3D0020726905 | ||
| 1324 | :1052B0005F6261733D002072695F73697A3D00200F | ||
| 1325 | :1052C00072695F746F743D002072695F6D696E3D35 | ||
| 1326 | :1052D000002072695F666C673D002072695F746FC1 | ||
| 1327 | :1052E000733D002072695F7468723D002074685FCE | ||
| 1328 | :1052F0007374663D002074685F7374723D0020749F | ||
| 1329 | :10530000685F6261733D002074685F73697A3D0075 | ||
| 1330 | :105310002074685F7472673D002074685F666C6714 | ||
| 1331 | :105320003D002074685F636E743D002072685F7397 | ||
| 1332 | :1053300074723D002072685F7374663D002072686D | ||
| 1333 | :105340005F6261733D002072685F73697A3D00207F | ||
| 1334 | :1053500072685F7370613D002072685F61736F3DBA | ||
| 1335 | :10536000002072685F726F6F3D002072685F666C2C | ||
| 1336 | :10537000673D00206D5F636172653D002070745F62 | ||
| 1337 | :10538000666C6F3D002061735F666C6F3D0020723C | ||
| 1338 | :105390006D5F666C6F3D00202020715F696E3D007F | ||
| 1339 | :1053A0002020715F6F75743D0020715F6472616EC3 | ||
| 1340 | :1053B0003D002020715F74696D3D00202020715FE9 | ||
| 1341 | :1053C00066633D0020715F737461743D0020715FFE | ||
| 1342 | :1053D000646174613D0020715F6D6F646D3D0020FC | ||
| 1343 | :1053E00068616E645F6F3D002068616E645F623D5E | ||
| 1344 | :1053F000002068616E645F653D002068616E645FD7 | ||
| 1345 | :10540000693D0020206F706F73743D002020746927 | ||
| 1346 | :105410006D656F3D0020637573746D313D002063D1 | ||
| 1347 | :105420007573746D323D0020637573746D643D0057 | ||
| 1348 | :10543000207478726174653D0020727872617465C1 | ||
| 1349 | :105440003D002020635F6D61703D0020635F6164FB | ||
| 1350 | :1054500064723D0020635F616973723D0020635F89 | ||
| 1351 | :10546000787461673D0020635F646566723D00206B | ||
| 1352 | :10547000635F666C73683D002074786D6178733D7E | ||
| 1353 | :10548000002072695F656D733D002020635F6C735F | ||
| 1354 | :10549000723D002020635F6965723D002020635FDC | ||
| 1355 | :1054A0006663723D002020635F6D63723D002020C3 | ||
| 1356 | :1054B000635F6C63723D002020635F6473733D0023 | ||
| 1357 | :1054C00020635F647373693D0020635F647373726C | ||
| 1358 | :1054D0003D002020635F6973723D002020635F639D | ||
| 1359 | :1054E00061723D002020635F6566723D0020635F4E | ||
| 1360 | :1054F000657273743D0020635F65636E743D0020C8 | ||
| 1361 | :10550000635F62726B633D0020635F626F6B633D3C | ||
| 1362 | :105510000020635F7265706C3D0020635F6363739E | ||
| 1363 | :10552000723D0020635F737474313D0020635F73CC | ||
| 1364 | :105530007474323D002BC08ED88EC0E8C200E8E5FE | ||
| 1365 | :1055400000FABF8400C705DC568C4D02BF0C00C7B3 | ||
| 1366 | :10555000056E5E8C4D02BF0400C705BA5E8C4D021D | ||
| 1367 | :10556000E8F10090E84901E81600F490E8E500BE93 | ||
| 1368 | :10557000BA4DE8090CA09312E85D0CE8C209EBE40F | ||
| 1369 | :10558000E8D50CE8C40C0AC074F68B1EF8793C0D03 | ||
| 1370 | :10559000742E3C0874173C7F741383FB207FE188D2 | ||
| 1371 | :1055A00087D67943891EF879E8770CEBD30BDB7447 | ||
| 1372 | :1055B000CF4B891EF8798B36167AE8C10BEBC19078 | ||
| 1373 | :1055C000E80200EBBBC687D679000BDB741EA0D6C1 | ||
| 1374 | :1055D00079BF6051B91D008BD9060E07F2AE077571 | ||
| 1375 | :1055E00017412BD9D1E32EFF977D519033C0A3F8FB | ||
| 1376 | :1055F00079BE894DE8870BC3BE8D4DE8800BEBEC7F | ||
| 1377 | :10560000BA0002B093EEB055EEBA1002B093EEB00D | ||
| 1378 | :10561000AAEEBA0002EC3C557508BA1002EC3CAA9E | ||
| 1379 | :105620007403E82FF6C3BA0402B01AEEB020EEB04D | ||
| 1380 | :1056300030EEB040EEB080EEBA0002B013EEB0072C | ||
| 1381 | :10564000EEBA0802B080EEBA0202B0BBEEBA0402B3 | ||
| 1382 | :10565000B005EEC3C606CA1301C706F8790000C636 | ||
| 1383 | :1056600006F67901C706D0790000C706D279000096 | ||
| 1384 | :10567000C706D4790000C706FA790000C706FC798E | ||
| 1385 | :105680000000C706FE790000C706007A0000C706C2 | ||
| 1386 | :10569000027ACE598C0E047AC706067A0000C70635 | ||
| 1387 | :1056A000277A0000C606297A00C6062A7A00C39027 | ||
| 1388 | :1056B000BE224DE8C80AE83F002C313C0177F7E8EC | ||
| 1389 | :1056C00081098B360C7AE8B50ABE6A4DE8AF0A0E3E | ||
| 1390 | :1056D00058E8F80ABE7A4DE8A40AC39060D1E38383 | ||
| 1391 | :1056E000FB1873111EBA00008EDA2EFF97B7518B8C | ||
| 1392 | :1056F000EC8946101F61CF90E84F0B0AC07505E892 | ||
| 1393 | :10570000560BEBF4C390833EF879017416BED7793B | ||
| 1394 | :10571000E8310A8BD0AC3C2C74043C207505E8239E | ||
| 1395 | :105720000AEEC3E9D2FE833EF8790174F6BED7795A | ||
| 1396 | :10573000E8110A8BD0AC3C2C74083C207404E9B707 | ||
| 1397 | :10574000FE90E8FF09EFC3908B16067A833EF87946 | ||
| 1398 | :1057500001740BBED779E8EB098BD0A3067AB02091 | ||
| 1399 | :10576000E8570B8B16067AECE86F0BC38B16067A9C | ||
| 1400 | :10577000833EF87901740BBED779E8C7098BD0A3B3 | ||
| 1401 | :10578000067AB020E8330B8B16067AEDE8670BC378 | ||
| 1402 | :10579000FAC606F67900C390C606F67901FBC390F7 | ||
| 1403 | :1057A00006E85809B020E8110B268B05E8470BB036 | ||
| 1404 | :1057B00008E8060BE8030BE8000BE8FD0AB8010057 | ||
| 1405 | :1057C000E8CFF4BA0202EC24017502EBDCBA06025F | ||
| 1406 | :1057D000EC07C390C706087A1000EB06C706087AE4 | ||
| 1407 | :1057E0000100068E06FC798B3EFA79E80E09E80B7B | ||
| 1408 | :1057F00000893EFA798C06FC7907C390BEB24DE869 | ||
| 1409 | :105800007C098B16087A52E82A09E80F0AE80C0A84 | ||
| 1410 | :1058100033DBB9100090268A01E8BC09E8FD094392 | ||
| 1411 | :10582000E2F4E8F709E8F40933DBB9100090268ABE | ||
| 1412 | :10583000013C2072053C7E760390B02EE8E30943DC | ||
| 1413 | :10584000E2ECBEB24DE8360983C7105A4A75B7C3B9 | ||
| 1414 | :10585000068E06007A8B3EFE79E8A008893EFE7926 | ||
| 1415 | :105860008C06007A578B360E7AE81209C706087A3A | ||
| 1416 | :105870001000BA0002E8E800E881FF5FBA0000E823 | ||
| 1417 | :10588000DE00BEB54DE8F6088CC0E83F09B03AE846 | ||
| 1418 | :1058900090098BC7E83509E87E08E8C30090E8B7AF | ||
| 1419 | :1058A00009E8A6090AC074F63C0B750683EF10EBF5 | ||
| 1420 | :1058B00019903C0A750683C710EB0F903C0C7504D9 | ||
| 1421 | :1058C00047EB07903C0875244F908B36FE798BC7C9 | ||
| 1422 | :1058D0002BC63D000172A53D1001720483EE20909D | ||
| 1423 | :1058E00083C6108936FE79578BFEEB803C2E7508F7 | ||
| 1424 | :1058F000BA0113E86A0007C3C6060A7A0232C990E1 | ||
| 1425 | :105900003C30724C3C39760C245F3C4172423C4640 | ||
| 1426 | :10591000773E2C072C3050E8CC085802C8FE0E0AFF | ||
| 1427 | :105920007A740FC0E104E82F09E81E090AC074F672 | ||
| 1428 | :10593000EBCE26880DE8E0078AD0E823008AC13C38 | ||
| 1429 | :105940002072053C7E760390B02EE8D508E970FF02 | ||
| 1430 | :10595000E8C507E80A00268A05E87C08E91DFF90EB | ||
| 1431 | :10596000F606267A02750286F2528B361A7AE80D0E | ||
| 1432 | :10597000085A528AC60206247AF606267A01750665 | ||
| 1433 | :10598000E89F08EB0D9032E4E80D088B361C7AE8AE | ||
| 1434 | :10599000EC075A8AC20206257AF606267A017506AF | ||
| 1435 | :1059A000E87F08EB069032E4E8ED078B361E7AE8D4 | ||
| 1436 | :1059B000CC07C390068E06047A8B3E027AE83C0739 | ||
| 1437 | :1059C000893E027A8C06047A07FF1E027AC3BE97CC | ||
| 1438 | :1059D0004DE8AA07CB900657BED779E866078BD863 | ||
| 1439 | :1059E000E861078BC82BCB78118EC3BF0000B8FFCE | ||
| 1440 | :1059F000FF51B90800F3AB59E2F75F07C39006BE49 | ||
| 1441 | :105A0000D779E83F078BD8D1E32E8B9F4400BE2681 | ||
| 1442 | :105A100052E8F1088BC3E8DD08B80100E873F2E84A | ||
| 1443 | :105A2000E008BE2F52E8DD088B4718E8C808BE77AB | ||
| 1444 | :105A300052E8D1088B4726E8BC08BE5352E8C50897 | ||
| 1445 | :105A40008B471EE8B008BE5C52E8B9088B4720E8D7 | ||
| 1446 | :105A5000A408BE6E52E8AD088B4724E89808BE80C3 | ||
| 1447 | :105A600052E8A1088B472AE88C08E89508BE38520E | ||
| 1448 | :105A7000E892088B07E87E08BE4152E887088B470A | ||
| 1449 | :105A80001AE87208BE4A52E87B088B471CE8660891 | ||
| 1450 | :105A9000BE6552E86F088B4722E85A08E86308BEE3 | ||
| 1451 | :105AA000D152E860088B4738E84B08BEAD52E85445 | ||
| 1452 | :105AB000088B4730E83F08BEB652E848088B4732AB | ||
| 1453 | :105AC000E83308BEA452E83C088B472EE82708BEFE | ||
| 1454 | :105AD000BF52E830088B4734E81B08E82408BE8929 | ||
| 1455 | :105AE00052E821088B4704E80C08BE9252E81508DA | ||
| 1456 | :105AF0008B4714E80008BE9B52E809088B472CE846 | ||
| 1457 | :105B0000F407BEC852E8FD078B4736E8E807BEDA5F | ||
| 1458 | :105B100052E8F1078B473AE8DC07BEE352E8E507B5 | ||
| 1459 | :105B20008B473CE8D007E8D907BE1953E8D6078B66 | ||
| 1460 | :105B30004748E8C107BEFE52E8CA078B4742E8B5AE | ||
| 1461 | :105B400007BE0753E8BE078B4744E8A907BE7C534E | ||
| 1462 | :105B5000E8B2078B474CE89D07BE8553E8A6078B44 | ||
| 1463 | :105B6000474EE89107BE8E53E89A078B4750E88569 | ||
| 1464 | :105B700007E88E07BE2253E88B078B474AE8760773 | ||
| 1465 | :105B8000BEEC52E87F078B4708E86A07BEF552E88B | ||
| 1466 | :105B900073078B4740E85E07BE1053E867078B47E3 | ||
| 1467 | :105BA00046E85207E85B07BE6A53E858078B477A16 | ||
| 1468 | :105BB000E84307BE3D53E84C078B4770E83707BE04 | ||
| 1469 | :105BC0004653E840078B4772E82B07BE4F53E83433 | ||
| 1470 | :105BD000078B4774E81F07E82807BE2B53E8250703 | ||
| 1471 | :105BE0008B470CE81007BE3453E819078B4710E8C1 | ||
| 1472 | :105BF0000407BE5853E80D078B4776E8F806BE61E8 | ||
| 1473 | :105C000053E801078B4778E8EC06BE7353E8F506C6 | ||
| 1474 | :105C10008B473EE8E006E8E906BE9753E8E6068BC8 | ||
| 1475 | :105C20004752E8D106BEA053E8DA068B4754E8C5D0 | ||
| 1476 | :105C300006BEA953E8CE068B4756E8B906BEB25356 | ||
| 1477 | :105C4000E8C2068B4758E8AD06BEBB53E8B6068BE4 | ||
| 1478 | :105C5000475AE8A106BEC453E8AA068B475CE895FC | ||
| 1479 | :105C600006E89E06BECD53E89B068B475EE8860697 | ||
| 1480 | :105C7000BED653E88F068B4760E87A06BEDF53E84E | ||
| 1481 | :105C800083068B4762E86E06BEE853E877068B47CB | ||
| 1482 | :105C90007CE86206BEF153E86B068B477EE8560649 | ||
| 1483 | :105CA000BEFA53E85F068B878000E84906E8520693 | ||
| 1484 | :105CB000BE4254E84F068B879E00E83906BE035467 | ||
| 1485 | :105CC000E842068B4764E82D06BE0C54E836068B86 | ||
| 1486 | :105CD000476EE82106BE1554E82A068B878E00E839 | ||
| 1487 | :105CE0001406BE1E54E81D068B879000E80706BE0A | ||
| 1488 | :105CF0002754E810068B879200E8FA05E80306BEF1 | ||
| 1489 | :105D00003054E800068B879400E8EA05BE3954E871 | ||
| 1490 | :105D1000F3058B879600E8DD05BE6F54E8E6058B3A | ||
| 1491 | :105D2000879800E8D005BE5D54E8D9058A87A000B1 | ||
| 1492 | :105D3000E8A705BE5454E8CC058A4728E89B05BE71 | ||
| 1493 | :105D40006654E8C0058A87A100E88E05E8B305BE61 | ||
| 1494 | :105D50007854E8B0058A87A200E87E05BE8154E841 | ||
| 1495 | :105D6000A3058A87A300E87105BE8A54E896058AD0 | ||
| 1496 | :105D700087A400E86405BE9354E889058A87A500D6 | ||
| 1497 | :105D8000E85705BE9C54E87C058A87A600E84A05CA | ||
| 1498 | :105D9000BEA554E86F058A87A700E83D05BEAE544E | ||
| 1499 | :105DA000E862058A87A800E83005E85505BEB754C3 | ||
| 1500 | :105DB000E852058A87A900E82005BEC054E84505D9 | ||
| 1501 | :105DC0008A87AA00E81305BEC954E838058A87AB5C | ||
| 1502 | :105DD00000E80605BED254E82B058A87AD00E8F935 | ||
| 1503 | :105DE00004BEDB54E81E058A87AE00E8EC04BEE47E | ||
| 1504 | :105DF00054E811058A87AF00E8DF04BEED54E804DB | ||
| 1505 | :105E0000058A87B000E8D204E8F704BEF654E8F447 | ||
| 1506 | :105E1000048A87B100E8C204BEFF54E8E7048A8719 | ||
| 1507 | :105E2000B200E8B504BE0855E8DA048A87B300E892 | ||
| 1508 | :105E3000A804BE1155E8CD048A87BB00E89B04E89E | ||
| 1509 | :105E4000C004BE1A55E8BD048A87BC00E88B04BEB6 | ||
| 1510 | :105E50002355E8B0048A87BE00E87E04BE2C55E8CE | ||
| 1511 | :105E6000A3048A87BF00E87104E8960407C36006AC | ||
| 1512 | :105E70001E168BECFF4E16F7461A00027401FBB893 | ||
| 1513 | :105E800000008ED88EC0892E2D7AE8CB0081661A4C | ||
| 1514 | :105E9000FFFEC6062A7A00E8D800B8005FA32B7A76 | ||
| 1515 | :105EA000E85D00803E2A7A00740A814E1A0001C61D | ||
| 1516 | :105EB000062A7A00171F0761CF9060061E168BEC2A | ||
| 1517 | :105EC000F7461A00027401FBB800008ED88EC08914 | ||
| 1518 | :105ED0002E2D7A81661AFFFEC6062A7A00E8920005 | ||
| 1519 | :105EE000B8005FA32B7AE81700803E2A7A00740A74 | ||
| 1520 | :105EF000814E1A0001C6062A7A00171F0761CF904B | ||
| 1521 | :105F0000B8F000E88CEDFF262B7AC390065356803C | ||
| 1522 | :105F10003E297A007403E83F00BED779E825028B5A | ||
| 1523 | :105F2000D8A3277A2E8A07A2297AB0CC2E88075EBA | ||
| 1524 | :105F30005B07C3C6062A7A00B80A5FA32B7AC39010 | ||
| 1525 | :105F40008B2E2D7AE82B00C3C6062A7A01E80800BA | ||
| 1526 | :105F5000B80A5FA32B7AC39057803E297A00740F4A | ||
| 1527 | :105F60008B3E277AA0297A2E8805C606297A005FFB | ||
| 1528 | :105F7000C390BEB24DE80602BED851E80002FF76DB | ||
| 1529 | :105F80001458E84702BEDE51E8F301FF760E58E8E8 | ||
| 1530 | :105F90003A02BEE451E8E601FF761258E82D02BE4F | ||
| 1531 | :105FA000EA51E8D901FF761058E82002BE1452E801 | ||
| 1532 | :105FB000CC01FF760A58E81302BE1A52E8BF01FF6F | ||
| 1533 | :105FC000760C58E80602BECF51E8B201FF761A58A7 | ||
| 1534 | :105FD000E8F901BEB24DE8A501BEF051E89F01FF0E | ||
| 1535 | :105FE000761858E8E601BEF651E89201FF760258AD | ||
| 1536 | :105FF000E8D901BEFC51E88501FF760458E8CC01E0 | ||
| 1537 | :10600000BE0252E87801FF760058E8BF01BE085290 | ||
| 1538 | :10601000E86B01FF760658E8B201BE0E52E85E0159 | ||
| 1539 | :10602000FF760858E8A501BE2052E85101FF761618 | ||
| 1540 | :1060300058E89801BE894DE84401C390BEC94DE8B7 | ||
| 1541 | :106040003C01C33C0074053C017459C3C7060C7A7B | ||
| 1542 | :10605000CD50C7060E7AF050C706107AE850C70632 | ||
| 1543 | :10606000127AEC50C706147AF450C706167AFB5021 | ||
| 1544 | :10607000C706187A0351C7061A7A0B51C7061C7A4D | ||
| 1545 | :106080000E51C7061E7A1051C706207A1251C70654 | ||
| 1546 | :10609000227A1651C606247A01C606257A01C6065A | ||
| 1547 | :1060A000267A03C3C7060C7A1A51C7060E7A4D51D9 | ||
| 1548 | :1060B000C706107A4751C706127A4A51C706147AA2 | ||
| 1549 | :1060C0004F51C706167A5151C706187A5551C7065F | ||
| 1550 | :1060D0001A7A5651C7061C7A5951C7061E7A5A5168 | ||
| 1551 | :1060E000C706207A5B51C706227A5E51C606247A1B | ||
| 1552 | :1060F00020C606257A20C606267A02C3A1F879486A | ||
| 1553 | :106100007414BED779E83C008BF8AC3C3A75078E26 | ||
| 1554 | :10611000C7E830008BF8C3908BC72B06FE798AF056 | ||
| 1555 | :10612000240F8AD002D002D080C20BC0EE0480C6F9 | ||
| 1556 | :1061300003043DC38CC0E89300B03AE8E4008BC789 | ||
| 1557 | :10614000E88900C35133C990AC3C2074FB900AC06D | ||
| 1558 | :1061500074262C3072223C0976143C11721A2C07DA | ||
| 1559 | :106160003C0F760A3C2A72102C203C0F770A98C10B | ||
| 1560 | :10617000E10403C8ACEBD7904E8BC159C390068C99 | ||
| 1561 | :10618000C88EC0E8020007C3268A04460AC0740607 | ||
| 1562 | :10619000E88F00EBF390C3900BC0747A5133D2B9FF | ||
| 1563 | :1061A000E803F7F18BCAE803008BC159BA6400F623 | ||
| 1564 | :1061B000F2E80C008AC498B20AF6F2E802008AC437 | ||
| 1565 | :1061C000500AF074050430E8580058C386C4E80744 | ||
| 1566 | :1061D0000086C4E80200C390C1C804E80800C1C03A | ||
| 1567 | :1061E00004E80200C3905350240FBBCA622ED7E8C4 | ||
| 1568 | :1061F0003000585BC39086C4E8070086C4E80200FC | ||
| 1569 | :10620000C39050B908008AE032C0D1C00430E81110 | ||
| 1570 | :1062100000E2F558C390B030E80700C3B020E801B1 | ||
| 1571 | :1062200000C3568B36D0798884D0774681E6FF014B | ||
| 1572 | :10623000FF06D4798936D079813ED479FE0175087C | ||
| 1573 | :1062400056E814005EEBF1905EC3BA0202EC240142 | ||
| 1574 | :106250007404BA0602ECC390803EF67900740960BB | ||
| 1575 | :10626000B80100E82CEA6190BA0202ECA804742894 | ||
| 1576 | :106270008B36D279833ED47900741D8A84D07746D8 | ||
| 1577 | :1062800081E6FF018936D279FF0ED479BA0602EE93 | ||
| 1578 | :10629000BA0202ECA80475DCA1D479C352BA060292 | ||
| 1579 | :1062A000EE5AC3905250BA0202ECA8047408585A2D | ||
| 1580 | :1062B000E8E9FFF9C390585AF8C35250BA0202EC09 | ||
| 1581 | :1062C000A80474FB585AE8D3FFC330313233343555 | ||
| 1582 | :1062D0003637383941424344454653508AE080E4DA | ||
| 1583 | :1062E0000FBBCA62C0E8042ED7E8CEFF8AC42ED7FF | ||
| 1584 | :1062F000E8C7FF585BC386E0E8DFFF86E0E8DAFF27 | ||
| 1585 | :10630000C390BEB24D502EAC3C007405E8ABFFEB21 | ||
| 1586 | :10631000F558C390C808000056578B7604BF040098 | ||
| 1587 | :10632000C746FC0000C746FA0000C746F8000083D5 | ||
| 1588 | :106330007E0600750E56E8B60E590BC075058BC764 | ||
| 1589 | :10634000E95B018B46FC8946FE0BFF7505B8010031 | ||
| 1590 | :10635000EB0233C05056E8A40D5959B4008946FCED | ||
| 1591 | :106360008B5EFC83FB087603E92B01D1E32EFFA7AC | ||
| 1592 | :10637000B264B80300E92601837EFA007414C746AC | ||
| 1593 | :10638000FA00008A445898508A44599850E8C20F3D | ||
| 1594 | :106390005959837EF800740AC746F8000056E89BF6 | ||
| 1595 | :1063A0000859837E060075058BC7E9F10083FF0459 | ||
| 1596 | :1063B0007503E9E6008BC7E9E400837EFE00750300 | ||
| 1597 | :1063C000BF0200E9D500837EFE007503BF0100E92E | ||
| 1598 | :1063D000C9008B5EFE83FB077603E98600D1E32EBE | ||
| 1599 | :1063E000FFA7A26433FFE97F00BF0400807C580F41 | ||
| 1600 | :1063F0007422837EF800751CFE44586A0856E87EB5 | ||
| 1601 | :106400000C59598A445804805056E8720C5959C79F | ||
| 1602 | :1064100046FA0100837EF800740AC746F800005669 | ||
| 1603 | :10642000E8190859EB42BF0400807C5800742283AD | ||
| 1604 | :106430007EF800751CFE4C586A0856E8410C595904 | ||
| 1605 | :106440008A445804805056E8350C5959C746FA0119 | ||
| 1606 | :1064500000837EF800740AC746F8000056E8DC079F | ||
| 1607 | :1064600059EB05BF0400EB00EB31BF0400EB2CC778 | ||
| 1608 | :1064700046F801006A0856E8050C5959807C58090D | ||
| 1609 | :106480007D04B00FEB02B00004805056E8F00B59C9 | ||
| 1610 | :1064900059BF0400EB05BF0400EB00E9A5FE5F5EF9 | ||
| 1611 | :1064A000C9C3E4636364636463646364E963266427 | ||
| 1612 | :1064B00051647863BA63C6639664D2636A646A643B | ||
| 1613 | :1064C0006F647263C808000056578B76048B7E0891 | ||
| 1614 | :1064D0006A0156E8A90B59598A4606C0E0060480AD | ||
| 1615 | :1064E0005056E89A0B5959C746FE0000897EF8EBD2 | ||
| 1616 | :1064F00003FF46FE8B5EF8FF46F8803F0075F2838F | ||
| 1617 | :106500007EFE107D25B810002B46FED1F88946FC92 | ||
| 1618 | :10651000C746FA0000EB0B6A2056E8620B5959FF98 | ||
| 1619 | :1065200046FA8B46FA3B46FC7CEDEB0C8BDF478A48 | ||
| 1620 | :10653000075056E8490B5959803D0075EF6A0256DD | ||
| 1621 | :10654000E83C0B5959EB005F5EC9C3C80400005614 | ||
| 1622 | :10655000578B7E04C746FE0000BE1400E909018B7C | ||
| 1623 | :106560005EFE83C3042BDF8A87AC0B88445AC64483 | ||
| 1624 | :1065700058088A46FE884459C744060000C6441994 | ||
| 1625 | :1065800000C6441A00C6441B00C6441D0DC6441E66 | ||
| 1626 | :1065900003C6441F00C6442000C6442100C6445B15 | ||
| 1627 | :1065A00000C6445D00C6445E00C6445F00C6446049 | ||
| 1628 | :1065B00000C746FC0000EB0D8B5EFCD1E3C740300A | ||
| 1629 | :1065C0000000FF46FC837EFC107CEDC746FC00000B | ||
| 1630 | :1065D000EB0A8B5EFCC6405000FF46FC837EFC0449 | ||
| 1631 | :1065E0007CF0C744540000C7445600008A445A98BF | ||
| 1632 | :1065F000BAF80023D0B805000BC28946FC9CFA8A81 | ||
| 1633 | :1066000046FCBAFE00EEBA0000EC9D24088846FC69 | ||
| 1634 | :10661000837EFC007502EB4AFF76FEE87A0C59682F | ||
| 1635 | :10662000350256E8320A59590BC07534683802569B | ||
| 1636 | :10663000E8250A59590BC0752768420256E8180A1E | ||
| 1637 | :1066400059590BC0751A684C0256E80B0A59590B78 | ||
| 1638 | :10665000C0750D68560256E8FE0959590BC0740200 | ||
| 1639 | :10666000EB00FF46FE83C662397EFE7D03E9EFFE46 | ||
| 1640 | :10667000EB005F5EC9C3C808000056578B4604BADA | ||
| 1641 | :106680006200F7EA0514008BF0837E06007405B8FB | ||
| 1642 | :106690001000EB03B808008944048A460888445C6B | ||
| 1643 | :1066A00056E85904598BF88BC78944568944548A53 | ||
| 1644 | :1066B000445D88442F0BFF751D68C20F6A0156E8C0 | ||
| 1645 | :1066C00002FE83C406EB006A0156E847FC59590BE9 | ||
| 1646 | :1066D000C075F4BF0100897EFAB90500BBE96A2ED6 | ||
| 1647 | :1066E0008B073B46FA74074343E2F4E9A4032EFF09 | ||
| 1648 | :1066F000670AC744060200C74408F4088B5E04D149 | ||
| 1649 | :10670000E38B87FC0889440A33C08BF8894454E939 | ||
| 1650 | :10671000800356E8BB0559BF01008A445D88446088 | ||
| 1651 | :10672000E96F03837C04087530807C5C0175158AF1 | ||
| 1652 | :10673000445DB400D1E08BD8FFB7E40856E8F70811 | ||
| 1653 | :106740005959EB138A445DB400D1E08BD8FFB7C42C | ||
| 1654 | :106750000856E8E2085959EB2E807C5C0175158AD1 | ||
| 1655 | :10676000445DB400D1E08BD8FFB7D40856E8C70821 | ||
| 1656 | :106770005959EB138A445DB400D1E08BD8FFB7B40C | ||
| 1657 | :106780000856E8B20859596A0156E887FB59598BEF | ||
| 1658 | :10679000D883FB03772AD1E32EFFA7E16ABF01006C | ||
| 1659 | :1067A0008A445D88445EEB188A445D04FF240788B0 | ||
| 1660 | :1067B000445DEB0C8A445DFEC0240788445DEB0019 | ||
| 1661 | :1067C000E9CF028A445DB400D1E08BD8FFB7FD0267 | ||
| 1662 | :1067D00056E863085959681D0356E85A0859596A1A | ||
| 1663 | :1067E0000156E82FFB59598BD883FB037736D1E349 | ||
| 1664 | :1067F0002EFFA7D96ABF01008A445D88445FEB245D | ||
| 1665 | :106800008A445D04FF8A540480C2FF22C288445D2A | ||
| 1666 | :10681000EB128A445DFEC08A540480C2FF22C28803 | ||
| 1667 | :10682000445DEB00E96B028B5C0683C3FED1E38B16 | ||
| 1668 | :10683000400889048B1CFF77066A0056E885FC83B4 | ||
| 1669 | :10684000C4068B5C064BD1E38B40088944028B5C09 | ||
| 1670 | :1068500002FF77066A0156E86AFC83C4066A01569D | ||
| 1671 | :10686000E8B1FA59598BD883FB037603E91F02D1AB | ||
| 1672 | :10687000E32EFFA7D16A8B5C028B47048944028B0D | ||
| 1673 | :106880005C02803F44750D8B5C028A4701B4003B7B | ||
| 1674 | :1068900044047DE28B4604D1E08B1C03D88B440278 | ||
| 1675 | :1068A0008947088B5C064BD1E38B4402894008E999 | ||
| 1676 | :1068B000DE018B5C028B47028944028B5C02803FC5 | ||
| 1677 | :1068C00044750D8B5C028A4701B4003B44047DE2B1 | ||
| 1678 | :1068D0008B4604D1E08B1C03D88B44028947088B7C | ||
| 1679 | :1068E0005C064BD1E38B4402894008E9A201BF0159 | ||
| 1680 | :1068F00000E99C018B5C028A07B4008946F8B90C58 | ||
| 1681 | :1069000000BBA16A2E8B073B46F874074343E2F4B1 | ||
| 1682 | :10691000E977012EFF67188B4604D1E08B5C0203F8 | ||
| 1683 | :10692000D88B47088B5C06FF4406D1E38940088B6F | ||
| 1684 | :106930001C807F010074128B5C028A47018B1C8AC9 | ||
| 1685 | :106940005701B6008BDA884018E94001FF4C06E990 | ||
| 1686 | :106950003A018B5C028A47018B1C8A5701B6008B77 | ||
| 1687 | :10696000DA884018E925018B5C028A47018B1C8A72 | ||
| 1688 | :106970005701B6008BDA884018FF4C06E90D018BF1 | ||
| 1689 | :106980005C028A47018B1C8A5701B6008BDA3040C3 | ||
| 1690 | :1069900018E9F800B8F0108BF88944548A445F88ED | ||
| 1691 | :1069A000445DE9E7008A441C983D020074073D03FA | ||
| 1692 | :1069B000007402EB07C746FE0000EB2B8A441C98CC | ||
| 1693 | :1069C000D1E08BD8FFB7690256E86B0659596A01C6 | ||
| 1694 | :1069D00056E840F959598946FE837EFE00740683C5 | ||
| 1695 | :1069E0007EFE0375E9EB00837EFE0374628A441C1D | ||
| 1696 | :1069F00098D1E08BD8FFB76D0256E83A0659595640 | ||
| 1697 | :106A0000E84D97598946FC8B5EFC83EBFE83FB03C4 | ||
| 1698 | :106A10007733D1E32EFFA7996A68AC0256E81706D0 | ||
| 1699 | :106A20005959EB23688F0256E80C065959EB186840 | ||
| 1700 | :106A3000750256E801065959EB0D68C60256E8F68C | ||
| 1701 | :106A4000055959EB02EB006A0156E8C7F85959BFDE | ||
| 1702 | :106A50000100EB3868DD0256E8DC0559596A015639 | ||
| 1703 | :106A6000E8B1F85959BF0100EB22B8D0308BF88952 | ||
| 1704 | :106A700044548A446088445DEB12B8E0208BF88966 | ||
| 1705 | :106A800044548A445E88445DEB02EB00EB02EB0069 | ||
| 1706 | :106A9000EB00E941FC5F5EC9C3196A246A2F6A3AB8 | ||
| 1707 | :106AA0006A0000010002000400410042004300446B | ||
| 1708 | :106AB00000800081008200FF001769546A7A6AA58D | ||
| 1709 | :106AC00069526994696A6A676952697F6967694C42 | ||
| 1710 | :106AD00069F4687668B268EE68F56700681268F570 | ||
| 1711 | :106AE000679D67A867B4679D6700000100F010E02C | ||
| 1712 | :106AF00020D0302768F266C36723671267C8040096 | ||
| 1713 | :106B00000056578B76048A4459988946FC6A098B4B | ||
| 1714 | :106B100046FC05840150E8930859598BF88BC7252A | ||
| 1715 | :106B200000F03D001075558BC725F0003DF0007555 | ||
| 1716 | :106B30004B8BC725000FC1F8088946FE8B44043BE8 | ||
| 1717 | :106B400046FE7D0533C0E9EF008BC7250F00BA0F65 | ||
| 1718 | :106B5000002BD03B56FE740533C0E9DB00C744026E | ||
| 1719 | :106B600004098A46FE88445F88445D8B5EFCD1E35D | ||
| 1720 | :106B7000C787FC080409B8F010E9BC008BC72500E2 | ||
| 1721 | :106B8000F03D002075528BC725F0003DE0007548B0 | ||
| 1722 | :106B90008BC725000FC1F8088946FE837EFE087E5C | ||
| 1723 | :106BA0000533C0E992008BC7250F00BA0F002BD028 | ||
| 1724 | :106BB0003B56FE740533C0EB7F90C744020C098A34 | ||
| 1725 | :106BC00046FE88445E88445D8B5EFCD1E3C787FC4B | ||
| 1726 | :106BD000080C09B8E020EB608BC72500F03D0030C1 | ||
| 1727 | :106BE00075528BC725F0003DD00075488BC7250036 | ||
| 1728 | :106BF0000FC1F8088946FE8B44043B46FE7D0433F2 | ||
| 1729 | :106C0000C0EB358BC7250F00BA0F002BD03B56FECB | ||
| 1730 | :106C1000740433C0EB22C7440214098A46FE884438 | ||
| 1731 | :106C20006088445D8B5EFCD1E3C787FC081409B81B | ||
| 1732 | :106C3000D030EB0433C0EB005F5EC9C3C806000070 | ||
| 1733 | :106C4000568B76046A0856E8350459598A44580424 | ||
| 1734 | :106C5000805056E8290459598B44543B4456750AD0 | ||
| 1735 | :106C60008A445D3A442F7502EB648B445489445640 | ||
| 1736 | :106C70008B5C028A470188442F8A445DB400C1E0DE | ||
| 1737 | :106C8000088B54540BD08A445DB400BB0F002BD842 | ||
| 1738 | :106C90000BD38956FE6A108A445998050400990559 | ||
| 1739 | :106CA000400183D2005250E8540883C4068956FC40 | ||
| 1740 | :106CB0008946FA8B46FE0946FA834EFC006A19FFA4 | ||
| 1741 | :106CC00076FCFF76FAE8730783C406E8FE075EC920 | ||
| 1742 | :106CD000C3C81C000056578B5E048A4759988BF036 | ||
| 1743 | :106CE0008B5E048A475DB4008946E6837EE6007DBC | ||
| 1744 | :106CF0000A8B5E048B4704488946E68B5E048B470B | ||
| 1745 | :106D0000043B46E67F05C746E600008B5E048A46E4 | ||
| 1746 | :106D1000E688475D8BDED1E38B9F5902C647022090 | ||
| 1747 | :106D20008BDED1E38B9F5902C64703308BDED1E364 | ||
| 1748 | :106D30008B9F6102C64702208BDED1E38B9F6102ED | ||
| 1749 | :106D4000C64703308B46E68946FA837EFA007418FC | ||
| 1750 | :106D50008B46FABB0A0033D2F7F380C2308BDED108 | ||
| 1751 | :106D6000E38B9F5902885703BB0A008B46FA33D244 | ||
| 1752 | :106D7000F7F38946FA837EFA0074188B46FABB0A49 | ||
| 1753 | :106D80000033D2F7F380C2308BDED1E38B9F590200 | ||
| 1754 | :106D90008857028B46E68946FA837EFA0074188B80 | ||
| 1755 | :106DA00046FABB0A0033D2F7F380C2308BDED1E360 | ||
| 1756 | :106DB0008B9F6102885703BB0A008B46FA33D2F7D8 | ||
| 1757 | :106DC000F38946FA837EFA0074188B46FABB0A00F0 | ||
| 1758 | :106DD00033D2F7F380C2308BDED1E38B9F61028820 | ||
| 1759 | :106DE00057028B5EE6D1E3FFB712026A00FF76041A | ||
| 1760 | :106DF000E8D1F683C40668D30F6A01FF7604E8C3BE | ||
| 1761 | :106E0000F683C406FF76E656E8019359598956F28F | ||
| 1762 | :106E10008946F0FF76E656E8149359598956EE896B | ||
| 1763 | :106E200046EC9CFAC45EF0268B078946EAC45EEC09 | ||
| 1764 | :106E3000268B078946E8BA50FFED8946FE9DC74676 | ||
| 1765 | :106E4000E40100E8EEA0BA50FFED8946FC8B46FC59 | ||
| 1766 | :106E50002B46FE3DE8037303E980019CFABA50FF1C | ||
| 1767 | :106E6000ED8946FC8B46FC2B46FE8946F8C45EF055 | ||
| 1768 | :106E7000268B072B46EA8946F6C45EF0268B0789E7 | ||
| 1769 | :106E800046EAC45EEC268B072B46E88946F4C45ECE | ||
| 1770 | :106E9000EC268B078946E8BA50FFED8946FE9D81B6 | ||
| 1771 | :106EA0007EF8E803761CFF76F8FF76F6E87601595F | ||
| 1772 | :106EB000598946F6FF76F8FF76F4E8680159598952 | ||
| 1773 | :106EC00046F4BF0E00EB178BDED1E38B9F5902C651 | ||
| 1774 | :106ED00001208BDED1E38B9F6102C601204783FF37 | ||
| 1775 | :106EE0001176E48BDED1E38B9F5902C6470D308BC0 | ||
| 1776 | :106EF000DED1E38B9F6102C6470D30837EF60977B2 | ||
| 1777 | :106F000005B80D00EB26837EF6637705B80E00EB1F | ||
| 1778 | :106F10001B817EF6E7037705B80F00EB0F817EF645 | ||
| 1779 | :106F20000F277705B81000EB03B811008BF8EB259D | ||
| 1780 | :106F30008B46F6BB0A0033D2F7F380C2308BDED12A | ||
| 1781 | :106F4000E38B9F590288114FBB0A008B46F633D260 | ||
| 1782 | :106F5000F7F38946F6837EF60075D5837EF40977CC | ||
| 1783 | :106F600005B80D00EB26837EF4637705B80E00EBC1 | ||
| 1784 | :106F70001B817EF4E7037705B80F00EB0F817EF4E9 | ||
| 1785 | :106F80000F277705B81000EB03B811008BF8EB253D | ||
| 1786 | :106F90008B46F4BB0A0033D2F7F380C2308BDED1CC | ||
| 1787 | :106FA000E38B9F610288114FBB0A008B46F433D2FA | ||
| 1788 | :106FB000F7F38946F4837EF40075D58BDED1E3FFC9 | ||
| 1789 | :106FC000B75902FF7604E86E0059598BDED1E3FF12 | ||
| 1790 | :106FD000B76102FF7604E85E0059596A00FF760443 | ||
| 1791 | :106FE000E831F359598BD883FB04771FD1E32EFF87 | ||
| 1792 | :106FF000A71B70EB22C746E40000FF4EE6EB0CC770 | ||
| 1793 | :1070000046E40000FF46E6EB02EB00837EE40074FA | ||
| 1794 | :1070100003E92AFEE9D4FC5F5EC9C3F36FF56FFF95 | ||
| 1795 | :107020006FF36F0970558BEC8B4604B9E803F7E1F9 | ||
| 1796 | :107030008B4E06F7F15DC3558BEC568B7606EB0E47 | ||
| 1797 | :107040008BDE468A0750FF7604E833005959803CAE | ||
| 1798 | :107050000075EDEB005E5DC3558BEC568B7606EB51 | ||
| 1799 | :10706000148BDE468A0750FF7604E8450059590B19 | ||
| 1800 | :10707000C07402EB07803C0075E7EB005E5DC3C89F | ||
| 1801 | :10708000020000568B76048A445A988946FE9CFA80 | ||
| 1802 | :107090008A46FEBAFE00EEBA0200ECA80274069D13 | ||
| 1803 | :1070A000E8919EEBE9BA00008A4606EE9DEB005E91 | ||
| 1804 | :1070B000C9C3C8040000568B76048A445A9889468E | ||
| 1805 | :1070C000FEE8E6A18946FCE8E0A12B46FC3DB80BB2 | ||
| 1806 | :1070D0007605B80100EB239CFA8A46FEBAFE00EE64 | ||
| 1807 | :1070E000BA0200ECA80274069DE8489EEBD9BA00EB | ||
| 1808 | :1070F000008A4606EE9D33C0EB005EC9C3C804009B | ||
| 1809 | :107100000056578B7604837E0600740756E8030109 | ||
| 1810 | :1071100059EB0556E8A200598846FF807EFF0877A4 | ||
| 1811 | :10712000068A46FFE98400807EFF0F7603EB7990A4 | ||
| 1812 | :107130008A46FFB4002D0A008BD883FB047767D101 | ||
| 1813 | :10714000E32EFFA7AF71B000EB6156E86B0059B4B6 | ||
| 1814 | :1071500000250F008946FC56E85E0059B4008BF804 | ||
| 1815 | :1071600056E8550059B400C1E0088BD703D08BFA1C | ||
| 1816 | :107170008B5EFCD1E3897830EB2E56E83B005988D2 | ||
| 1817 | :10718000445BEB2456E831005988445056E8290006 | ||
| 1818 | :107190005988445156E821005988445256E819004C | ||
| 1819 | :1071A00059884453EB02EB00E95BFF5F5EC9C346BD | ||
| 1820 | :1071B00071A6714A717A718471C8040000568B7689 | ||
| 1821 | :1071C000048A445A988946FE9CFA8A46FEBAFE0012 | ||
| 1822 | :1071D000EEBA0200ECA80175069DE8579DEBE9BAEE | ||
| 1823 | :1071E0000000EC8846FD9D8A46FDEB005EC9C3C8E1 | ||
| 1824 | :1071F000020000568B76048A445A988946FE9CFA0F | ||
| 1825 | :107200008A46FEBAFE00EEBA0200EC32E424019D8A | ||
| 1826 | :107210005EC9C3C8060000568B76048A445A988912 | ||
| 1827 | :1072200046FEE885A08946FAE87FA02B46FA3DB8DD | ||
| 1828 | :107230000B7604B008EB249CFA8A46FEBAFE00EEF8 | ||
| 1829 | :10724000BA0200ECA80175069DE8E89CEBDABA00EA | ||
| 1830 | :1072500000EC8846FD9D8A46FDEB005EC9C3558B58 | ||
| 1831 | :10726000EC568B56048A4606EE33F6EB035058462E | ||
| 1832 | :1072700083FE147CF85E5DC3C8020000568B560482 | ||
| 1833 | :10728000EC8846FF33F6EB0350584683FE147CF837 | ||
| 1834 | :107290008A46FFEB005EC9C3C802000056578B76D2 | ||
| 1835 | :1072A00004833EB00B00751FBA8801B000EEBA86A9 | ||
| 1836 | :1072B00001B000EE6A096A00683001E87D0183C40C | ||
| 1837 | :1072C00006C706B00B01006A098BC605800150E8AD | ||
| 1838 | :1072D000DA0059598BF88BC7C1E80C250F00894695 | ||
| 1839 | :1072E000FE8BC7C1E808250F008B56FE83F20C3BCE | ||
| 1840 | :1072F000C275218BC7C1E804250F008B56FE83F2AF | ||
| 1841 | :10730000063BC2750F8BC7250F008B56FE83F20913 | ||
| 1842 | :107310003BC2740D6A0756E838005959C746FE0744 | ||
| 1843 | :10732000008A46FE0480A233028BC6BA6200F7EAE6 | ||
| 1844 | :107330008A56FE8BD888976C006832028BC6BA6278 | ||
| 1845 | :1073400000F7EA05140050E80EFD5959EB005F5EA6 | ||
| 1846 | :10735000C9C3C8020000568B760683E60F8BC6C1F0 | ||
| 1847 | :10736000E00C8BD683F20CC1E2080BC28BD683F201 | ||
| 1848 | :1073700006C1E2040BC28BD683F2090BC28946FE1A | ||
| 1849 | :107380006A196A108B46049905400183D200525055 | ||
| 1850 | :10739000E86B0183C4060B46FE83CA005250E89A8C | ||
| 1851 | :1073A0000083C406E82501EB005EC9C3558BEC568B | ||
| 1852 | :1073B0005733FF6A01688601E8A3FE5959B1102AC4 | ||
| 1853 | :1073C0004E06D3660433F6EB2E817E0400807204F1 | ||
| 1854 | :1073D000B001EB02B00050688801E881FE59596A9B | ||
| 1855 | :1073E00003688601E877FE59596A01688601E86DED | ||
| 1856 | :1073F000FE5959D16604463B76067CCD33F6EB2424 | ||
| 1857 | :10740000D1E76A03688601E854FE59596A01688623 | ||
| 1858 | :1074100001E84AFE5959688801E85CFE599825013F | ||
| 1859 | :10742000000BF84683FE107CD76A00688601E82DC1 | ||
| 1860 | :10743000FE59598BC7EB005F5E5DC3558BEC565709 | ||
| 1861 | :107440008B7E086A01688601E813FE5959B820004E | ||
| 1862 | :107450002BC750FF7606FF7604E8A20083C4068996 | ||
| 1863 | :10746000560689460433F6EB47817E060080720C8F | ||
| 1864 | :107470007506837E04007204B001EB02B000506810 | ||
| 1865 | :107480008801E8D9FD59596A03688601E8CFFD599A | ||
| 1866 | :10749000596A01688601E8C5FD59596A01FF7606F7 | ||
| 1867 | :1074A000FF7604E8580083C40689560689460446D8 | ||
| 1868 | :1074B0003BF77CB56A00688601E8A2FD59596A006D | ||
| 1869 | :1074C000688601E898FD59595F5E5DC3558BEC569F | ||
| 1870 | :1074D0006A01688601E886FD595933F6EB00688831 | ||
| 1871 | :1074E00001E894FD59A80175088BC6463D64007CEF | ||
| 1872 | :1074F000ED6A00688601E865FD59595E5DC3C80400 | ||
| 1873 | :1075000000008B46048B56068B4E08E306D1E0D173 | ||
| 1874 | :10751000D2E2FA8946FC8956FE8B56FE8B46FCEB7E | ||
| 1875 | :1075200000C9C300000000000000000000000000CF | ||
| 1876 | :1075300050726576696F7573204D656E7500426592 | ||
| 1877 | :1075400067696E00000000000000000000000000FD | ||
| 1878 | :10755000000000000000000000000000000000002B | ||
| 1879 | :10756000000000000000000000000000000000001B | ||
| 1880 | :10757000000000000000000000000000000000000B | ||
| 1881 | :1075800000000000000000000000000000000000FB | ||
| 1882 | :1075900000000000000000000000000000000000EB | ||
| 1883 | :1075A00000000000000000000000000000000000DB | ||
| 1884 | :1075B00000000000000000000000000000000000CB | ||
| 1885 | :1075C00000000000000000000000000000000000BB | ||
| 1886 | :1075D00000000000000000000000000000000000AB | ||
| 1887 | :1075E000000000000000000000000000000000009B | ||
| 1888 | :1075F000000000000000000000000000000000008B | ||
| 1889 | :10760000000000000000000000000000000000007A | ||
| 1890 | :10761000000000000000000000000000000000006A | ||
| 1891 | :10762000000000000000000000000000000000005A | ||
| 1892 | :10763000000000000000000000000000000000004A | ||
| 1893 | :10764000000000000000000000000000000000003A | ||
| 1894 | :10765000000000000000000000000000000000002A | ||
| 1895 | :10766000000000000000000000000000000000001A | ||
| 1896 | :10767000000000000000000000000000000000000A | ||
| 1897 | :1076800000000000000000000000000000000000FA | ||
| 1898 | :1076900000000000000000000000000000000000EA | ||
| 1899 | :1076A00000000000000000000000000000000000DA | ||
| 1900 | :1076B00000000000000000000000000000000000CA | ||
| 1901 | :1076C000000000000000000000000000506F727415 | ||
| 1902 | :1076D000203000506F7274203100506F727420326D | ||
| 1903 | :1076E00000506F7274203300506F72742034005059 | ||
| 1904 | :1076F0006F7274203500506F7274203600506F72B4 | ||
| 1905 | :1077000074203700506F7274203800506F727420EC | ||
| 1906 | :107710003900506F727420313000506F7274203114 | ||
| 1907 | :107720003100506F727420313200506F727420310A | ||
| 1908 | :107730003300506F727420313400506F72742031F6 | ||
| 1909 | :1077400035009C01A301AA01B101B801BF01C60126 | ||
| 1910 | :10775000CD01D401DB01E201EA01F201FA010202EA | ||
| 1911 | :107760000A02080000078100038080809F919591A4 | ||
| 1912 | :107770009F000381848E95848484840003828484A2 | ||
| 1913 | :107780008484958E8400048800B20BC60BDA0BEE5D | ||
| 1914 | :107790000B020C160C2A0C3E0C520C770C9C0CBEE7 | ||
| 1915 | :1077A0000CE00C020D01802054657374205061734D | ||
| 1916 | :1077B000736564201F20507265737320800200017E | ||
| 1917 | :1077C00080204D697373696E67205278204461741C | ||
| 1918 | :1077D000611F205072657373208002000180204277 | ||
| 1919 | :1077E00061642052782044617461201F20507265CA | ||
| 1920 | :1077F000737320800200018020586D7472204275DE | ||
| 1921 | :1078000073791F20507265737320800200018020FD | ||
| 1922 | :107810006E6F742063757272656E746C791F2020B0 | ||
| 1923 | :10782000696D706C656D656E7465640200240D2F62 | ||
| 1924 | :107830000D3A0D450D500D5B0D660D710D7C0D87DC | ||
| 1925 | :107840000D920D9D0DA80DB30DBE0DC90D53802CCD | ||
| 1926 | :107850003254442053862C334454522053822C33C8 | ||
| 1927 | :10786000525453201F53812C3252442053852C32C2 | ||
| 1928 | :1078700043442053832C334354532053842C3344A8 | ||
| 1929 | :1078800053522053872C3252492702000180202076 | ||
| 1930 | :10789000444344202D2070696E2032301F275385C9 | ||
| 1931 | :1078A0002E31818263908081828384858687888956 | ||
| 1932 | :1078B0008A8B8C8D8E8F27020001802020445352AA | ||
| 1933 | :1078C000202D2070696E2031311F2753842E318185 | ||
| 1934 | :1078D000826390808182838485868788898A8B8C65 | ||
| 1935 | :1078E0008D8E8F27020001802020435453202D20AD | ||
| 1936 | :1078F00070696E20341F2753832E318182639080FC | ||
| 1937 | :107900008182838485868788898A8B8C8D8E8F2758 | ||
| 1938 | :107910000200018020205249202D2070696E203203 | ||
| 1939 | :10792000321F2753872E3181826390808182838426 | ||
| 1940 | :1079300085868788898A8B8C8D8E8F2702000180AF | ||
| 1941 | :107940002020445452202D2070696E20362F381F7D | ||
| 1942 | :107950002753862E3181826390808182838485863D | ||
| 1943 | :107960008788898A8B8C8D8E8F270200018020204A | ||
| 1944 | :10797000525453202D2070696E20351F2753822EBC | ||
| 1945 | :107980003181826390808182838485868788898A19 | ||
| 1946 | :107990008B8C8D8E8F27020001802020527844200E | ||
| 1947 | :1079A0002D2070696E20321F2753812E30534D8158 | ||
| 1948 | :1079B000826390808182838485868788898A8B8C84 | ||
| 1949 | :1079C0008D8E8F27020001802020547844202D20A6 | ||
| 1950 | :1079D00070696E20331F2753802E30534D81826390 | ||
| 1951 | :1079E00090808182838485868788898A8B8C8D8E1E | ||
| 1952 | :1079F0008F27020001802020444344202D207069FD | ||
| 1953 | :107A00006E20351F2753852E3181826390808182BD | ||
| 1954 | :107A1000838485868788898A8B8C8D8E8F27020048 | ||
| 1955 | :107A200001802020445352202D2070696E20351F84 | ||
| 1956 | :107A30002753842E3181826390808182838485865E | ||
| 1957 | :107A40008788898A8B8C8D8E8F2702000180202069 | ||
| 1958 | :107A5000435453202D2070696E20311F2753832EED | ||
| 1959 | :107A60003181826390808182838485868788898A38 | ||
| 1960 | :107A70008B8C8D8E8F270200018020205249202D73 | ||
| 1961 | :107A800020286E2E632E291F2753872E3181826373 | ||
| 1962 | :107A900090808182838485868788898A8B8C8D8E6D | ||
| 1963 | :107AA0008F27020001802020445452202D2070692D | ||
| 1964 | :107AB0006E20321F2753862E31818263908081820F | ||
| 1965 | :107AC000838485868788898A8B8C8D8E8F27020098 | ||
| 1966 | :107AD00001802020525453202D2070696E20371FC2 | ||
| 1967 | :107AE0002753822E318182639080818283848586B0 | ||
| 1968 | :107AF0008788898A8B8C8D8E8F27020001802020B9 | ||
| 1969 | :107B0000527844202D2070696E20361F2753812E15 | ||
| 1970 | :107B100030534D81826390808182838485868788FB | ||
| 1971 | :107B2000898A8B8C8D8E8F270200018020205478CB | ||
| 1972 | :107B300044202D2070696E20331F2753802E305330 | ||
| 1973 | :107B40004D81826390808182838485868788898A3B | ||
| 1974 | :107B50008B8C8D8E8F27020001802020444344208F | ||
| 1975 | :107B60002D2070696E20351F202020202753852E60 | ||
| 1976 | :107B700031818263888081828384858687270200A1 | ||
| 1977 | :107B800001802020445352202D2070696E20351F23 | ||
| 1978 | :107B9000202020202753842E318182638880818297 | ||
| 1979 | :107BA0008384858687270200018020204354532048 | ||
| 1980 | :107BB0002D2070696E20311F202020202753832E16 | ||
| 1981 | :107BC0003181826388808182838485868727020051 | ||
| 1982 | :107BD000018020205249202D20286E2E632E291F3F | ||
| 1983 | :107BE000202020202753872E318182638880818244 | ||
| 1984 | :107BF00083848586872702000180202044545220F8 | ||
| 1985 | :107C00002D2070696E20321F202020202753862EC1 | ||
| 1986 | :107C10003181826388808182838485868727020000 | ||
| 1987 | :107C200001802020525453202D2070696E20371F70 | ||
| 1988 | :107C3000202020202753822E3181826388808182F8 | ||
| 1989 | :107C40008384858687270200018020205278442083 | ||
| 1990 | :107C50002D2070696E20361F202020202753812E72 | ||
| 1991 | :107C600030534D8182638880818283848586872713 | ||
| 1992 | :107C7000020001802020547844202D2070696E205D | ||
| 1993 | :107C8000331F202020202753802E30534D818263C4 | ||
| 1994 | :107C90008880818283848586872702000180202056 | ||
| 1995 | :107CA000444344202D2070696E2032301F20202054 | ||
| 1996 | :107CB000202753852E318182638880818283848549 | ||
| 1997 | :107CC000868727020001802020445352202D2070F7 | ||
| 1998 | :107CD000696E2031311F202020202753842E3181CE | ||
| 1999 | :107CE0008263888081828384858687270200018061 | ||
| 2000 | :107CF0002020435453202D2070696E20341F2020F3 | ||
| 2001 | :107D000020202753832E318182638880818283845F | ||
| 2002 | :107D1000858687270200018020205249202D20706F | ||
| 2003 | :107D2000696E2032321F202020202753872E318178 | ||
| 2004 | :107D30008263888081828384858687270200018010 | ||
| 2005 | :107D40002020445452202D2070696E20362F381F79 | ||
| 2006 | :107D5000202020202753862E3181826388808182D3 | ||
| 2007 | :107D60008384858687270200018020205254532077 | ||
| 2008 | :107D70002D2070696E20351F202020202753822E51 | ||
| 2009 | :107D8000318182638880818283848586872702008F | ||
| 2010 | :107D900001802020527844202D2070696E20321FEF | ||
| 2011 | :107DA000202020202753812E30534D8182638880EC | ||
| 2012 | :107DB0008182838485868727020001802020547871 | ||
| 2013 | :107DC00044202D2070696E20331F2020202027534F | ||
| 2014 | :107DD000802E30534D8182638880818283848586A2 | ||
| 2015 | :107DE0008727020068049604B6033C040E04890346 | ||
| 2016 | :107DF0005C03E20360088A08BE0738080E0895078E | ||
| 2017 | :107E00006C07E6071C057405FA05C404F004CC05EC | ||
| 2018 | :107E1000A00548057806C806420728065006180738 | ||
| 2019 | :107E2000F006A0060000F408F408D40D04090409C3 | ||
| 2020 | :107E30000409040942000C091C09E50D020014099B | ||
| 2021 | :107E40000409F40D43001C090C09050E0004040983 | ||
| 2022 | :107E50001409120E2C092C092C092C0900003C09CC | ||
| 2023 | :107E60006C091E0E740974097409740900014C0927 | ||
| 2024 | :107E70002C092D0E740974097409740900025C0937 | ||
| 2025 | :107E80003C093D0E740974097409740900036C09F6 | ||
| 2026 | :107E90004C094D0E7409740974097409FF002C090A | ||
| 2027 | :107EA0005C09000000058409EC095E0EF409F40980 | ||
| 2028 | :107EB000F409F409000694097409680EAC0AAC0AC6 | ||
| 2029 | :107EC000AC0AAC0A0007A4098409720EBC0ABC0AF9 | ||
| 2030 | :107ED000BC0ABC0A0008B40994097C0ED40AD40A6E | ||
| 2031 | :107EE000D40AD40A000BC409A409830EFC0AFC0AB4 | ||
| 2032 | :107EF000FC0AFC0A000CD409B409900E140B140BF4 | ||
| 2033 | :107F0000140B140B0002E409C409A00E2C0B2C0B5B | ||
| 2034 | :107F10002C0B2C0B0400EC09D4090E00FF00740993 | ||
| 2035 | :107F2000E40900008201FC09A40AAC0E8202040AE2 | ||
| 2036 | :107F3000F409AF0E82030C0AFC09B20E8204140A83 | ||
| 2037 | :107F4000040AB60E82051C0A0C0ABC0E8206240A1C | ||
| 2038 | :107F5000140AC00E82072C0A1C0AC40E8208340AB6 | ||
| 2039 | :107F6000240AC80E82093C0A2C0ACC0E820A440A52 | ||
| 2040 | :107F7000340AD10E82104C0A3C0AD60E820B540AE7 | ||
| 2041 | :107F8000440ADB0E82115C0A4C0AE00E820C640A81 | ||
| 2042 | :107F9000540AE50E82126C0A5C0AEA0E820D740A1B | ||
| 2043 | :107FA000640AEF0E820E7C0A6C0AF40E820F840AB9 | ||
| 2044 | :107FB000740AFB0E82138C0A7C0A020F8214940A44 | ||
| 2045 | :107FC000840A090F82159C0A8C0A100F8216A40AD3 | ||
| 2046 | :107FD000940A170F8217F4099C0A1E0F8202B40A32 | ||
| 2047 | :107FE000B40A260F8203AC0AAC0A2D0F8200C40A21 | ||
| 2048 | :107FF000CC0A340F8201CC0ABC0A3F0F8202BC0AB1 | ||
| 2049 | :10800000C40A4D0F8200DC0AF40A590F8201E40A07 | ||
| 2050 | :10801000D40A630F8202EC0ADC0A6E0F8203F40AB0 | ||
| 2051 | :10802000E40A7A0F8204D40AEC0A870F8200040B58 | ||
| 2052 | :108030000C0B930F82010C0BFC0A9B0F8202FC0AB3 | ||
| 2053 | :10804000040BA70F82001C0B240BB00F8201240B22 | ||
| 2054 | :10805000140BB50F8202140B1C0BBE0F4400340B23 | ||
| 2055 | :10806000A40B9C0144013C0B2C0BA3014402440BC8 | ||
| 2056 | :10807000340BAA0144034C0B3C0BB1014404540BD8 | ||
| 2057 | :10808000440BB80144055C0B4C0BBF014406640B68 | ||
| 2058 | :10809000540BC60144076C0B5C0BCD014408740BF8 | ||
| 2059 | :1080A000640BD40144097C0B6C0BDB01440A840B88 | ||
| 2060 | :1080B000740BE201440B8C0B7C0BEA01440C940B17 | ||
| 2061 | :1080C000840BF201440D9C0B8C0BFA01440EA40BA3 | ||
| 2062 | :1080D000940B0202440F2C0B9C0B0A02171F0F2F4C | ||
| 2063 | :1080E0000000018078783A20747820637073202A29 | ||
| 2064 | :1080F0002A2A2A2A0200018078783A20747820639C | ||
| 2065 | :108100007073202A2A2A2A2A0200018078783A20CD | ||
| 2066 | :10811000747820637073202A2A2A2A2A0200018098 | ||
| 2067 | :1081200078783A20747820637073202A2A2A2A2AC1 | ||
| 2068 | :10813000020001C078783A20726320637073202AAD | ||
| 2069 | :108140002A2A2A2A020001C078783A207263206322 | ||
| 2070 | :108150007073202A2A2A2A2A020001C078783A203D | ||
| 2071 | :10816000726320637073202A2A2A2A2A020001C01F | ||
| 2072 | :1081700078783A20726320637073202A2A2A2A2A88 | ||
| 2073 | :1081800002000180496E7374616C6C204C6F6F70DB | ||
| 2074 | :108190006261636B1F5072657373208020746F205F | ||
| 2075 | :1081A000737461727402000180204361626C652007 | ||
| 2076 | :1081B000746F2052656D6F74651F50726573732004 | ||
| 2077 | :1081C0008020746F20737461727402000180204CEF | ||
| 2078 | :1081D0006F63616C204C6F6F706261636B201F2056 | ||
| 2079 | :1081E0002052756E6E696E67202E2E2E0200018061 | ||
| 2080 | :1081F00052656D6F7465204C6F6F706261636B20A8 | ||
| 2081 | :108200001F202052756E6E696E67202E2E2E020082 | ||
| 2082 | :10821000018020496E74726E6C204C6F6F706261C9 | ||
| 2083 | :10822000636B1F202052756E6E696E67202E2E2E96 | ||
| 2084 | :10823000020001805472616E736D69742050617424 | ||
| 2085 | :108240007465726E1F202052756E6E696E67202EE7 | ||
| 2086 | :108250002E2E020001802020303A2027438000018A | ||
| 2087 | :10826000802020313A202743810001802020323AAB | ||
| 2088 | :10827000202743820001802020333A2027438300B7 | ||
| 2089 | :1082800001802020343A20274384000180202035BB | ||
| 2090 | :108290003A202743850001802020363A2027438654 | ||
| 2091 | :1082A0000001802020373A202743870001802020CA | ||
| 2092 | :1082B000383A202743880001802020393A2027437C | ||
| 2093 | :1082C000890001802031303A2027438A0001802034 | ||
| 2094 | :1082D00031313A2027438B0001802031323A202768 | ||
| 2095 | :1082E000438C0001802031333A2027438D000180E8 | ||
| 2096 | :1082F0002031343A2027438E0001802031353A2046 | ||
| 2097 | :1083000027438F002A2A204D61696E20204D656E1B | ||
| 2098 | :1083100075202A2A004D6F6E69746F72206120509B | ||
| 2099 | :108320006F7274004D6F6E69746F722061205369B3 | ||
| 2100 | :10833000676E616C00457374696D617465204350AC | ||
| 2101 | :108340005300446961676E6F7374696373004C6FA7 | ||
| 2102 | :1083500063616C204C6F6F706261636B0052656D7E | ||
| 2103 | :108360006F7465204C6F6F706261636B00496E744F | ||
| 2104 | :10837000726E6C204C6F6F706261636B005472613F | ||
| 2105 | :108380006E736D6974205061747465726E00426121 | ||
| 2106 | :10839000756420526174650044617461204269749F | ||
| 2107 | :1083A000730053746F702042697473005061726976 | ||
| 2108 | :1083B00074790044617461205061747465726E0058 | ||
| 2109 | :1083C000547820466C6F7720436F6E74726F6C0028 | ||
| 2110 | :1083D000506F7274204E756D6265720035300037D3 | ||
| 2111 | :1083E0003500313130003133342E35003135300035 | ||
| 2112 | :1083F00032303000333030003630300031323030FF | ||
| 2113 | :10840000003138303000323030300032343030001B | ||
| 2114 | :1084100033363030003438303000373230300039C5 | ||
| 2115 | :108420003630300031392C3230300033382C343093 | ||
| 2116 | :10843000300035362C3030300035372C36303000B7 | ||
| 2117 | :1084400036342C3030300037362C38303000313173 | ||
| 2118 | :10845000352C323030003720626974730038206266 | ||
| 2119 | :1084600069747300312073746F7020626974003115 | ||
| 2120 | :108470002E352073746F702062697473003220731C | ||
| 2121 | :10848000746F702062697473006E6F20706172691E | ||
| 2122 | :108490007479006F64642070617269747900657624 | ||
| 2123 | :1084A000656E207061726974790073706163652014 | ||
| 2124 | :1084B000706172697479006D61726B2070617269AC | ||
| 2125 | :1084C000747900436F6C756D6E7300426172626502 | ||
| 2126 | :1084D0007220506F6C650055555555552E2E2E0047 | ||
| 2127 | :1084E0004E6F6E6500586F6E2F586F66660043546E | ||
| 2128 | :1084F00053005072657373208020666F72206D6523 | ||
| 2129 | :108500006E750028636F756E74696E672E2E2E2946 | ||
| 2130 | :108510000000654E64204F6620436F4465000000F4 | ||
| 2131 | :10852000000000000000000000000000000000004B | ||
| 2132 | :10853000000000000000000000000000000000003B | ||
| 2133 | :10854000000000000000000000000000000000002B | ||
| 2134 | :10855000000000000000000000000000000000001B | ||
| 2135 | :10856000000000000000000000000000000000000B | ||
| 2136 | :1085700000000000000000000000000000000000FB | ||
| 2137 | :1085800000000000000000000000000000000000EB | ||
| 2138 | :1085900000000000000000000000000000000000DB | ||
| 2139 | :1085A00000000000000000000000000000000000CB | ||
| 2140 | :1085B00000000000000000000000000000000000BB | ||
| 2141 | :1085C00000000000000000000000000000000000AB | ||
| 2142 | :1085D000000000000000000000000000000000009B | ||
| 2143 | :1085E000000000000000000000000000000000008B | ||
| 2144 | :1085F000000000000000000000000000000000007B | ||
| 2145 | :00000001FF | ||
| 2146 | /* Intelliport II loadware */ | ||
| 2147 | /* -31232 bytes read from ff.lod */ | ||
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index debdfe0fc809..59f8db4a39a7 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
| @@ -866,6 +866,12 @@ COMPATIBLE_IOCTL(TIOCGPTN) | |||
| 866 | COMPATIBLE_IOCTL(TIOCSPTLCK) | 866 | COMPATIBLE_IOCTL(TIOCSPTLCK) |
| 867 | COMPATIBLE_IOCTL(TIOCSERGETLSR) | 867 | COMPATIBLE_IOCTL(TIOCSERGETLSR) |
| 868 | COMPATIBLE_IOCTL(TIOCSIG) | 868 | COMPATIBLE_IOCTL(TIOCSIG) |
| 869 | #ifdef TIOCSRS485 | ||
| 870 | COMPATIBLE_IOCTL(TIOCSRS485) | ||
| 871 | #endif | ||
| 872 | #ifdef TIOCGRS485 | ||
| 873 | COMPATIBLE_IOCTL(TIOCGRS485) | ||
| 874 | #endif | ||
| 869 | #ifdef TCGETS2 | 875 | #ifdef TCGETS2 |
| 870 | COMPATIBLE_IOCTL(TCGETS2) | 876 | COMPATIBLE_IOCTL(TCGETS2) |
| 871 | COMPATIBLE_IOCTL(TCSETS2) | 877 | COMPATIBLE_IOCTL(TCSETS2) |
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index fa217607c582..c57e064666e4 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild | |||
| @@ -84,7 +84,6 @@ header-y += capability.h | |||
| 84 | header-y += capi.h | 84 | header-y += capi.h |
| 85 | header-y += cciss_defs.h | 85 | header-y += cciss_defs.h |
| 86 | header-y += cciss_ioctl.h | 86 | header-y += cciss_ioctl.h |
| 87 | header-y += cdk.h | ||
| 88 | header-y += cdrom.h | 87 | header-y += cdrom.h |
| 89 | header-y += cgroupstats.h | 88 | header-y += cgroupstats.h |
| 90 | header-y += chio.h | 89 | header-y += chio.h |
| @@ -93,7 +92,6 @@ header-y += cn_proc.h | |||
| 93 | header-y += coda.h | 92 | header-y += coda.h |
| 94 | header-y += coda_psdev.h | 93 | header-y += coda_psdev.h |
| 95 | header-y += coff.h | 94 | header-y += coff.h |
| 96 | header-y += comstats.h | ||
| 97 | header-y += connector.h | 95 | header-y += connector.h |
| 98 | header-y += const.h | 96 | header-y += const.h |
| 99 | header-y += cramfs_fs.h | 97 | header-y += cramfs_fs.h |
| @@ -140,7 +138,6 @@ header-y += fuse.h | |||
| 140 | header-y += futex.h | 138 | header-y += futex.h |
| 141 | header-y += gameport.h | 139 | header-y += gameport.h |
| 142 | header-y += gen_stats.h | 140 | header-y += gen_stats.h |
| 143 | header-y += generic_serial.h | ||
| 144 | header-y += genetlink.h | 141 | header-y += genetlink.h |
| 145 | header-y += gfs2_ondisk.h | 142 | header-y += gfs2_ondisk.h |
| 146 | header-y += gigaset_dev.h | 143 | header-y += gigaset_dev.h |
| @@ -372,6 +369,7 @@ header-y += tipc.h | |||
| 372 | header-y += tipc_config.h | 369 | header-y += tipc_config.h |
| 373 | header-y += toshiba.h | 370 | header-y += toshiba.h |
| 374 | header-y += tty.h | 371 | header-y += tty.h |
| 372 | header-y += tty_flags.h | ||
| 375 | header-y += types.h | 373 | header-y += types.h |
| 376 | header-y += udf_fs_i.h | 374 | header-y += udf_fs_i.h |
| 377 | header-y += udp.h | 375 | header-y += udp.h |
diff --git a/include/linux/amba/serial.h b/include/linux/amba/serial.h index d117b29d1062..f612c783170f 100644 --- a/include/linux/amba/serial.h +++ b/include/linux/amba/serial.h | |||
| @@ -205,7 +205,6 @@ struct amba_pl011_data { | |||
| 205 | void *dma_tx_param; | 205 | void *dma_tx_param; |
| 206 | void (*init) (void); | 206 | void (*init) (void); |
| 207 | void (*exit) (void); | 207 | void (*exit) (void); |
| 208 | void (*reset) (void); | ||
| 209 | }; | 208 | }; |
| 210 | #endif | 209 | #endif |
| 211 | 210 | ||
diff --git a/include/linux/cd1400.h b/include/linux/cd1400.h deleted file mode 100644 index 1dc3ab0523fd..000000000000 --- a/include/linux/cd1400.h +++ /dev/null | |||
| @@ -1,292 +0,0 @@ | |||
| 1 | /*****************************************************************************/ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * cd1400.h -- cd1400 UART hardware info. | ||
| 5 | * | ||
| 6 | * Copyright (C) 1996-1998 Stallion Technologies | ||
| 7 | * Copyright (C) 1994-1996 Greg Ungerer. | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | /*****************************************************************************/ | ||
| 25 | #ifndef _CD1400_H | ||
| 26 | #define _CD1400_H | ||
| 27 | /*****************************************************************************/ | ||
| 28 | |||
| 29 | /* | ||
| 30 | * Define the number of async ports per cd1400 uart chip. | ||
| 31 | */ | ||
| 32 | #define CD1400_PORTS 4 | ||
| 33 | |||
| 34 | /* | ||
| 35 | * Define the cd1400 uarts internal FIFO sizes. | ||
| 36 | */ | ||
| 37 | #define CD1400_TXFIFOSIZE 12 | ||
| 38 | #define CD1400_RXFIFOSIZE 12 | ||
| 39 | |||
| 40 | /* | ||
| 41 | * Local RX FIFO thresh hold level. Also define the RTS thresh hold | ||
| 42 | * based on the RX thresh hold. | ||
| 43 | */ | ||
| 44 | #define FIFO_RXTHRESHOLD 6 | ||
| 45 | #define FIFO_RTSTHRESHOLD 7 | ||
| 46 | |||
| 47 | /*****************************************************************************/ | ||
| 48 | |||
| 49 | /* | ||
| 50 | * Define the cd1400 register addresses. These are all the valid | ||
| 51 | * registers with the cd1400. Some are global, some virtual, some | ||
| 52 | * per port. | ||
| 53 | */ | ||
| 54 | #define GFRCR 0x40 | ||
| 55 | #define CAR 0x68 | ||
| 56 | #define GCR 0x4b | ||
| 57 | #define SVRR 0x67 | ||
| 58 | #define RICR 0x44 | ||
| 59 | #define TICR 0x45 | ||
| 60 | #define MICR 0x46 | ||
| 61 | #define RIR 0x6b | ||
| 62 | #define TIR 0x6a | ||
| 63 | #define MIR 0x69 | ||
| 64 | #define PPR 0x7e | ||
| 65 | |||
| 66 | #define RIVR 0x43 | ||
| 67 | #define TIVR 0x42 | ||
| 68 | #define MIVR 0x41 | ||
| 69 | #define TDR 0x63 | ||
| 70 | #define RDSR 0x62 | ||
| 71 | #define MISR 0x4c | ||
| 72 | #define EOSRR 0x60 | ||
| 73 | |||
| 74 | #define LIVR 0x18 | ||
| 75 | #define CCR 0x05 | ||
| 76 | #define SRER 0x06 | ||
| 77 | #define COR1 0x08 | ||
| 78 | #define COR2 0x09 | ||
| 79 | #define COR3 0x0a | ||
| 80 | #define COR4 0x1e | ||
| 81 | #define COR5 0x1f | ||
| 82 | #define CCSR 0x0b | ||
| 83 | #define RDCR 0x0e | ||
| 84 | #define SCHR1 0x1a | ||
| 85 | #define SCHR2 0x1b | ||
| 86 | #define SCHR3 0x1c | ||
| 87 | #define SCHR4 0x1d | ||
| 88 | #define SCRL 0x22 | ||
| 89 | #define SCRH 0x23 | ||
| 90 | #define LNC 0x24 | ||
| 91 | #define MCOR1 0x15 | ||
| 92 | #define MCOR2 0x16 | ||
| 93 | #define RTPR 0x21 | ||
| 94 | #define MSVR1 0x6c | ||
| 95 | #define MSVR2 0x6d | ||
| 96 | #define PSVR 0x6f | ||
| 97 | #define RBPR 0x78 | ||
| 98 | #define RCOR 0x7c | ||
| 99 | #define TBPR 0x72 | ||
| 100 | #define TCOR 0x76 | ||
| 101 | |||
| 102 | /*****************************************************************************/ | ||
| 103 | |||
| 104 | /* | ||
| 105 | * Define the set of baud rate clock divisors. | ||
| 106 | */ | ||
| 107 | #define CD1400_CLK0 8 | ||
| 108 | #define CD1400_CLK1 32 | ||
| 109 | #define CD1400_CLK2 128 | ||
| 110 | #define CD1400_CLK3 512 | ||
| 111 | #define CD1400_CLK4 2048 | ||
| 112 | |||
| 113 | #define CD1400_NUMCLKS 5 | ||
| 114 | |||
| 115 | /*****************************************************************************/ | ||
| 116 | |||
| 117 | /* | ||
| 118 | * Define the clock pre-scalar value to be a 5 ms clock. This should be | ||
| 119 | * OK for now. It would probably be better to make it 10 ms, but we | ||
| 120 | * can't fit that divisor into 8 bits! | ||
| 121 | */ | ||
| 122 | #define PPR_SCALAR 244 | ||
| 123 | |||
| 124 | /*****************************************************************************/ | ||
| 125 | |||
| 126 | /* | ||
| 127 | * Define values used to set character size options. | ||
| 128 | */ | ||
| 129 | #define COR1_CHL5 0x00 | ||
| 130 | #define COR1_CHL6 0x01 | ||
| 131 | #define COR1_CHL7 0x02 | ||
| 132 | #define COR1_CHL8 0x03 | ||
| 133 | |||
| 134 | /* | ||
| 135 | * Define values used to set the number of stop bits. | ||
| 136 | */ | ||
| 137 | #define COR1_STOP1 0x00 | ||
| 138 | #define COR1_STOP15 0x04 | ||
| 139 | #define COR1_STOP2 0x08 | ||
| 140 | |||
| 141 | /* | ||
| 142 | * Define values used to set the parity scheme in use. | ||
| 143 | */ | ||
| 144 | #define COR1_PARNONE 0x00 | ||
| 145 | #define COR1_PARFORCE 0x20 | ||
| 146 | #define COR1_PARENB 0x40 | ||
| 147 | #define COR1_PARIGNORE 0x10 | ||
| 148 | |||
| 149 | #define COR1_PARODD 0x80 | ||
| 150 | #define COR1_PAREVEN 0x00 | ||
| 151 | |||
| 152 | #define COR2_IXM 0x80 | ||
| 153 | #define COR2_TXIBE 0x40 | ||
| 154 | #define COR2_ETC 0x20 | ||
| 155 | #define COR2_LLM 0x10 | ||
| 156 | #define COR2_RLM 0x08 | ||
| 157 | #define COR2_RTSAO 0x04 | ||
| 158 | #define COR2_CTSAE 0x02 | ||
| 159 | |||
| 160 | #define COR3_SCDRNG 0x80 | ||
| 161 | #define COR3_SCD34 0x40 | ||
| 162 | #define COR3_FCT 0x20 | ||
| 163 | #define COR3_SCD12 0x10 | ||
| 164 | |||
| 165 | /* | ||
| 166 | * Define values used by COR4. | ||
| 167 | */ | ||
| 168 | #define COR4_BRKINT 0x08 | ||
| 169 | #define COR4_IGNBRK 0x18 | ||
| 170 | |||
| 171 | /*****************************************************************************/ | ||
| 172 | |||
| 173 | /* | ||
| 174 | * Define the modem control register values. | ||
| 175 | * Note that the actual hardware is a little different to the conventional | ||
| 176 | * pin names on the cd1400. | ||
| 177 | */ | ||
| 178 | #define MSVR1_DTR 0x01 | ||
| 179 | #define MSVR1_DSR 0x10 | ||
| 180 | #define MSVR1_RI 0x20 | ||
| 181 | #define MSVR1_CTS 0x40 | ||
| 182 | #define MSVR1_DCD 0x80 | ||
| 183 | |||
| 184 | #define MSVR2_RTS 0x02 | ||
| 185 | #define MSVR2_DSR 0x10 | ||
| 186 | #define MSVR2_RI 0x20 | ||
| 187 | #define MSVR2_CTS 0x40 | ||
| 188 | #define MSVR2_DCD 0x80 | ||
| 189 | |||
| 190 | #define MCOR1_DCD 0x80 | ||
| 191 | #define MCOR1_CTS 0x40 | ||
| 192 | #define MCOR1_RI 0x20 | ||
| 193 | #define MCOR1_DSR 0x10 | ||
| 194 | |||
| 195 | #define MCOR2_DCD 0x80 | ||
| 196 | #define MCOR2_CTS 0x40 | ||
| 197 | #define MCOR2_RI 0x20 | ||
| 198 | #define MCOR2_DSR 0x10 | ||
| 199 | |||
| 200 | /*****************************************************************************/ | ||
| 201 | |||
| 202 | /* | ||
| 203 | * Define the bits used with the service (interrupt) enable register. | ||
| 204 | */ | ||
| 205 | #define SRER_NNDT 0x01 | ||
| 206 | #define SRER_TXEMPTY 0x02 | ||
| 207 | #define SRER_TXDATA 0x04 | ||
| 208 | #define SRER_RXDATA 0x10 | ||
| 209 | #define SRER_MODEM 0x80 | ||
| 210 | |||
| 211 | /*****************************************************************************/ | ||
| 212 | |||
| 213 | /* | ||
| 214 | * Define operational commands for the command register. | ||
| 215 | */ | ||
| 216 | #define CCR_RESET 0x80 | ||
| 217 | #define CCR_CORCHANGE 0x4e | ||
| 218 | #define CCR_SENDCH 0x20 | ||
| 219 | #define CCR_CHANCTRL 0x10 | ||
| 220 | |||
| 221 | #define CCR_TXENABLE (CCR_CHANCTRL | 0x08) | ||
| 222 | #define CCR_TXDISABLE (CCR_CHANCTRL | 0x04) | ||
| 223 | #define CCR_RXENABLE (CCR_CHANCTRL | 0x02) | ||
| 224 | #define CCR_RXDISABLE (CCR_CHANCTRL | 0x01) | ||
| 225 | |||
| 226 | #define CCR_SENDSCHR1 (CCR_SENDCH | 0x01) | ||
| 227 | #define CCR_SENDSCHR2 (CCR_SENDCH | 0x02) | ||
| 228 | #define CCR_SENDSCHR3 (CCR_SENDCH | 0x03) | ||
| 229 | #define CCR_SENDSCHR4 (CCR_SENDCH | 0x04) | ||
| 230 | |||
| 231 | #define CCR_RESETCHAN (CCR_RESET | 0x00) | ||
| 232 | #define CCR_RESETFULL (CCR_RESET | 0x01) | ||
| 233 | #define CCR_TXFLUSHFIFO (CCR_RESET | 0x02) | ||
| 234 | |||
| 235 | #define CCR_MAXWAIT 10000 | ||
| 236 | |||
| 237 | /*****************************************************************************/ | ||
| 238 | |||
| 239 | /* | ||
| 240 | * Define the valid acknowledgement types (for hw ack cycle). | ||
| 241 | */ | ||
| 242 | #define ACK_TYPMASK 0x07 | ||
| 243 | #define ACK_TYPTX 0x02 | ||
| 244 | #define ACK_TYPMDM 0x01 | ||
| 245 | #define ACK_TYPRXGOOD 0x03 | ||
| 246 | #define ACK_TYPRXBAD 0x07 | ||
| 247 | |||
| 248 | #define SVRR_RX 0x01 | ||
| 249 | #define SVRR_TX 0x02 | ||
| 250 | #define SVRR_MDM 0x04 | ||
| 251 | |||
| 252 | #define ST_OVERRUN 0x01 | ||
| 253 | #define ST_FRAMING 0x02 | ||
| 254 | #define ST_PARITY 0x04 | ||
| 255 | #define ST_BREAK 0x08 | ||
| 256 | #define ST_SCHAR1 0x10 | ||
| 257 | #define ST_SCHAR2 0x20 | ||
| 258 | #define ST_SCHAR3 0x30 | ||
| 259 | #define ST_SCHAR4 0x40 | ||
| 260 | #define ST_RANGE 0x70 | ||
| 261 | #define ST_SCHARMASK 0x70 | ||
| 262 | #define ST_TIMEOUT 0x80 | ||
| 263 | |||
| 264 | #define MISR_DCD 0x80 | ||
| 265 | #define MISR_CTS 0x40 | ||
| 266 | #define MISR_RI 0x20 | ||
| 267 | #define MISR_DSR 0x10 | ||
| 268 | |||
| 269 | /*****************************************************************************/ | ||
| 270 | |||
| 271 | /* | ||
| 272 | * Defines for the CCSR status register. | ||
| 273 | */ | ||
| 274 | #define CCSR_RXENABLED 0x80 | ||
| 275 | #define CCSR_RXFLOWON 0x40 | ||
| 276 | #define CCSR_RXFLOWOFF 0x20 | ||
| 277 | #define CCSR_TXENABLED 0x08 | ||
| 278 | #define CCSR_TXFLOWON 0x04 | ||
| 279 | #define CCSR_TXFLOWOFF 0x02 | ||
| 280 | |||
| 281 | /*****************************************************************************/ | ||
| 282 | |||
| 283 | /* | ||
| 284 | * Define the embedded commands. | ||
| 285 | */ | ||
| 286 | #define ETC_CMD 0x00 | ||
| 287 | #define ETC_STARTBREAK 0x81 | ||
| 288 | #define ETC_DELAY 0x82 | ||
| 289 | #define ETC_STOPBREAK 0x83 | ||
| 290 | |||
| 291 | /*****************************************************************************/ | ||
| 292 | #endif | ||
diff --git a/include/linux/cdk.h b/include/linux/cdk.h deleted file mode 100644 index 80093a8d4f64..000000000000 --- a/include/linux/cdk.h +++ /dev/null | |||
| @@ -1,486 +0,0 @@ | |||
| 1 | /*****************************************************************************/ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * cdk.h -- CDK interface definitions. | ||
| 5 | * | ||
| 6 | * Copyright (C) 1996-1998 Stallion Technologies | ||
| 7 | * Copyright (C) 1994-1996 Greg Ungerer. | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | /*****************************************************************************/ | ||
| 25 | #ifndef _CDK_H | ||
| 26 | #define _CDK_H | ||
| 27 | /*****************************************************************************/ | ||
| 28 | |||
| 29 | #pragma pack(2) | ||
| 30 | |||
| 31 | /* | ||
| 32 | * The following set of definitions is used to communicate with the | ||
| 33 | * shared memory interface of the Stallion intelligent multiport serial | ||
| 34 | * boards. The definitions in this file are taken directly from the | ||
| 35 | * document titled "Generic Stackable Interface, Downloader and | ||
| 36 | * Communications Development Kit". | ||
| 37 | */ | ||
| 38 | |||
| 39 | /* | ||
| 40 | * Define the set of important shared memory addresses. These are | ||
| 41 | * required to initialize the board and get things started. All of these | ||
| 42 | * addresses are relative to the start of the shared memory. | ||
| 43 | */ | ||
| 44 | #define CDK_SIGADDR 0x200 | ||
| 45 | #define CDK_FEATADDR 0x280 | ||
| 46 | #define CDK_CDKADDR 0x300 | ||
| 47 | #define CDK_RDYADDR 0x262 | ||
| 48 | |||
| 49 | #define CDK_ALIVEMARKER 13 | ||
| 50 | |||
| 51 | /* | ||
| 52 | * On hardware power up the ROMs located on the EasyConnection 8/64 will | ||
| 53 | * fill out the following signature information into shared memory. This | ||
| 54 | * way the host system can quickly determine that the board is present | ||
| 55 | * and is operational. | ||
| 56 | */ | ||
| 57 | typedef struct cdkecpsig { | ||
| 58 | unsigned long magic; | ||
| 59 | unsigned short romver; | ||
| 60 | unsigned short cputype; | ||
| 61 | unsigned char panelid[8]; | ||
| 62 | } cdkecpsig_t; | ||
| 63 | |||
| 64 | #define ECP_MAGIC 0x21504345 | ||
| 65 | |||
| 66 | /* | ||
| 67 | * On hardware power up the ROMs located on the ONboard, Stallion and | ||
| 68 | * Brumbys will fill out the following signature information into shared | ||
| 69 | * memory. This way the host system can quickly determine that the board | ||
| 70 | * is present and is operational. | ||
| 71 | */ | ||
| 72 | typedef struct cdkonbsig { | ||
| 73 | unsigned short magic0; | ||
| 74 | unsigned short magic1; | ||
| 75 | unsigned short magic2; | ||
| 76 | unsigned short magic3; | ||
| 77 | unsigned short romver; | ||
| 78 | unsigned short memoff; | ||
| 79 | unsigned short memseg; | ||
| 80 | unsigned short amask0; | ||
| 81 | unsigned short pic; | ||
| 82 | unsigned short status; | ||
| 83 | unsigned short btype; | ||
| 84 | unsigned short clkticks; | ||
| 85 | unsigned short clkspeed; | ||
| 86 | unsigned short amask1; | ||
| 87 | unsigned short amask2; | ||
| 88 | } cdkonbsig_t; | ||
| 89 | |||
| 90 | #define ONB_MAGIC0 0xf2a7 | ||
| 91 | #define ONB_MAGIC1 0xa149 | ||
| 92 | #define ONB_MAGIC2 0x6352 | ||
| 93 | #define ONB_MAGIC3 0xf121 | ||
| 94 | |||
| 95 | /* | ||
| 96 | * Define the feature area structure. The feature area is the set of | ||
| 97 | * startup parameters used by the slave image when it starts executing. | ||
| 98 | * They allow for the specification of buffer sizes, debug trace, etc. | ||
| 99 | */ | ||
| 100 | typedef struct cdkfeature { | ||
| 101 | unsigned long debug; | ||
| 102 | unsigned long banner; | ||
| 103 | unsigned long etype; | ||
| 104 | unsigned long nrdevs; | ||
| 105 | unsigned long brdspec; | ||
| 106 | unsigned long txrqsize; | ||
| 107 | unsigned long rxrqsize; | ||
| 108 | unsigned long flags; | ||
| 109 | } cdkfeature_t; | ||
| 110 | |||
| 111 | #define ETYP_DDK 0 | ||
| 112 | #define ETYP_CDK 1 | ||
| 113 | |||
| 114 | /* | ||
| 115 | * Define the CDK header structure. This is the info that the slave | ||
| 116 | * environment sets up after it has been downloaded and started. It | ||
| 117 | * essentially provides a memory map for the shared memory interface. | ||
| 118 | */ | ||
| 119 | typedef struct cdkhdr { | ||
| 120 | unsigned short command; | ||
| 121 | unsigned short status; | ||
| 122 | unsigned short port; | ||
| 123 | unsigned short mode; | ||
| 124 | unsigned long cmd_buf[14]; | ||
| 125 | unsigned short alive_cnt; | ||
| 126 | unsigned short intrpt_mode; | ||
| 127 | unsigned char intrpt_id[8]; | ||
| 128 | unsigned char ver_release; | ||
| 129 | unsigned char ver_modification; | ||
| 130 | unsigned char ver_fix; | ||
| 131 | unsigned char deadman_restart; | ||
| 132 | unsigned short deadman; | ||
| 133 | unsigned short nrdevs; | ||
| 134 | unsigned long memp; | ||
| 135 | unsigned long hostp; | ||
| 136 | unsigned long slavep; | ||
| 137 | unsigned char hostreq; | ||
| 138 | unsigned char slavereq; | ||
| 139 | unsigned char cmd_reserved[30]; | ||
| 140 | } cdkhdr_t; | ||
| 141 | |||
| 142 | #define MODE_DDK 0 | ||
| 143 | #define MODE_CDK 1 | ||
| 144 | |||
| 145 | #define IMD_INTR 0x0 | ||
| 146 | #define IMD_PPINTR 0x1 | ||
| 147 | #define IMD_POLL 0xff | ||
| 148 | |||
| 149 | /* | ||
| 150 | * Define the memory mapping structure. This structure is pointed to by | ||
| 151 | * the memp field in the stlcdkhdr struct. As many as these structures | ||
| 152 | * as required are laid out in shared memory to define how the rest of | ||
| 153 | * shared memory is divided up. There will be one for each port. | ||
| 154 | */ | ||
| 155 | typedef struct cdkmem { | ||
| 156 | unsigned short dtype; | ||
| 157 | unsigned long offset; | ||
| 158 | } cdkmem_t; | ||
| 159 | |||
| 160 | #define TYP_UNDEFINED 0x0 | ||
| 161 | #define TYP_ASYNCTRL 0x1 | ||
| 162 | #define TYP_ASYNC 0x20 | ||
| 163 | #define TYP_PARALLEL 0x40 | ||
| 164 | #define TYP_SYNCX21 0x60 | ||
| 165 | |||
| 166 | /*****************************************************************************/ | ||
| 167 | |||
| 168 | /* | ||
| 169 | * Following is a set of defines and structures used to actually deal | ||
| 170 | * with the serial ports on the board. Firstly is the set of commands | ||
| 171 | * that can be applied to ports. | ||
| 172 | */ | ||
| 173 | #define ASYCMD (((unsigned long) 'a') << 8) | ||
| 174 | |||
| 175 | #define A_NULL (ASYCMD | 0) | ||
| 176 | #define A_FLUSH (ASYCMD | 1) | ||
| 177 | #define A_BREAK (ASYCMD | 2) | ||
| 178 | #define A_GETPORT (ASYCMD | 3) | ||
| 179 | #define A_SETPORT (ASYCMD | 4) | ||
| 180 | #define A_SETPORTF (ASYCMD | 5) | ||
| 181 | #define A_SETPORTFTX (ASYCMD | 6) | ||
| 182 | #define A_SETPORTFRX (ASYCMD | 7) | ||
| 183 | #define A_GETSIGNALS (ASYCMD | 8) | ||
| 184 | #define A_SETSIGNALS (ASYCMD | 9) | ||
| 185 | #define A_SETSIGNALSF (ASYCMD | 10) | ||
| 186 | #define A_SETSIGNALSFTX (ASYCMD | 11) | ||
| 187 | #define A_SETSIGNALSFRX (ASYCMD | 12) | ||
| 188 | #define A_GETNOTIFY (ASYCMD | 13) | ||
| 189 | #define A_SETNOTIFY (ASYCMD | 14) | ||
| 190 | #define A_NOTIFY (ASYCMD | 15) | ||
| 191 | #define A_PORTCTRL (ASYCMD | 16) | ||
| 192 | #define A_GETSTATS (ASYCMD | 17) | ||
| 193 | #define A_RQSTATE (ASYCMD | 18) | ||
| 194 | #define A_FLOWSTATE (ASYCMD | 19) | ||
| 195 | #define A_CLEARSTATS (ASYCMD | 20) | ||
| 196 | |||
| 197 | /* | ||
| 198 | * Define those arguments used for simple commands. | ||
| 199 | */ | ||
| 200 | #define FLUSHRX 0x1 | ||
| 201 | #define FLUSHTX 0x2 | ||
| 202 | |||
| 203 | #define BREAKON -1 | ||
| 204 | #define BREAKOFF -2 | ||
| 205 | |||
| 206 | /* | ||
| 207 | * Define the port setting structure, and all those defines that go along | ||
| 208 | * with it. Basically this structure defines the characteristics of this | ||
| 209 | * port: baud rate, chars, parity, input/output char cooking etc. | ||
| 210 | */ | ||
| 211 | typedef struct asyport { | ||
| 212 | unsigned long baudout; | ||
| 213 | unsigned long baudin; | ||
| 214 | unsigned long iflag; | ||
| 215 | unsigned long oflag; | ||
| 216 | unsigned long lflag; | ||
| 217 | unsigned long pflag; | ||
| 218 | unsigned long flow; | ||
| 219 | unsigned long spare1; | ||
| 220 | unsigned short vtime; | ||
| 221 | unsigned short vmin; | ||
| 222 | unsigned short txlo; | ||
| 223 | unsigned short txhi; | ||
| 224 | unsigned short rxlo; | ||
| 225 | unsigned short rxhi; | ||
| 226 | unsigned short rxhog; | ||
| 227 | unsigned short spare2; | ||
| 228 | unsigned char csize; | ||
| 229 | unsigned char stopbs; | ||
| 230 | unsigned char parity; | ||
| 231 | unsigned char stopin; | ||
| 232 | unsigned char startin; | ||
| 233 | unsigned char stopout; | ||
| 234 | unsigned char startout; | ||
| 235 | unsigned char parmark; | ||
| 236 | unsigned char brkmark; | ||
| 237 | unsigned char cc[11]; | ||
| 238 | } asyport_t; | ||
| 239 | |||
| 240 | #define PT_STOP1 0x0 | ||
| 241 | #define PT_STOP15 0x1 | ||
| 242 | #define PT_STOP2 0x2 | ||
| 243 | |||
| 244 | #define PT_NOPARITY 0x0 | ||
| 245 | #define PT_ODDPARITY 0x1 | ||
| 246 | #define PT_EVENPARITY 0x2 | ||
| 247 | #define PT_MARKPARITY 0x3 | ||
| 248 | #define PT_SPACEPARITY 0x4 | ||
| 249 | |||
| 250 | #define F_NONE 0x0 | ||
| 251 | #define F_IXON 0x1 | ||
| 252 | #define F_IXOFF 0x2 | ||
| 253 | #define F_IXANY 0x4 | ||
| 254 | #define F_IOXANY 0x8 | ||
| 255 | #define F_RTSFLOW 0x10 | ||
| 256 | #define F_CTSFLOW 0x20 | ||
| 257 | #define F_DTRFLOW 0x40 | ||
| 258 | #define F_DCDFLOW 0x80 | ||
| 259 | #define F_DSROFLOW 0x100 | ||
| 260 | #define F_DSRIFLOW 0x200 | ||
| 261 | |||
| 262 | #define FI_NORX 0x1 | ||
| 263 | #define FI_RAW 0x2 | ||
| 264 | #define FI_ISTRIP 0x4 | ||
| 265 | #define FI_UCLC 0x8 | ||
| 266 | #define FI_INLCR 0x10 | ||
| 267 | #define FI_ICRNL 0x20 | ||
| 268 | #define FI_IGNCR 0x40 | ||
| 269 | #define FI_IGNBREAK 0x80 | ||
| 270 | #define FI_DSCRDBREAK 0x100 | ||
| 271 | #define FI_1MARKBREAK 0x200 | ||
| 272 | #define FI_2MARKBREAK 0x400 | ||
| 273 | #define FI_XCHNGBREAK 0x800 | ||
| 274 | #define FI_IGNRXERRS 0x1000 | ||
| 275 | #define FI_DSCDRXERRS 0x2000 | ||
| 276 | #define FI_1MARKRXERRS 0x4000 | ||
| 277 | #define FI_2MARKRXERRS 0x8000 | ||
| 278 | #define FI_XCHNGRXERRS 0x10000 | ||
| 279 | #define FI_DSCRDNULL 0x20000 | ||
| 280 | |||
| 281 | #define FO_OLCUC 0x1 | ||
| 282 | #define FO_ONLCR 0x2 | ||
| 283 | #define FO_OOCRNL 0x4 | ||
| 284 | #define FO_ONOCR 0x8 | ||
| 285 | #define FO_ONLRET 0x10 | ||
| 286 | #define FO_ONL 0x20 | ||
| 287 | #define FO_OBS 0x40 | ||
| 288 | #define FO_OVT 0x80 | ||
| 289 | #define FO_OFF 0x100 | ||
| 290 | #define FO_OTAB1 0x200 | ||
| 291 | #define FO_OTAB2 0x400 | ||
| 292 | #define FO_OTAB3 0x800 | ||
| 293 | #define FO_OCR1 0x1000 | ||
| 294 | #define FO_OCR2 0x2000 | ||
| 295 | #define FO_OCR3 0x4000 | ||
| 296 | #define FO_OFILL 0x8000 | ||
| 297 | #define FO_ODELL 0x10000 | ||
| 298 | |||
| 299 | #define P_RTSLOCK 0x1 | ||
| 300 | #define P_CTSLOCK 0x2 | ||
| 301 | #define P_MAPRTS 0x4 | ||
| 302 | #define P_MAPCTS 0x8 | ||
| 303 | #define P_LOOPBACK 0x10 | ||
| 304 | #define P_DTRFOLLOW 0x20 | ||
| 305 | #define P_FAKEDCD 0x40 | ||
| 306 | |||
| 307 | #define P_RXIMIN 0x10000 | ||
| 308 | #define P_RXITIME 0x20000 | ||
| 309 | #define P_RXTHOLD 0x40000 | ||
| 310 | |||
| 311 | /* | ||
| 312 | * Define a structure to communicate serial port signal and data state | ||
| 313 | * information. | ||
| 314 | */ | ||
| 315 | typedef struct asysigs { | ||
| 316 | unsigned long data; | ||
| 317 | unsigned long signal; | ||
| 318 | unsigned long sigvalue; | ||
| 319 | } asysigs_t; | ||
| 320 | |||
| 321 | #define DT_TXBUSY 0x1 | ||
| 322 | #define DT_TXEMPTY 0x2 | ||
| 323 | #define DT_TXLOW 0x4 | ||
| 324 | #define DT_TXHIGH 0x8 | ||
| 325 | #define DT_TXFULL 0x10 | ||
| 326 | #define DT_TXHOG 0x20 | ||
| 327 | #define DT_TXFLOWED 0x40 | ||
| 328 | #define DT_TXBREAK 0x80 | ||
| 329 | |||
| 330 | #define DT_RXBUSY 0x100 | ||
| 331 | #define DT_RXEMPTY 0x200 | ||
| 332 | #define DT_RXLOW 0x400 | ||
| 333 | #define DT_RXHIGH 0x800 | ||
| 334 | #define DT_RXFULL 0x1000 | ||
| 335 | #define DT_RXHOG 0x2000 | ||
| 336 | #define DT_RXFLOWED 0x4000 | ||
| 337 | #define DT_RXBREAK 0x8000 | ||
| 338 | |||
| 339 | #define SG_DTR 0x1 | ||
| 340 | #define SG_DCD 0x2 | ||
| 341 | #define SG_RTS 0x4 | ||
| 342 | #define SG_CTS 0x8 | ||
| 343 | #define SG_DSR 0x10 | ||
| 344 | #define SG_RI 0x20 | ||
| 345 | |||
| 346 | /* | ||
| 347 | * Define the notification setting structure. This is used to tell the | ||
| 348 | * port what events we want to be informed about. Fields here use the | ||
| 349 | * same defines as for the asysigs structure above. | ||
| 350 | */ | ||
| 351 | typedef struct asynotify { | ||
| 352 | unsigned long ctrl; | ||
| 353 | unsigned long data; | ||
| 354 | unsigned long signal; | ||
| 355 | unsigned long sigvalue; | ||
| 356 | } asynotify_t; | ||
| 357 | |||
| 358 | /* | ||
| 359 | * Define the port control structure. It is used to do fine grain | ||
| 360 | * control operations on the port. | ||
| 361 | */ | ||
| 362 | typedef struct { | ||
| 363 | unsigned long rxctrl; | ||
| 364 | unsigned long txctrl; | ||
| 365 | char rximdch; | ||
| 366 | char tximdch; | ||
| 367 | char spare1; | ||
| 368 | char spare2; | ||
| 369 | } asyctrl_t; | ||
| 370 | |||
| 371 | #define CT_ENABLE 0x1 | ||
| 372 | #define CT_DISABLE 0x2 | ||
| 373 | #define CT_STOP 0x4 | ||
| 374 | #define CT_START 0x8 | ||
| 375 | #define CT_STARTFLOW 0x10 | ||
| 376 | #define CT_STOPFLOW 0x20 | ||
| 377 | #define CT_SENDCHR 0x40 | ||
| 378 | |||
| 379 | /* | ||
| 380 | * Define the stats structure kept for each port. This is a useful set | ||
| 381 | * of data collected for each port on the slave. The A_GETSTATS command | ||
| 382 | * is used to retrieve this data from the slave. | ||
| 383 | */ | ||
| 384 | typedef struct asystats { | ||
| 385 | unsigned long opens; | ||
| 386 | unsigned long txchars; | ||
| 387 | unsigned long rxchars; | ||
| 388 | unsigned long txringq; | ||
| 389 | unsigned long rxringq; | ||
| 390 | unsigned long txmsgs; | ||
| 391 | unsigned long rxmsgs; | ||
| 392 | unsigned long txflushes; | ||
| 393 | unsigned long rxflushes; | ||
| 394 | unsigned long overruns; | ||
| 395 | unsigned long framing; | ||
| 396 | unsigned long parity; | ||
| 397 | unsigned long ringover; | ||
| 398 | unsigned long lost; | ||
| 399 | unsigned long rxstart; | ||
| 400 | unsigned long rxstop; | ||
| 401 | unsigned long txstart; | ||
| 402 | unsigned long txstop; | ||
| 403 | unsigned long dcdcnt; | ||
| 404 | unsigned long dtrcnt; | ||
| 405 | unsigned long ctscnt; | ||
| 406 | unsigned long rtscnt; | ||
| 407 | unsigned long dsrcnt; | ||
| 408 | unsigned long ricnt; | ||
| 409 | unsigned long txbreaks; | ||
| 410 | unsigned long rxbreaks; | ||
| 411 | unsigned long signals; | ||
| 412 | unsigned long state; | ||
| 413 | unsigned long hwid; | ||
| 414 | } asystats_t; | ||
| 415 | |||
| 416 | /*****************************************************************************/ | ||
| 417 | |||
| 418 | /* | ||
| 419 | * All command and control communication with a device on the slave is | ||
| 420 | * via a control block in shared memory. Each device has its own control | ||
| 421 | * block, defined by the following structure. The control block allows | ||
| 422 | * the host to open, close and control the device on the slave. | ||
| 423 | */ | ||
| 424 | typedef struct cdkctrl { | ||
| 425 | unsigned char open; | ||
| 426 | unsigned char close; | ||
| 427 | unsigned long openarg; | ||
| 428 | unsigned long closearg; | ||
| 429 | unsigned long cmd; | ||
| 430 | unsigned long status; | ||
| 431 | unsigned long args[32]; | ||
| 432 | } cdkctrl_t; | ||
| 433 | |||
| 434 | /* | ||
| 435 | * Each device on the slave passes data to and from the host via a ring | ||
| 436 | * queue in shared memory. Define a ring queue structure to hold the | ||
| 437 | * vital information about each ring queue. Two ring queues will be | ||
| 438 | * allocated for each port, one for receive data and one for transmit | ||
| 439 | * data. | ||
| 440 | */ | ||
| 441 | typedef struct cdkasyrq { | ||
| 442 | unsigned long offset; | ||
| 443 | unsigned short size; | ||
| 444 | unsigned short head; | ||
| 445 | unsigned short tail; | ||
| 446 | } cdkasyrq_t; | ||
| 447 | |||
| 448 | /* | ||
| 449 | * Each asynchronous port is defined in shared memory by the following | ||
| 450 | * structure. It contains a control block to command a device, and also | ||
| 451 | * the necessary data channel information as well. | ||
| 452 | */ | ||
| 453 | typedef struct cdkasy { | ||
| 454 | cdkctrl_t ctrl; | ||
| 455 | unsigned short notify; | ||
| 456 | asynotify_t changed; | ||
| 457 | unsigned short receive; | ||
| 458 | cdkasyrq_t rxq; | ||
| 459 | unsigned short transmit; | ||
| 460 | cdkasyrq_t txq; | ||
| 461 | } cdkasy_t; | ||
| 462 | |||
| 463 | #pragma pack() | ||
| 464 | |||
| 465 | /*****************************************************************************/ | ||
| 466 | |||
| 467 | /* | ||
| 468 | * Define the set of ioctls used by the driver to do special things | ||
| 469 | * to the board. These include interrupting it, and initializing | ||
| 470 | * the driver after board startup and shutdown. | ||
| 471 | */ | ||
| 472 | #include <linux/ioctl.h> | ||
| 473 | |||
| 474 | #define STL_BINTR _IO('s',20) | ||
| 475 | #define STL_BSTART _IO('s',21) | ||
| 476 | #define STL_BSTOP _IO('s',22) | ||
| 477 | #define STL_BRESET _IO('s',23) | ||
| 478 | |||
| 479 | /* | ||
| 480 | * Define a set of ioctl extensions, used to get at special stuff. | ||
| 481 | */ | ||
| 482 | #define STL_GETPFLAG _IO('s',80) | ||
| 483 | #define STL_SETPFLAG _IO('s',81) | ||
| 484 | |||
| 485 | /*****************************************************************************/ | ||
| 486 | #endif | ||
diff --git a/include/linux/comstats.h b/include/linux/comstats.h deleted file mode 100644 index 3f5ea8e8026d..000000000000 --- a/include/linux/comstats.h +++ /dev/null | |||
| @@ -1,119 +0,0 @@ | |||
| 1 | /*****************************************************************************/ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * comstats.h -- Serial Port Stats. | ||
| 5 | * | ||
| 6 | * Copyright (C) 1996-1998 Stallion Technologies | ||
| 7 | * Copyright (C) 1994-1996 Greg Ungerer. | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | /*****************************************************************************/ | ||
| 25 | #ifndef _COMSTATS_H | ||
| 26 | #define _COMSTATS_H | ||
| 27 | /*****************************************************************************/ | ||
| 28 | |||
| 29 | /* | ||
| 30 | * Serial port stats structure. The structure itself is UART | ||
| 31 | * independent, but some fields may be UART/driver specific (for | ||
| 32 | * example state). | ||
| 33 | */ | ||
| 34 | |||
| 35 | typedef struct { | ||
| 36 | unsigned long brd; | ||
| 37 | unsigned long panel; | ||
| 38 | unsigned long port; | ||
| 39 | unsigned long hwid; | ||
| 40 | unsigned long type; | ||
| 41 | unsigned long txtotal; | ||
| 42 | unsigned long rxtotal; | ||
| 43 | unsigned long txbuffered; | ||
| 44 | unsigned long rxbuffered; | ||
| 45 | unsigned long rxoverrun; | ||
| 46 | unsigned long rxparity; | ||
| 47 | unsigned long rxframing; | ||
| 48 | unsigned long rxlost; | ||
| 49 | unsigned long txbreaks; | ||
| 50 | unsigned long rxbreaks; | ||
| 51 | unsigned long txxon; | ||
| 52 | unsigned long txxoff; | ||
| 53 | unsigned long rxxon; | ||
| 54 | unsigned long rxxoff; | ||
| 55 | unsigned long txctson; | ||
| 56 | unsigned long txctsoff; | ||
| 57 | unsigned long rxrtson; | ||
| 58 | unsigned long rxrtsoff; | ||
| 59 | unsigned long modem; | ||
| 60 | unsigned long state; | ||
| 61 | unsigned long flags; | ||
| 62 | unsigned long ttystate; | ||
| 63 | unsigned long cflags; | ||
| 64 | unsigned long iflags; | ||
| 65 | unsigned long oflags; | ||
| 66 | unsigned long lflags; | ||
| 67 | unsigned long signals; | ||
| 68 | } comstats_t; | ||
| 69 | |||
| 70 | |||
| 71 | /* | ||
| 72 | * Board stats structure. Returns useful info about the board. | ||
| 73 | */ | ||
| 74 | |||
| 75 | #define COM_MAXPANELS 8 | ||
| 76 | |||
| 77 | typedef struct { | ||
| 78 | unsigned long panel; | ||
| 79 | unsigned long type; | ||
| 80 | unsigned long hwid; | ||
| 81 | unsigned long nrports; | ||
| 82 | } companel_t; | ||
| 83 | |||
| 84 | typedef struct { | ||
| 85 | unsigned long brd; | ||
| 86 | unsigned long type; | ||
| 87 | unsigned long hwid; | ||
| 88 | unsigned long state; | ||
| 89 | unsigned long ioaddr; | ||
| 90 | unsigned long ioaddr2; | ||
| 91 | unsigned long memaddr; | ||
| 92 | unsigned long irq; | ||
| 93 | unsigned long nrpanels; | ||
| 94 | unsigned long nrports; | ||
| 95 | companel_t panels[COM_MAXPANELS]; | ||
| 96 | } combrd_t; | ||
| 97 | |||
| 98 | |||
| 99 | /* | ||
| 100 | * Define the ioctl operations for stats stuff. | ||
| 101 | */ | ||
| 102 | #include <linux/ioctl.h> | ||
| 103 | |||
| 104 | #define COM_GETPORTSTATS _IO('c',30) | ||
| 105 | #define COM_CLRPORTSTATS _IO('c',31) | ||
| 106 | #define COM_GETBRDSTATS _IO('c',32) | ||
| 107 | |||
| 108 | |||
| 109 | /* | ||
| 110 | * Define the set of ioctls that give user level access to the | ||
| 111 | * private port, panel and board structures. The argument required | ||
| 112 | * will be driver dependent! | ||
| 113 | */ | ||
| 114 | #define COM_READPORT _IO('c',40) | ||
| 115 | #define COM_READBOARD _IO('c',41) | ||
| 116 | #define COM_READPANEL _IO('c',42) | ||
| 117 | |||
| 118 | /*****************************************************************************/ | ||
| 119 | #endif | ||
diff --git a/include/linux/generic_serial.h b/include/linux/generic_serial.h deleted file mode 100644 index 79b3eb37243a..000000000000 --- a/include/linux/generic_serial.h +++ /dev/null | |||
| @@ -1,35 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * generic_serial.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 1998 R.E.Wolff@BitWizard.nl | ||
| 5 | * | ||
| 6 | * written for the SX serial driver. | ||
| 7 | * | ||
| 8 | * Version 0.1 -- December, 1998. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef GENERIC_SERIAL_H | ||
| 12 | #define GENERIC_SERIAL_H | ||
| 13 | |||
| 14 | #warning Use of this header is deprecated. | ||
| 15 | #warning Since nobody sets the constants defined here for you, you should not, in any case, use them. Including the header is thus pointless. | ||
| 16 | |||
| 17 | /* Flags */ | ||
| 18 | /* Warning: serial.h defines some ASYNC_ flags, they say they are "only" | ||
| 19 | used in serial.c, but they are also used in all other serial drivers. | ||
| 20 | Make sure they don't clash with these here... */ | ||
| 21 | #define GS_TX_INTEN 0x00800000 | ||
| 22 | #define GS_RX_INTEN 0x00400000 | ||
| 23 | #define GS_ACTIVE 0x00200000 | ||
| 24 | |||
| 25 | #define GS_TYPE_NORMAL 1 | ||
| 26 | |||
| 27 | #define GS_DEBUG_FLUSH 0x00000001 | ||
| 28 | #define GS_DEBUG_BTR 0x00000002 | ||
| 29 | #define GS_DEBUG_TERMIOS 0x00000004 | ||
| 30 | #define GS_DEBUG_STUFF 0x00000008 | ||
| 31 | #define GS_DEBUG_CLOSE 0x00000010 | ||
| 32 | #define GS_DEBUG_FLOW 0x00000020 | ||
| 33 | #define GS_DEBUG_WRITE 0x00000040 | ||
| 34 | |||
| 35 | #endif | ||
diff --git a/include/linux/istallion.h b/include/linux/istallion.h deleted file mode 100644 index ad700a60c158..000000000000 --- a/include/linux/istallion.h +++ /dev/null | |||
| @@ -1,123 +0,0 @@ | |||
| 1 | /*****************************************************************************/ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * istallion.h -- stallion intelligent multiport serial driver. | ||
| 5 | * | ||
| 6 | * Copyright (C) 1996-1998 Stallion Technologies | ||
| 7 | * Copyright (C) 1994-1996 Greg Ungerer. | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | /*****************************************************************************/ | ||
| 25 | #ifndef _ISTALLION_H | ||
| 26 | #define _ISTALLION_H | ||
| 27 | /*****************************************************************************/ | ||
| 28 | |||
| 29 | /* | ||
| 30 | * Define important driver constants here. | ||
| 31 | */ | ||
| 32 | #define STL_MAXBRDS 4 | ||
| 33 | #define STL_MAXPANELS 4 | ||
| 34 | #define STL_MAXPORTS 64 | ||
| 35 | #define STL_MAXCHANS (STL_MAXPORTS + 1) | ||
| 36 | #define STL_MAXDEVS (STL_MAXBRDS * STL_MAXPORTS) | ||
| 37 | |||
| 38 | |||
| 39 | /* | ||
| 40 | * Define a set of structures to hold all the board/panel/port info | ||
| 41 | * for our ports. These will be dynamically allocated as required at | ||
| 42 | * driver initialization time. | ||
| 43 | */ | ||
| 44 | |||
| 45 | /* | ||
| 46 | * Port and board structures to hold status info about each object. | ||
| 47 | * The board structure contains pointers to structures for each port | ||
| 48 | * connected to it. Panels are not distinguished here, since | ||
| 49 | * communication with the slave board will always be on a per port | ||
| 50 | * basis. | ||
| 51 | */ | ||
| 52 | struct stliport { | ||
| 53 | unsigned long magic; | ||
| 54 | struct tty_port port; | ||
| 55 | unsigned int portnr; | ||
| 56 | unsigned int panelnr; | ||
| 57 | unsigned int brdnr; | ||
| 58 | unsigned long state; | ||
| 59 | unsigned int devnr; | ||
| 60 | int baud_base; | ||
| 61 | int custom_divisor; | ||
| 62 | int closing_wait; | ||
| 63 | int rc; | ||
| 64 | int argsize; | ||
| 65 | void *argp; | ||
| 66 | unsigned int rxmarkmsk; | ||
| 67 | wait_queue_head_t raw_wait; | ||
| 68 | struct asysigs asig; | ||
| 69 | unsigned long addr; | ||
| 70 | unsigned long rxoffset; | ||
| 71 | unsigned long txoffset; | ||
| 72 | unsigned long sigs; | ||
| 73 | unsigned long pflag; | ||
| 74 | unsigned int rxsize; | ||
| 75 | unsigned int txsize; | ||
| 76 | unsigned char reqbit; | ||
| 77 | unsigned char portidx; | ||
| 78 | unsigned char portbit; | ||
| 79 | }; | ||
| 80 | |||
| 81 | /* | ||
| 82 | * Use a structure of function pointers to do board level operations. | ||
| 83 | * These include, enable/disable, paging shared memory, interrupting, etc. | ||
| 84 | */ | ||
| 85 | struct stlibrd { | ||
| 86 | unsigned long magic; | ||
| 87 | unsigned int brdnr; | ||
| 88 | unsigned int brdtype; | ||
| 89 | unsigned long state; | ||
| 90 | unsigned int nrpanels; | ||
| 91 | unsigned int nrports; | ||
| 92 | unsigned int nrdevs; | ||
| 93 | unsigned int iobase; | ||
| 94 | int iosize; | ||
| 95 | unsigned long memaddr; | ||
| 96 | void __iomem *membase; | ||
| 97 | unsigned long memsize; | ||
| 98 | int pagesize; | ||
| 99 | int hostoffset; | ||
| 100 | int slaveoffset; | ||
| 101 | int bitsize; | ||
| 102 | int enabval; | ||
| 103 | unsigned int panels[STL_MAXPANELS]; | ||
| 104 | int panelids[STL_MAXPANELS]; | ||
| 105 | void (*init)(struct stlibrd *brdp); | ||
| 106 | void (*enable)(struct stlibrd *brdp); | ||
| 107 | void (*reenable)(struct stlibrd *brdp); | ||
| 108 | void (*disable)(struct stlibrd *brdp); | ||
| 109 | void __iomem *(*getmemptr)(struct stlibrd *brdp, unsigned long offset, int line); | ||
| 110 | void (*intr)(struct stlibrd *brdp); | ||
| 111 | void (*reset)(struct stlibrd *brdp); | ||
| 112 | struct stliport *ports[STL_MAXPORTS]; | ||
| 113 | }; | ||
| 114 | |||
| 115 | |||
| 116 | /* | ||
| 117 | * Define MAGIC numbers used for above structures. | ||
| 118 | */ | ||
| 119 | #define STLI_PORTMAGIC 0xe671c7a1 | ||
| 120 | #define STLI_BOARDMAGIC 0x4bc6c825 | ||
| 121 | |||
| 122 | /*****************************************************************************/ | ||
| 123 | #endif | ||
diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h index daf4a3a40ee0..b7c8cdc1d422 100644 --- a/include/linux/kbd_kern.h +++ b/include/linux/kbd_kern.h | |||
| @@ -65,7 +65,6 @@ struct kbd_struct { | |||
| 65 | 65 | ||
| 66 | extern int kbd_init(void); | 66 | extern int kbd_init(void); |
| 67 | 67 | ||
| 68 | extern unsigned char getledstate(void); | ||
| 69 | extern void setledstate(struct kbd_struct *kbd, unsigned int led); | 68 | extern void setledstate(struct kbd_struct *kbd, unsigned int led); |
| 70 | 69 | ||
| 71 | extern int do_poke_blanked_console; | 70 | extern int do_poke_blanked_console; |
| @@ -145,16 +144,4 @@ void compute_shiftstate(void); | |||
| 145 | 144 | ||
| 146 | extern unsigned int keymap_count; | 145 | extern unsigned int keymap_count; |
| 147 | 146 | ||
| 148 | /* console.c */ | ||
| 149 | |||
| 150 | static inline void con_schedule_flip(struct tty_struct *t) | ||
| 151 | { | ||
| 152 | unsigned long flags; | ||
| 153 | spin_lock_irqsave(&t->buf.lock, flags); | ||
| 154 | if (t->buf.tail != NULL) | ||
| 155 | t->buf.tail->commit = t->buf.tail->used; | ||
| 156 | spin_unlock_irqrestore(&t->buf.lock, flags); | ||
| 157 | schedule_work(&t->buf.work); | ||
| 158 | } | ||
| 159 | |||
| 160 | #endif | 147 | #endif |
diff --git a/include/linux/kdb.h b/include/linux/kdb.h index 42d9e863a313..7f6fe6e015bc 100644 --- a/include/linux/kdb.h +++ b/include/linux/kdb.h | |||
| @@ -13,6 +13,14 @@ | |||
| 13 | * Copyright (C) 2009 Jason Wessel <jason.wessel@windriver.com> | 13 | * Copyright (C) 2009 Jason Wessel <jason.wessel@windriver.com> |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | typedef enum { | ||
| 17 | KDB_REPEAT_NONE = 0, /* Do not repeat this command */ | ||
| 18 | KDB_REPEAT_NO_ARGS, /* Repeat the command without arguments */ | ||
| 19 | KDB_REPEAT_WITH_ARGS, /* Repeat the command including its arguments */ | ||
| 20 | } kdb_repeat_t; | ||
| 21 | |||
| 22 | typedef int (*kdb_func_t)(int, const char **); | ||
| 23 | |||
| 16 | #ifdef CONFIG_KGDB_KDB | 24 | #ifdef CONFIG_KGDB_KDB |
| 17 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 18 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
| @@ -32,14 +40,6 @@ extern atomic_t kdb_event; | |||
| 32 | 40 | ||
| 33 | #define KDB_MAXARGS 16 /* Maximum number of arguments to a function */ | 41 | #define KDB_MAXARGS 16 /* Maximum number of arguments to a function */ |
| 34 | 42 | ||
| 35 | typedef enum { | ||
| 36 | KDB_REPEAT_NONE = 0, /* Do not repeat this command */ | ||
| 37 | KDB_REPEAT_NO_ARGS, /* Repeat the command without arguments */ | ||
| 38 | KDB_REPEAT_WITH_ARGS, /* Repeat the command including its arguments */ | ||
| 39 | } kdb_repeat_t; | ||
| 40 | |||
| 41 | typedef int (*kdb_func_t)(int, const char **); | ||
| 42 | |||
| 43 | /* KDB return codes from a command or internal kdb function */ | 43 | /* KDB return codes from a command or internal kdb function */ |
| 44 | #define KDB_NOTFOUND (-1) | 44 | #define KDB_NOTFOUND (-1) |
| 45 | #define KDB_ARGCOUNT (-2) | 45 | #define KDB_ARGCOUNT (-2) |
| @@ -149,11 +149,14 @@ extern int kdb_register_repeat(char *, kdb_func_t, char *, char *, | |||
| 149 | short, kdb_repeat_t); | 149 | short, kdb_repeat_t); |
| 150 | extern int kdb_unregister(char *); | 150 | extern int kdb_unregister(char *); |
| 151 | #else /* ! CONFIG_KGDB_KDB */ | 151 | #else /* ! CONFIG_KGDB_KDB */ |
| 152 | #define kdb_printf(...) | 152 | static inline __printf(1, 2) int kdb_printf(const char *fmt, ...) { return 0; } |
| 153 | #define kdb_init(x) | 153 | static inline void kdb_init(int level) {} |
| 154 | #define kdb_register(...) | 154 | static inline int kdb_register(char *cmd, kdb_func_t func, char *usage, |
| 155 | #define kdb_register_repeat(...) | 155 | char *help, short minlen) { return 0; } |
| 156 | #define kdb_uregister(x) | 156 | static inline int kdb_register_repeat(char *cmd, kdb_func_t func, char *usage, |
| 157 | char *help, short minlen, | ||
| 158 | kdb_repeat_t repeat) { return 0; } | ||
| 159 | static inline int kdb_unregister(char *cmd) { return 0; } | ||
| 157 | #endif /* CONFIG_KGDB_KDB */ | 160 | #endif /* CONFIG_KGDB_KDB */ |
| 158 | enum { | 161 | enum { |
| 159 | KDB_NOT_INITIALIZED, | 162 | KDB_NOT_INITIALIZED, |
diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index c4d2fc194ede..4dff0c6ed58f 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h | |||
| @@ -240,6 +240,7 @@ extern void kgdb_arch_late(void); | |||
| 240 | * hardware breakpoints. | 240 | * hardware breakpoints. |
| 241 | * @correct_hw_break: Allow an architecture to specify how to correct the | 241 | * @correct_hw_break: Allow an architecture to specify how to correct the |
| 242 | * hardware debug registers. | 242 | * hardware debug registers. |
| 243 | * @enable_nmi: Manage NMI-triggered entry to KGDB | ||
| 243 | */ | 244 | */ |
| 244 | struct kgdb_arch { | 245 | struct kgdb_arch { |
| 245 | unsigned char gdb_bpt_instr[BREAK_INSTR_SIZE]; | 246 | unsigned char gdb_bpt_instr[BREAK_INSTR_SIZE]; |
| @@ -252,6 +253,8 @@ struct kgdb_arch { | |||
| 252 | void (*disable_hw_break)(struct pt_regs *regs); | 253 | void (*disable_hw_break)(struct pt_regs *regs); |
| 253 | void (*remove_all_hw_break)(void); | 254 | void (*remove_all_hw_break)(void); |
| 254 | void (*correct_hw_break)(void); | 255 | void (*correct_hw_break)(void); |
| 256 | |||
| 257 | void (*enable_nmi)(bool on); | ||
| 255 | }; | 258 | }; |
| 256 | 259 | ||
| 257 | /** | 260 | /** |
| @@ -283,6 +286,16 @@ extern struct kgdb_arch arch_kgdb_ops; | |||
| 283 | 286 | ||
| 284 | extern unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs); | 287 | extern unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs); |
| 285 | 288 | ||
| 289 | #ifdef CONFIG_SERIAL_KGDB_NMI | ||
| 290 | extern int kgdb_register_nmi_console(void); | ||
| 291 | extern int kgdb_unregister_nmi_console(void); | ||
| 292 | extern bool kgdb_nmi_poll_knock(void); | ||
| 293 | #else | ||
| 294 | static inline int kgdb_register_nmi_console(void) { return 0; } | ||
| 295 | static inline int kgdb_unregister_nmi_console(void) { return 0; } | ||
| 296 | static inline bool kgdb_nmi_poll_knock(void) { return 1; } | ||
| 297 | #endif | ||
| 298 | |||
| 286 | extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops); | 299 | extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops); |
| 287 | extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops); | 300 | extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops); |
| 288 | extern struct kgdb_io *dbg_io_ops; | 301 | extern struct kgdb_io *dbg_io_ops; |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 6b4565c440c8..8d3c42719387 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -1847,7 +1847,6 @@ | |||
| 1847 | #define PCI_DEVICE_ID_SIIG_8S_20x_650 0x2081 | 1847 | #define PCI_DEVICE_ID_SIIG_8S_20x_650 0x2081 |
| 1848 | #define PCI_DEVICE_ID_SIIG_8S_20x_850 0x2082 | 1848 | #define PCI_DEVICE_ID_SIIG_8S_20x_850 0x2082 |
| 1849 | #define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050 | 1849 | #define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050 |
| 1850 | #define PCI_SUBDEVICE_ID_SIIG_DUAL_SERIAL 0x2530 | ||
| 1851 | 1850 | ||
| 1852 | #define PCI_VENDOR_ID_RADISYS 0x1331 | 1851 | #define PCI_VENDOR_ID_RADISYS 0x1331 |
| 1853 | 1852 | ||
diff --git a/include/linux/platform_data/max310x.h b/include/linux/platform_data/max310x.h new file mode 100644 index 000000000000..91648bf5fc5c --- /dev/null +++ b/include/linux/platform_data/max310x.h | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | /* | ||
| 2 | * Maxim (Dallas) MAX3107/8 serial driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> | ||
| 5 | * | ||
| 6 | * Based on max3100.c, by Christian Pellegrin <chripell@evolware.org> | ||
| 7 | * Based on max3110.c, by Feng Tang <feng.tang@intel.com> | ||
| 8 | * Based on max3107.c, by Aavamobile | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #ifndef _MAX310X_H_ | ||
| 17 | #define _MAX310X_H_ | ||
| 18 | |||
| 19 | /* | ||
| 20 | * Example board initialization data: | ||
| 21 | * | ||
| 22 | * static struct max310x_pdata max3107_pdata = { | ||
| 23 | * .driver_flags = MAX310X_EXT_CLK, | ||
| 24 | * .uart_flags[0] = MAX310X_ECHO_SUPRESS | MAX310X_AUTO_DIR_CTRL, | ||
| 25 | * .frequency = 3686400, | ||
| 26 | * .gpio_base = -1, | ||
| 27 | * }; | ||
| 28 | * | ||
| 29 | * static struct spi_board_info spi_device_max3107[] = { | ||
| 30 | * { | ||
| 31 | * .modalias = "max3107", | ||
| 32 | * .irq = IRQ_EINT3, | ||
| 33 | * .bus_num = 1, | ||
| 34 | * .chip_select = 1, | ||
| 35 | * .platform_data = &max3107_pdata, | ||
| 36 | * }, | ||
| 37 | * }; | ||
| 38 | */ | ||
| 39 | |||
| 40 | #define MAX310X_MAX_UARTS 1 | ||
| 41 | |||
| 42 | /* MAX310X platform data structure */ | ||
| 43 | struct max310x_pdata { | ||
| 44 | /* Flags global to driver */ | ||
| 45 | const u8 driver_flags:2; | ||
| 46 | #define MAX310X_EXT_CLK (0x00000001) /* External clock enable */ | ||
| 47 | #define MAX310X_AUTOSLEEP (0x00000002) /* Enable AutoSleep mode */ | ||
| 48 | /* Flags global to UART port */ | ||
| 49 | const u8 uart_flags[MAX310X_MAX_UARTS]; | ||
| 50 | #define MAX310X_LOOPBACK (0x00000001) /* Loopback mode enable */ | ||
| 51 | #define MAX310X_ECHO_SUPRESS (0x00000002) /* Enable echo supress */ | ||
| 52 | #define MAX310X_AUTO_DIR_CTRL (0x00000004) /* Enable Auto direction | ||
| 53 | * control (RS-485) | ||
| 54 | */ | ||
| 55 | /* Frequency (extrenal clock or crystal) */ | ||
| 56 | const int frequency; | ||
| 57 | /* GPIO base number (can be negative) */ | ||
| 58 | const int gpio_base; | ||
| 59 | /* Called during startup */ | ||
| 60 | void (*init)(void); | ||
| 61 | /* Called before finish */ | ||
| 62 | void (*exit)(void); | ||
| 63 | /* Suspend callback */ | ||
| 64 | void (*suspend)(int do_suspend); | ||
| 65 | }; | ||
| 66 | |||
| 67 | #endif | ||
diff --git a/include/linux/platform_data/sccnxp.h b/include/linux/platform_data/sccnxp.h new file mode 100644 index 000000000000..7311ccd3217f --- /dev/null +++ b/include/linux/platform_data/sccnxp.h | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | /* | ||
| 2 | * NXP (Philips) SCC+++(SCN+++) serial driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> | ||
| 5 | * | ||
| 6 | * Based on sc26xx.c, by Thomas Bogendörfer (tsbogend@alpha.franken.de) | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #ifndef __SCCNXP_H | ||
| 15 | #define __SCCNXP_H | ||
| 16 | |||
| 17 | #define SCCNXP_MAX_UARTS 2 | ||
| 18 | |||
| 19 | /* Output lines */ | ||
| 20 | #define LINE_OP0 1 | ||
| 21 | #define LINE_OP1 2 | ||
| 22 | #define LINE_OP2 3 | ||
| 23 | #define LINE_OP3 4 | ||
| 24 | #define LINE_OP4 5 | ||
| 25 | #define LINE_OP5 6 | ||
| 26 | #define LINE_OP6 7 | ||
| 27 | #define LINE_OP7 8 | ||
| 28 | |||
| 29 | /* Input lines */ | ||
| 30 | #define LINE_IP0 9 | ||
| 31 | #define LINE_IP1 10 | ||
| 32 | #define LINE_IP2 11 | ||
| 33 | #define LINE_IP3 12 | ||
| 34 | #define LINE_IP4 13 | ||
| 35 | #define LINE_IP5 14 | ||
| 36 | #define LINE_IP6 15 | ||
| 37 | |||
| 38 | /* Signals */ | ||
| 39 | #define DTR_OP 0 /* DTR */ | ||
| 40 | #define RTS_OP 4 /* RTS */ | ||
| 41 | #define DSR_IP 8 /* DSR */ | ||
| 42 | #define CTS_IP 12 /* CTS */ | ||
| 43 | #define DCD_IP 16 /* DCD */ | ||
| 44 | #define RNG_IP 20 /* RNG */ | ||
| 45 | |||
| 46 | #define DIR_OP 24 /* Special signal for control RS-485. | ||
| 47 | * Goes high when transmit, | ||
| 48 | * then goes low. | ||
| 49 | */ | ||
| 50 | |||
| 51 | /* Routing control signal 'sig' to line 'line' */ | ||
| 52 | #define MCTRL_SIG(sig, line) ((line) << (sig)) | ||
| 53 | |||
| 54 | /* | ||
| 55 | * Example board initialization data: | ||
| 56 | * | ||
| 57 | * static struct resource sc2892_resources[] = { | ||
| 58 | * DEFINE_RES_MEM(UART_PHYS_START, 0x10), | ||
| 59 | * DEFINE_RES_IRQ(IRQ_EXT2), | ||
| 60 | * }; | ||
| 61 | * | ||
| 62 | * static struct sccnxp_pdata sc2892_info = { | ||
| 63 | * .frequency = 3686400, | ||
| 64 | * .mctrl_cfg[0] = MCTRL_SIG(DIR_OP, LINE_OP0), | ||
| 65 | * .mctrl_cfg[1] = MCTRL_SIG(DIR_OP, LINE_OP1), | ||
| 66 | * }; | ||
| 67 | * | ||
| 68 | * static struct platform_device sc2892 = { | ||
| 69 | * .name = "sc2892", | ||
| 70 | * .id = -1, | ||
| 71 | * .resource = sc2892_resources, | ||
| 72 | * .num_resources = ARRAY_SIZE(sc2892_resources), | ||
| 73 | * .dev = { | ||
| 74 | * .platform_data = &sc2892_info, | ||
| 75 | * }, | ||
| 76 | * }; | ||
| 77 | */ | ||
| 78 | |||
| 79 | /* SCCNXP platform data structure */ | ||
| 80 | struct sccnxp_pdata { | ||
| 81 | /* Frequency (extrenal clock or crystal) */ | ||
| 82 | int frequency; | ||
| 83 | /* Shift for A0 line */ | ||
| 84 | const u8 reg_shift; | ||
| 85 | /* Modem control lines configuration */ | ||
| 86 | const u32 mctrl_cfg[SCCNXP_MAX_UARTS]; | ||
| 87 | /* Called during startup */ | ||
| 88 | void (*init)(void); | ||
| 89 | /* Called before finish */ | ||
| 90 | void (*exit)(void); | ||
| 91 | }; | ||
| 92 | |||
| 93 | #endif | ||
diff --git a/include/linux/sc26198.h b/include/linux/sc26198.h deleted file mode 100644 index 7ca35abad387..000000000000 --- a/include/linux/sc26198.h +++ /dev/null | |||
| @@ -1,533 +0,0 @@ | |||
| 1 | /*****************************************************************************/ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * sc26198.h -- SC26198 UART hardware info. | ||
| 5 | * | ||
| 6 | * Copyright (C) 1995-1998 Stallion Technologies | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 21 | */ | ||
| 22 | |||
| 23 | /*****************************************************************************/ | ||
| 24 | #ifndef _SC26198_H | ||
| 25 | #define _SC26198_H | ||
| 26 | /*****************************************************************************/ | ||
| 27 | |||
| 28 | /* | ||
| 29 | * Define the number of async ports per sc26198 uart device. | ||
| 30 | */ | ||
| 31 | #define SC26198_PORTS 8 | ||
| 32 | |||
| 33 | /* | ||
| 34 | * Baud rate timing clocks. All derived from a master 14.7456 MHz clock. | ||
| 35 | */ | ||
| 36 | #define SC26198_MASTERCLOCK 14745600L | ||
| 37 | #define SC26198_DCLK (SC26198_MASTERCLOCK) | ||
| 38 | #define SC26198_CCLK (SC26198_MASTERCLOCK / 2) | ||
| 39 | #define SC26198_BCLK (SC26198_MASTERCLOCK / 4) | ||
| 40 | |||
| 41 | /* | ||
| 42 | * Define internal FIFO sizes for the 26198 ports. | ||
| 43 | */ | ||
| 44 | #define SC26198_TXFIFOSIZE 16 | ||
| 45 | #define SC26198_RXFIFOSIZE 16 | ||
| 46 | |||
| 47 | /*****************************************************************************/ | ||
| 48 | |||
| 49 | /* | ||
| 50 | * Global register definitions. These registers are global to each 26198 | ||
| 51 | * device, not specific ports on it. | ||
| 52 | */ | ||
| 53 | #define TSTR 0x0d | ||
| 54 | #define GCCR 0x0f | ||
| 55 | #define ICR 0x1b | ||
| 56 | #define WDTRCR 0x1d | ||
| 57 | #define IVR 0x1f | ||
| 58 | #define BRGTRUA 0x84 | ||
| 59 | #define GPOSR 0x87 | ||
| 60 | #define GPOC 0x8b | ||
| 61 | #define UCIR 0x8c | ||
| 62 | #define CIR 0x8c | ||
| 63 | #define BRGTRUB 0x8d | ||
| 64 | #define GRXFIFO 0x8e | ||
| 65 | #define GTXFIFO 0x8e | ||
| 66 | #define GCCR2 0x8f | ||
| 67 | #define BRGTRLA 0x94 | ||
| 68 | #define GPOR 0x97 | ||
| 69 | #define GPOD 0x9b | ||
| 70 | #define BRGTCR 0x9c | ||
| 71 | #define GICR 0x9c | ||
| 72 | #define BRGTRLB 0x9d | ||
| 73 | #define GIBCR 0x9d | ||
| 74 | #define GITR 0x9f | ||
| 75 | |||
| 76 | /* | ||
| 77 | * Per port channel registers. These are the register offsets within | ||
| 78 | * the port address space, so need to have the port address (0 to 7) | ||
| 79 | * inserted in bit positions 4:6. | ||
| 80 | */ | ||
| 81 | #define MR0 0x00 | ||
| 82 | #define MR1 0x01 | ||
| 83 | #define IOPCR 0x02 | ||
| 84 | #define BCRBRK 0x03 | ||
| 85 | #define BCRCOS 0x04 | ||
| 86 | #define BCRX 0x06 | ||
| 87 | #define BCRA 0x07 | ||
| 88 | #define XONCR 0x08 | ||
| 89 | #define XOFFCR 0x09 | ||
| 90 | #define ARCR 0x0a | ||
| 91 | #define RXCSR 0x0c | ||
| 92 | #define TXCSR 0x0e | ||
| 93 | #define MR2 0x80 | ||
| 94 | #define SR 0x81 | ||
| 95 | #define SCCR 0x81 | ||
| 96 | #define ISR 0x82 | ||
| 97 | #define IMR 0x82 | ||
| 98 | #define TXFIFO 0x83 | ||
| 99 | #define RXFIFO 0x83 | ||
| 100 | #define IPR 0x84 | ||
| 101 | #define IOPIOR 0x85 | ||
| 102 | #define XISR 0x86 | ||
| 103 | |||
| 104 | /* | ||
| 105 | * For any given port calculate the address to use to access a specified | ||
| 106 | * register. This is only used for unusual access, mostly this is done | ||
| 107 | * through the assembler access routines. | ||
| 108 | */ | ||
| 109 | #define SC26198_PORTREG(port,reg) ((((port) & 0x07) << 4) | (reg)) | ||
| 110 | |||
| 111 | /*****************************************************************************/ | ||
| 112 | |||
| 113 | /* | ||
| 114 | * Global configuration control register bit definitions. | ||
| 115 | */ | ||
| 116 | #define GCCR_NOACK 0x00 | ||
| 117 | #define GCCR_IVRACK 0x02 | ||
| 118 | #define GCCR_IVRCHANACK 0x04 | ||
| 119 | #define GCCR_IVRTYPCHANACK 0x06 | ||
| 120 | #define GCCR_ASYNCCYCLE 0x00 | ||
| 121 | #define GCCR_SYNCCYCLE 0x40 | ||
| 122 | |||
| 123 | /*****************************************************************************/ | ||
| 124 | |||
| 125 | /* | ||
| 126 | * Mode register 0 bit definitions. | ||
| 127 | */ | ||
| 128 | #define MR0_ADDRNONE 0x00 | ||
| 129 | #define MR0_AUTOWAKE 0x01 | ||
| 130 | #define MR0_AUTODOZE 0x02 | ||
| 131 | #define MR0_AUTOWAKEDOZE 0x03 | ||
| 132 | #define MR0_SWFNONE 0x00 | ||
| 133 | #define MR0_SWFTX 0x04 | ||
| 134 | #define MR0_SWFRX 0x08 | ||
| 135 | #define MR0_SWFRXTX 0x0c | ||
| 136 | #define MR0_TXMASK 0x30 | ||
| 137 | #define MR0_TXEMPTY 0x00 | ||
| 138 | #define MR0_TXHIGH 0x10 | ||
| 139 | #define MR0_TXHALF 0x20 | ||
| 140 | #define MR0_TXRDY 0x00 | ||
| 141 | #define MR0_ADDRNT 0x00 | ||
| 142 | #define MR0_ADDRT 0x40 | ||
| 143 | #define MR0_SWFNT 0x00 | ||
| 144 | #define MR0_SWFT 0x80 | ||
| 145 | |||
| 146 | /* | ||
| 147 | * Mode register 1 bit definitions. | ||
| 148 | */ | ||
| 149 | #define MR1_CS5 0x00 | ||
| 150 | #define MR1_CS6 0x01 | ||
| 151 | #define MR1_CS7 0x02 | ||
| 152 | #define MR1_CS8 0x03 | ||
| 153 | #define MR1_PAREVEN 0x00 | ||
| 154 | #define MR1_PARODD 0x04 | ||
| 155 | #define MR1_PARENB 0x00 | ||
| 156 | #define MR1_PARFORCE 0x08 | ||
| 157 | #define MR1_PARNONE 0x10 | ||
| 158 | #define MR1_PARSPECIAL 0x18 | ||
| 159 | #define MR1_ERRCHAR 0x00 | ||
| 160 | #define MR1_ERRBLOCK 0x20 | ||
| 161 | #define MR1_ISRUNMASKED 0x00 | ||
| 162 | #define MR1_ISRMASKED 0x40 | ||
| 163 | #define MR1_AUTORTS 0x80 | ||
| 164 | |||
| 165 | /* | ||
| 166 | * Mode register 2 bit definitions. | ||
| 167 | */ | ||
| 168 | #define MR2_STOP1 0x00 | ||
| 169 | #define MR2_STOP15 0x01 | ||
| 170 | #define MR2_STOP2 0x02 | ||
| 171 | #define MR2_STOP916 0x03 | ||
| 172 | #define MR2_RXFIFORDY 0x00 | ||
| 173 | #define MR2_RXFIFOHALF 0x04 | ||
| 174 | #define MR2_RXFIFOHIGH 0x08 | ||
| 175 | #define MR2_RXFIFOFULL 0x0c | ||
| 176 | #define MR2_AUTOCTS 0x10 | ||
| 177 | #define MR2_TXRTS 0x20 | ||
| 178 | #define MR2_MODENORM 0x00 | ||
| 179 | #define MR2_MODEAUTOECHO 0x40 | ||
| 180 | #define MR2_MODELOOP 0x80 | ||
| 181 | #define MR2_MODEREMECHO 0xc0 | ||
| 182 | |||
| 183 | /*****************************************************************************/ | ||
| 184 | |||
| 185 | /* | ||
| 186 | * Baud Rate Generator (BRG) selector values. | ||
| 187 | */ | ||
| 188 | #define BRG_50 0x00 | ||
| 189 | #define BRG_75 0x01 | ||
| 190 | #define BRG_150 0x02 | ||
| 191 | #define BRG_200 0x03 | ||
| 192 | #define BRG_300 0x04 | ||
| 193 | #define BRG_450 0x05 | ||
| 194 | #define BRG_600 0x06 | ||
| 195 | #define BRG_900 0x07 | ||
| 196 | #define BRG_1200 0x08 | ||
| 197 | #define BRG_1800 0x09 | ||
| 198 | #define BRG_2400 0x0a | ||
| 199 | #define BRG_3600 0x0b | ||
| 200 | #define BRG_4800 0x0c | ||
| 201 | #define BRG_7200 0x0d | ||
| 202 | #define BRG_9600 0x0e | ||
| 203 | #define BRG_14400 0x0f | ||
| 204 | #define BRG_19200 0x10 | ||
| 205 | #define BRG_28200 0x11 | ||
| 206 | #define BRG_38400 0x12 | ||
| 207 | #define BRG_57600 0x13 | ||
| 208 | #define BRG_115200 0x14 | ||
| 209 | #define BRG_230400 0x15 | ||
| 210 | #define BRG_GIN0 0x16 | ||
| 211 | #define BRG_GIN1 0x17 | ||
| 212 | #define BRG_CT0 0x18 | ||
| 213 | #define BRG_CT1 0x19 | ||
| 214 | #define BRG_RX2TX316 0x1b | ||
| 215 | #define BRG_RX2TX31 0x1c | ||
| 216 | |||
| 217 | #define SC26198_MAXBAUD 921600 | ||
| 218 | |||
| 219 | /*****************************************************************************/ | ||
| 220 | |||
| 221 | /* | ||
| 222 | * Command register command definitions. | ||
| 223 | */ | ||
| 224 | #define CR_NULL 0x04 | ||
| 225 | #define CR_ADDRNORMAL 0x0c | ||
| 226 | #define CR_RXRESET 0x14 | ||
| 227 | #define CR_TXRESET 0x1c | ||
| 228 | #define CR_CLEARRXERR 0x24 | ||
| 229 | #define CR_BREAKRESET 0x2c | ||
| 230 | #define CR_TXSTARTBREAK 0x34 | ||
| 231 | #define CR_TXSTOPBREAK 0x3c | ||
| 232 | #define CR_RTSON 0x44 | ||
| 233 | #define CR_RTSOFF 0x4c | ||
| 234 | #define CR_ADDRINIT 0x5c | ||
| 235 | #define CR_RXERRBLOCK 0x6c | ||
| 236 | #define CR_TXSENDXON 0x84 | ||
| 237 | #define CR_TXSENDXOFF 0x8c | ||
| 238 | #define CR_GANGXONSET 0x94 | ||
| 239 | #define CR_GANGXOFFSET 0x9c | ||
| 240 | #define CR_GANGXONINIT 0xa4 | ||
| 241 | #define CR_GANGXOFFINIT 0xac | ||
| 242 | #define CR_HOSTXON 0xb4 | ||
| 243 | #define CR_HOSTXOFF 0xbc | ||
| 244 | #define CR_CANCELXOFF 0xc4 | ||
| 245 | #define CR_ADDRRESET 0xdc | ||
| 246 | #define CR_RESETALLPORTS 0xf4 | ||
| 247 | #define CR_RESETALL 0xfc | ||
| 248 | |||
| 249 | #define CR_RXENABLE 0x01 | ||
| 250 | #define CR_TXENABLE 0x02 | ||
| 251 | |||
| 252 | /*****************************************************************************/ | ||
| 253 | |||
| 254 | /* | ||
| 255 | * Channel status register. | ||
| 256 | */ | ||
| 257 | #define SR_RXRDY 0x01 | ||
| 258 | #define SR_RXFULL 0x02 | ||
| 259 | #define SR_TXRDY 0x04 | ||
| 260 | #define SR_TXEMPTY 0x08 | ||
| 261 | #define SR_RXOVERRUN 0x10 | ||
| 262 | #define SR_RXPARITY 0x20 | ||
| 263 | #define SR_RXFRAMING 0x40 | ||
| 264 | #define SR_RXBREAK 0x80 | ||
| 265 | |||
| 266 | #define SR_RXERRS (SR_RXPARITY | SR_RXFRAMING | SR_RXOVERRUN) | ||
| 267 | |||
| 268 | /*****************************************************************************/ | ||
| 269 | |||
| 270 | /* | ||
| 271 | * Interrupt status register and interrupt mask register bit definitions. | ||
| 272 | */ | ||
| 273 | #define IR_TXRDY 0x01 | ||
| 274 | #define IR_RXRDY 0x02 | ||
| 275 | #define IR_RXBREAK 0x04 | ||
| 276 | #define IR_XONXOFF 0x10 | ||
| 277 | #define IR_ADDRRECOG 0x20 | ||
| 278 | #define IR_RXWATCHDOG 0x40 | ||
| 279 | #define IR_IOPORT 0x80 | ||
| 280 | |||
| 281 | /*****************************************************************************/ | ||
| 282 | |||
| 283 | /* | ||
| 284 | * Interrupt vector register field definitions. | ||
| 285 | */ | ||
| 286 | #define IVR_CHANMASK 0x07 | ||
| 287 | #define IVR_TYPEMASK 0x18 | ||
| 288 | #define IVR_CONSTMASK 0xc0 | ||
| 289 | |||
| 290 | #define IVR_RXDATA 0x10 | ||
| 291 | #define IVR_RXBADDATA 0x18 | ||
| 292 | #define IVR_TXDATA 0x08 | ||
| 293 | #define IVR_OTHER 0x00 | ||
| 294 | |||
| 295 | /*****************************************************************************/ | ||
| 296 | |||
| 297 | /* | ||
| 298 | * BRG timer control register bit definitions. | ||
| 299 | */ | ||
| 300 | #define BRGCTCR_DISABCLK0 0x00 | ||
| 301 | #define BRGCTCR_ENABCLK0 0x08 | ||
| 302 | #define BRGCTCR_DISABCLK1 0x00 | ||
| 303 | #define BRGCTCR_ENABCLK1 0x80 | ||
| 304 | |||
| 305 | #define BRGCTCR_0SCLK16 0x00 | ||
| 306 | #define BRGCTCR_0SCLK32 0x01 | ||
| 307 | #define BRGCTCR_0SCLK64 0x02 | ||
| 308 | #define BRGCTCR_0SCLK128 0x03 | ||
| 309 | #define BRGCTCR_0X1 0x04 | ||
| 310 | #define BRGCTCR_0X12 0x05 | ||
| 311 | #define BRGCTCR_0IO1A 0x06 | ||
| 312 | #define BRGCTCR_0GIN0 0x07 | ||
| 313 | |||
| 314 | #define BRGCTCR_1SCLK16 0x00 | ||
| 315 | #define BRGCTCR_1SCLK32 0x10 | ||
| 316 | #define BRGCTCR_1SCLK64 0x20 | ||
| 317 | #define BRGCTCR_1SCLK128 0x30 | ||
| 318 | #define BRGCTCR_1X1 0x40 | ||
| 319 | #define BRGCTCR_1X12 0x50 | ||
| 320 | #define BRGCTCR_1IO1B 0x60 | ||
| 321 | #define BRGCTCR_1GIN1 0x70 | ||
| 322 | |||
| 323 | /*****************************************************************************/ | ||
| 324 | |||
| 325 | /* | ||
| 326 | * Watch dog timer enable register. | ||
| 327 | */ | ||
| 328 | #define WDTRCR_ENABALL 0xff | ||
| 329 | |||
| 330 | /*****************************************************************************/ | ||
| 331 | |||
| 332 | /* | ||
| 333 | * XON/XOFF interrupt status register. | ||
| 334 | */ | ||
| 335 | #define XISR_TXCHARMASK 0x03 | ||
| 336 | #define XISR_TXCHARNORMAL 0x00 | ||
| 337 | #define XISR_TXWAIT 0x01 | ||
| 338 | #define XISR_TXXOFFPEND 0x02 | ||
| 339 | #define XISR_TXXONPEND 0x03 | ||
| 340 | |||
| 341 | #define XISR_TXFLOWMASK 0x0c | ||
| 342 | #define XISR_TXNORMAL 0x00 | ||
| 343 | #define XISR_TXSTOPPEND 0x04 | ||
| 344 | #define XISR_TXSTARTED 0x08 | ||
| 345 | #define XISR_TXSTOPPED 0x0c | ||
| 346 | |||
| 347 | #define XISR_RXFLOWMASK 0x30 | ||
| 348 | #define XISR_RXFLOWNONE 0x00 | ||
| 349 | #define XISR_RXXONSENT 0x10 | ||
| 350 | #define XISR_RXXOFFSENT 0x20 | ||
| 351 | |||
| 352 | #define XISR_RXXONGOT 0x40 | ||
| 353 | #define XISR_RXXOFFGOT 0x80 | ||
| 354 | |||
| 355 | /*****************************************************************************/ | ||
| 356 | |||
| 357 | /* | ||
| 358 | * Current interrupt register. | ||
| 359 | */ | ||
| 360 | #define CIR_TYPEMASK 0xc0 | ||
| 361 | #define CIR_TYPEOTHER 0x00 | ||
| 362 | #define CIR_TYPETX 0x40 | ||
| 363 | #define CIR_TYPERXGOOD 0x80 | ||
| 364 | #define CIR_TYPERXBAD 0xc0 | ||
| 365 | |||
| 366 | #define CIR_RXDATA 0x80 | ||
| 367 | #define CIR_RXBADDATA 0x40 | ||
| 368 | #define CIR_TXDATA 0x40 | ||
| 369 | |||
| 370 | #define CIR_CHANMASK 0x07 | ||
| 371 | #define CIR_CNTMASK 0x38 | ||
| 372 | |||
| 373 | #define CIR_SUBTYPEMASK 0x38 | ||
| 374 | #define CIR_SUBNONE 0x00 | ||
| 375 | #define CIR_SUBCOS 0x08 | ||
| 376 | #define CIR_SUBADDR 0x10 | ||
| 377 | #define CIR_SUBXONXOFF 0x18 | ||
| 378 | #define CIR_SUBBREAK 0x28 | ||
| 379 | |||
| 380 | /*****************************************************************************/ | ||
| 381 | |||
| 382 | /* | ||
| 383 | * Global interrupting channel register. | ||
| 384 | */ | ||
| 385 | #define GICR_CHANMASK 0x07 | ||
| 386 | |||
| 387 | /*****************************************************************************/ | ||
| 388 | |||
| 389 | /* | ||
| 390 | * Global interrupting byte count register. | ||
| 391 | */ | ||
| 392 | #define GICR_COUNTMASK 0x0f | ||
| 393 | |||
| 394 | /*****************************************************************************/ | ||
| 395 | |||
| 396 | /* | ||
| 397 | * Global interrupting type register. | ||
| 398 | */ | ||
| 399 | #define GITR_RXMASK 0xc0 | ||
| 400 | #define GITR_RXNONE 0x00 | ||
| 401 | #define GITR_RXBADDATA 0x80 | ||
| 402 | #define GITR_RXGOODDATA 0xc0 | ||
| 403 | #define GITR_TXDATA 0x20 | ||
| 404 | |||
| 405 | #define GITR_SUBTYPEMASK 0x07 | ||
| 406 | #define GITR_SUBNONE 0x00 | ||
| 407 | #define GITR_SUBCOS 0x01 | ||
| 408 | #define GITR_SUBADDR 0x02 | ||
| 409 | #define GITR_SUBXONXOFF 0x03 | ||
| 410 | #define GITR_SUBBREAK 0x05 | ||
| 411 | |||
| 412 | /*****************************************************************************/ | ||
| 413 | |||
| 414 | /* | ||
| 415 | * Input port change register. | ||
| 416 | */ | ||
| 417 | #define IPR_CTS 0x01 | ||
| 418 | #define IPR_DTR 0x02 | ||
| 419 | #define IPR_RTS 0x04 | ||
| 420 | #define IPR_DCD 0x08 | ||
| 421 | #define IPR_CTSCHANGE 0x10 | ||
| 422 | #define IPR_DTRCHANGE 0x20 | ||
| 423 | #define IPR_RTSCHANGE 0x40 | ||
| 424 | #define IPR_DCDCHANGE 0x80 | ||
| 425 | |||
| 426 | #define IPR_CHANGEMASK 0xf0 | ||
| 427 | |||
| 428 | /*****************************************************************************/ | ||
| 429 | |||
| 430 | /* | ||
| 431 | * IO port interrupt and output register. | ||
| 432 | */ | ||
| 433 | #define IOPR_CTS 0x01 | ||
| 434 | #define IOPR_DTR 0x02 | ||
| 435 | #define IOPR_RTS 0x04 | ||
| 436 | #define IOPR_DCD 0x08 | ||
| 437 | #define IOPR_CTSCOS 0x10 | ||
| 438 | #define IOPR_DTRCOS 0x20 | ||
| 439 | #define IOPR_RTSCOS 0x40 | ||
| 440 | #define IOPR_DCDCOS 0x80 | ||
| 441 | |||
| 442 | /*****************************************************************************/ | ||
| 443 | |||
| 444 | /* | ||
| 445 | * IO port configuration register. | ||
| 446 | */ | ||
| 447 | #define IOPCR_SETCTS 0x00 | ||
| 448 | #define IOPCR_SETDTR 0x04 | ||
| 449 | #define IOPCR_SETRTS 0x10 | ||
| 450 | #define IOPCR_SETDCD 0x00 | ||
| 451 | |||
| 452 | #define IOPCR_SETSIGS (IOPCR_SETRTS | IOPCR_SETRTS | IOPCR_SETDTR | IOPCR_SETDCD) | ||
| 453 | |||
| 454 | /*****************************************************************************/ | ||
| 455 | |||
| 456 | /* | ||
| 457 | * General purpose output select register. | ||
| 458 | */ | ||
| 459 | #define GPORS_TXC1XA 0x08 | ||
| 460 | #define GPORS_TXC16XA 0x09 | ||
| 461 | #define GPORS_RXC16XA 0x0a | ||
| 462 | #define GPORS_TXC16XB 0x0b | ||
| 463 | #define GPORS_GPOR3 0x0c | ||
| 464 | #define GPORS_GPOR2 0x0d | ||
| 465 | #define GPORS_GPOR1 0x0e | ||
| 466 | #define GPORS_GPOR0 0x0f | ||
| 467 | |||
| 468 | /*****************************************************************************/ | ||
| 469 | |||
| 470 | /* | ||
| 471 | * General purpose output register. | ||
| 472 | */ | ||
| 473 | #define GPOR_0 0x01 | ||
| 474 | #define GPOR_1 0x02 | ||
| 475 | #define GPOR_2 0x04 | ||
| 476 | #define GPOR_3 0x08 | ||
| 477 | |||
| 478 | /*****************************************************************************/ | ||
| 479 | |||
| 480 | /* | ||
| 481 | * General purpose output clock register. | ||
| 482 | */ | ||
| 483 | #define GPORC_0NONE 0x00 | ||
| 484 | #define GPORC_0GIN0 0x01 | ||
| 485 | #define GPORC_0GIN1 0x02 | ||
| 486 | #define GPORC_0IO3A 0x02 | ||
| 487 | |||
| 488 | #define GPORC_1NONE 0x00 | ||
| 489 | #define GPORC_1GIN0 0x04 | ||
| 490 | #define GPORC_1GIN1 0x08 | ||
| 491 | #define GPORC_1IO3C 0x0c | ||
| 492 | |||
| 493 | #define GPORC_2NONE 0x00 | ||
| 494 | #define GPORC_2GIN0 0x10 | ||
| 495 | #define GPORC_2GIN1 0x20 | ||
| 496 | #define GPORC_2IO3E 0x20 | ||
| 497 | |||
| 498 | #define GPORC_3NONE 0x00 | ||
| 499 | #define GPORC_3GIN0 0x40 | ||
| 500 | #define GPORC_3GIN1 0x80 | ||
| 501 | #define GPORC_3IO3G 0xc0 | ||
| 502 | |||
| 503 | /*****************************************************************************/ | ||
| 504 | |||
| 505 | /* | ||
| 506 | * General purpose output data register. | ||
| 507 | */ | ||
| 508 | #define GPOD_0MASK 0x03 | ||
| 509 | #define GPOD_0SET1 0x00 | ||
| 510 | #define GPOD_0SET0 0x01 | ||
| 511 | #define GPOD_0SETR0 0x02 | ||
| 512 | #define GPOD_0SETIO3B 0x03 | ||
| 513 | |||
| 514 | #define GPOD_1MASK 0x0c | ||
| 515 | #define GPOD_1SET1 0x00 | ||
| 516 | #define GPOD_1SET0 0x04 | ||
| 517 | #define GPOD_1SETR0 0x08 | ||
| 518 | #define GPOD_1SETIO3D 0x0c | ||
| 519 | |||
| 520 | #define GPOD_2MASK 0x30 | ||
| 521 | #define GPOD_2SET1 0x00 | ||
| 522 | #define GPOD_2SET0 0x10 | ||
| 523 | #define GPOD_2SETR0 0x20 | ||
| 524 | #define GPOD_2SETIO3F 0x30 | ||
| 525 | |||
| 526 | #define GPOD_3MASK 0xc0 | ||
| 527 | #define GPOD_3SET1 0x00 | ||
| 528 | #define GPOD_3SET0 0x40 | ||
| 529 | #define GPOD_3SETR0 0x80 | ||
| 530 | #define GPOD_3SETIO3H 0xc0 | ||
| 531 | |||
| 532 | /*****************************************************************************/ | ||
| 533 | #endif | ||
diff --git a/include/linux/serial.h b/include/linux/serial.h index 90e9f981358a..861e51de476b 100644 --- a/include/linux/serial.h +++ b/include/linux/serial.h | |||
| @@ -12,9 +12,12 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
| 14 | 14 | ||
| 15 | #include <linux/tty_flags.h> | ||
| 16 | |||
| 15 | #ifdef __KERNEL__ | 17 | #ifdef __KERNEL__ |
| 16 | #include <asm/page.h> | 18 | #include <asm/page.h> |
| 17 | 19 | ||
| 20 | |||
| 18 | /* | 21 | /* |
| 19 | * Counters of the input lines (CTS, DSR, RI, CD) interrupts | 22 | * Counters of the input lines (CTS, DSR, RI, CD) interrupts |
| 20 | */ | 23 | */ |
| @@ -83,89 +86,11 @@ struct serial_struct { | |||
| 83 | #define SERIAL_IO_HUB6 1 | 86 | #define SERIAL_IO_HUB6 1 |
| 84 | #define SERIAL_IO_MEM 2 | 87 | #define SERIAL_IO_MEM 2 |
| 85 | 88 | ||
| 86 | struct serial_uart_config { | ||
| 87 | char *name; | ||
| 88 | int dfl_xmit_fifo_size; | ||
| 89 | int flags; | ||
| 90 | }; | ||
| 91 | |||
| 92 | #define UART_CLEAR_FIFO 0x01 | 89 | #define UART_CLEAR_FIFO 0x01 |
| 93 | #define UART_USE_FIFO 0x02 | 90 | #define UART_USE_FIFO 0x02 |
| 94 | #define UART_STARTECH 0x04 | 91 | #define UART_STARTECH 0x04 |
| 95 | #define UART_NATSEMI 0x08 | 92 | #define UART_NATSEMI 0x08 |
| 96 | 93 | ||
| 97 | /* | ||
| 98 | * Definitions for async_struct (and serial_struct) flags field | ||
| 99 | * | ||
| 100 | * Define ASYNCB_* for convenient use with {test,set,clear}_bit. | ||
| 101 | */ | ||
| 102 | #define ASYNCB_HUP_NOTIFY 0 /* Notify getty on hangups and closes | ||
| 103 | * on the callout port */ | ||
| 104 | #define ASYNCB_FOURPORT 1 /* Set OU1, OUT2 per AST Fourport settings */ | ||
| 105 | #define ASYNCB_SAK 2 /* Secure Attention Key (Orange book) */ | ||
| 106 | #define ASYNCB_SPLIT_TERMIOS 3 /* Separate termios for dialin/callout */ | ||
| 107 | #define ASYNCB_SPD_HI 4 /* Use 56000 instead of 38400 bps */ | ||
| 108 | #define ASYNCB_SPD_VHI 5 /* Use 115200 instead of 38400 bps */ | ||
| 109 | #define ASYNCB_SKIP_TEST 6 /* Skip UART test during autoconfiguration */ | ||
| 110 | #define ASYNCB_AUTO_IRQ 7 /* Do automatic IRQ during | ||
| 111 | * autoconfiguration */ | ||
| 112 | #define ASYNCB_SESSION_LOCKOUT 8 /* Lock out cua opens based on session */ | ||
| 113 | #define ASYNCB_PGRP_LOCKOUT 9 /* Lock out cua opens based on pgrp */ | ||
| 114 | #define ASYNCB_CALLOUT_NOHUP 10 /* Don't do hangups for cua device */ | ||
| 115 | #define ASYNCB_HARDPPS_CD 11 /* Call hardpps when CD goes high */ | ||
| 116 | #define ASYNCB_SPD_SHI 12 /* Use 230400 instead of 38400 bps */ | ||
| 117 | #define ASYNCB_LOW_LATENCY 13 /* Request low latency behaviour */ | ||
| 118 | #define ASYNCB_BUGGY_UART 14 /* This is a buggy UART, skip some safety | ||
| 119 | * checks. Note: can be dangerous! */ | ||
| 120 | #define ASYNCB_AUTOPROBE 15 /* Port was autoprobed by PCI or PNP code */ | ||
| 121 | #define ASYNCB_LAST_USER 15 | ||
| 122 | |||
| 123 | /* Internal flags used only by kernel */ | ||
| 124 | #define ASYNCB_INITIALIZED 31 /* Serial port was initialized */ | ||
| 125 | #define ASYNCB_SUSPENDED 30 /* Serial port is suspended */ | ||
| 126 | #define ASYNCB_NORMAL_ACTIVE 29 /* Normal device is active */ | ||
| 127 | #define ASYNCB_BOOT_AUTOCONF 28 /* Autoconfigure port on bootup */ | ||
| 128 | #define ASYNCB_CLOSING 27 /* Serial port is closing */ | ||
| 129 | #define ASYNCB_CTS_FLOW 26 /* Do CTS flow control */ | ||
| 130 | #define ASYNCB_CHECK_CD 25 /* i.e., CLOCAL */ | ||
| 131 | #define ASYNCB_SHARE_IRQ 24 /* for multifunction cards, no longer used */ | ||
| 132 | #define ASYNCB_CONS_FLOW 23 /* flow control for console */ | ||
| 133 | #define ASYNCB_FIRST_KERNEL 22 | ||
| 134 | |||
| 135 | #define ASYNC_HUP_NOTIFY (1U << ASYNCB_HUP_NOTIFY) | ||
| 136 | #define ASYNC_SUSPENDED (1U << ASYNCB_SUSPENDED) | ||
| 137 | #define ASYNC_FOURPORT (1U << ASYNCB_FOURPORT) | ||
| 138 | #define ASYNC_SAK (1U << ASYNCB_SAK) | ||
| 139 | #define ASYNC_SPLIT_TERMIOS (1U << ASYNCB_SPLIT_TERMIOS) | ||
| 140 | #define ASYNC_SPD_HI (1U << ASYNCB_SPD_HI) | ||
| 141 | #define ASYNC_SPD_VHI (1U << ASYNCB_SPD_VHI) | ||
| 142 | #define ASYNC_SKIP_TEST (1U << ASYNCB_SKIP_TEST) | ||
| 143 | #define ASYNC_AUTO_IRQ (1U << ASYNCB_AUTO_IRQ) | ||
| 144 | #define ASYNC_SESSION_LOCKOUT (1U << ASYNCB_SESSION_LOCKOUT) | ||
| 145 | #define ASYNC_PGRP_LOCKOUT (1U << ASYNCB_PGRP_LOCKOUT) | ||
| 146 | #define ASYNC_CALLOUT_NOHUP (1U << ASYNCB_CALLOUT_NOHUP) | ||
| 147 | #define ASYNC_HARDPPS_CD (1U << ASYNCB_HARDPPS_CD) | ||
| 148 | #define ASYNC_SPD_SHI (1U << ASYNCB_SPD_SHI) | ||
| 149 | #define ASYNC_LOW_LATENCY (1U << ASYNCB_LOW_LATENCY) | ||
| 150 | #define ASYNC_BUGGY_UART (1U << ASYNCB_BUGGY_UART) | ||
| 151 | #define ASYNC_AUTOPROBE (1U << ASYNCB_AUTOPROBE) | ||
| 152 | |||
| 153 | #define ASYNC_FLAGS ((1U << (ASYNCB_LAST_USER + 1)) - 1) | ||
| 154 | #define ASYNC_USR_MASK (ASYNC_SPD_MASK|ASYNC_CALLOUT_NOHUP| \ | ||
| 155 | ASYNC_LOW_LATENCY) | ||
| 156 | #define ASYNC_SPD_CUST (ASYNC_SPD_HI|ASYNC_SPD_VHI) | ||
| 157 | #define ASYNC_SPD_WARP (ASYNC_SPD_HI|ASYNC_SPD_SHI) | ||
| 158 | #define ASYNC_SPD_MASK (ASYNC_SPD_HI|ASYNC_SPD_VHI|ASYNC_SPD_SHI) | ||
| 159 | |||
| 160 | #define ASYNC_INITIALIZED (1U << ASYNCB_INITIALIZED) | ||
| 161 | #define ASYNC_NORMAL_ACTIVE (1U << ASYNCB_NORMAL_ACTIVE) | ||
| 162 | #define ASYNC_BOOT_AUTOCONF (1U << ASYNCB_BOOT_AUTOCONF) | ||
| 163 | #define ASYNC_CLOSING (1U << ASYNCB_CLOSING) | ||
| 164 | #define ASYNC_CTS_FLOW (1U << ASYNCB_CTS_FLOW) | ||
| 165 | #define ASYNC_CHECK_CD (1U << ASYNCB_CHECK_CD) | ||
| 166 | #define ASYNC_SHARE_IRQ (1U << ASYNCB_SHARE_IRQ) | ||
| 167 | #define ASYNC_CONS_FLOW (1U << ASYNCB_CONS_FLOW) | ||
| 168 | #define ASYNC_INTERNAL_FLAGS (~((1U << ASYNCB_FIRST_KERNEL) - 1)) | ||
| 169 | 94 | ||
| 170 | /* | 95 | /* |
| 171 | * Multiport serial configuration structure --- external structure | 96 | * Multiport serial configuration structure --- external structure |
diff --git a/include/linux/serial167.h b/include/linux/serial167.h deleted file mode 100644 index 59c81b708562..000000000000 --- a/include/linux/serial167.h +++ /dev/null | |||
| @@ -1,157 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * serial167.h | ||
| 3 | * | ||
| 4 | * Richard Hirst [richard@sleepie.demon.co.uk] | ||
| 5 | * | ||
| 6 | * Based on cyclades.h | ||
| 7 | */ | ||
| 8 | |||
| 9 | struct cyclades_monitor { | ||
| 10 | unsigned long int_count; | ||
| 11 | unsigned long char_count; | ||
| 12 | unsigned long char_max; | ||
| 13 | unsigned long char_last; | ||
| 14 | }; | ||
| 15 | |||
| 16 | /* | ||
| 17 | * This is our internal structure for each serial port's state. | ||
| 18 | * | ||
| 19 | * Many fields are paralleled by the structure used by the serial_struct | ||
| 20 | * structure. | ||
| 21 | * | ||
| 22 | * For definitions of the flags field, see tty.h | ||
| 23 | */ | ||
| 24 | |||
| 25 | struct cyclades_port { | ||
| 26 | int magic; | ||
| 27 | int type; | ||
| 28 | int card; | ||
| 29 | int line; | ||
| 30 | int flags; /* defined in tty.h */ | ||
| 31 | struct tty_struct *tty; | ||
| 32 | int read_status_mask; | ||
| 33 | int timeout; | ||
| 34 | int xmit_fifo_size; | ||
| 35 | int cor1,cor2,cor3,cor4,cor5,cor6,cor7; | ||
| 36 | int tbpr,tco,rbpr,rco; | ||
| 37 | int ignore_status_mask; | ||
| 38 | int close_delay; | ||
| 39 | int IER; /* Interrupt Enable Register */ | ||
| 40 | unsigned long last_active; | ||
| 41 | int count; /* # of fd on device */ | ||
| 42 | int x_char; /* to be pushed out ASAP */ | ||
| 43 | int x_break; | ||
| 44 | int blocked_open; /* # of blocked opens */ | ||
| 45 | unsigned char *xmit_buf; | ||
| 46 | int xmit_head; | ||
| 47 | int xmit_tail; | ||
| 48 | int xmit_cnt; | ||
| 49 | int default_threshold; | ||
| 50 | int default_timeout; | ||
| 51 | wait_queue_head_t open_wait; | ||
| 52 | wait_queue_head_t close_wait; | ||
| 53 | struct cyclades_monitor mon; | ||
| 54 | }; | ||
| 55 | |||
| 56 | #define CYCLADES_MAGIC 0x4359 | ||
| 57 | |||
| 58 | #define CYGETMON 0x435901 | ||
| 59 | #define CYGETTHRESH 0x435902 | ||
| 60 | #define CYSETTHRESH 0x435903 | ||
| 61 | #define CYGETDEFTHRESH 0x435904 | ||
| 62 | #define CYSETDEFTHRESH 0x435905 | ||
| 63 | #define CYGETTIMEOUT 0x435906 | ||
| 64 | #define CYSETTIMEOUT 0x435907 | ||
| 65 | #define CYGETDEFTIMEOUT 0x435908 | ||
| 66 | #define CYSETDEFTIMEOUT 0x435909 | ||
| 67 | |||
| 68 | #define CyMaxChipsPerCard 1 | ||
| 69 | |||
| 70 | /**** cd2401 registers ****/ | ||
| 71 | |||
| 72 | #define CyGFRCR (0x81) | ||
| 73 | #define CyCCR (0x13) | ||
| 74 | #define CyCLR_CHAN (0x40) | ||
| 75 | #define CyINIT_CHAN (0x20) | ||
| 76 | #define CyCHIP_RESET (0x10) | ||
| 77 | #define CyENB_XMTR (0x08) | ||
| 78 | #define CyDIS_XMTR (0x04) | ||
| 79 | #define CyENB_RCVR (0x02) | ||
| 80 | #define CyDIS_RCVR (0x01) | ||
| 81 | #define CyCAR (0xee) | ||
| 82 | #define CyIER (0x11) | ||
| 83 | #define CyMdmCh (0x80) | ||
| 84 | #define CyRxExc (0x20) | ||
| 85 | #define CyRxData (0x08) | ||
| 86 | #define CyTxMpty (0x02) | ||
| 87 | #define CyTxRdy (0x01) | ||
| 88 | #define CyLICR (0x26) | ||
| 89 | #define CyRISR (0x89) | ||
| 90 | #define CyTIMEOUT (0x80) | ||
| 91 | #define CySPECHAR (0x70) | ||
| 92 | #define CyOVERRUN (0x08) | ||
| 93 | #define CyPARITY (0x04) | ||
| 94 | #define CyFRAME (0x02) | ||
| 95 | #define CyBREAK (0x01) | ||
| 96 | #define CyREOIR (0x84) | ||
| 97 | #define CyTEOIR (0x85) | ||
| 98 | #define CyMEOIR (0x86) | ||
| 99 | #define CyNOTRANS (0x08) | ||
| 100 | #define CyRFOC (0x30) | ||
| 101 | #define CyRDR (0xf8) | ||
| 102 | #define CyTDR (0xf8) | ||
| 103 | #define CyMISR (0x8b) | ||
| 104 | #define CyRISR (0x89) | ||
| 105 | #define CyTISR (0x8a) | ||
| 106 | #define CyMSVR1 (0xde) | ||
| 107 | #define CyMSVR2 (0xdf) | ||
| 108 | #define CyDSR (0x80) | ||
| 109 | #define CyDCD (0x40) | ||
| 110 | #define CyCTS (0x20) | ||
| 111 | #define CyDTR (0x02) | ||
| 112 | #define CyRTS (0x01) | ||
| 113 | #define CyRTPRL (0x25) | ||
| 114 | #define CyRTPRH (0x24) | ||
| 115 | #define CyCOR1 (0x10) | ||
| 116 | #define CyPARITY_NONE (0x00) | ||
| 117 | #define CyPARITY_E (0x40) | ||
| 118 | #define CyPARITY_O (0xC0) | ||
| 119 | #define Cy_5_BITS (0x04) | ||
| 120 | #define Cy_6_BITS (0x05) | ||
| 121 | #define Cy_7_BITS (0x06) | ||
| 122 | #define Cy_8_BITS (0x07) | ||
| 123 | #define CyCOR2 (0x17) | ||
| 124 | #define CyETC (0x20) | ||
| 125 | #define CyCtsAE (0x02) | ||
| 126 | #define CyCOR3 (0x16) | ||
| 127 | #define Cy_1_STOP (0x02) | ||
| 128 | #define Cy_2_STOP (0x04) | ||
| 129 | #define CyCOR4 (0x15) | ||
| 130 | #define CyREC_FIFO (0x0F) /* Receive FIFO threshold */ | ||
| 131 | #define CyCOR5 (0x14) | ||
| 132 | #define CyCOR6 (0x18) | ||
| 133 | #define CyCOR7 (0x07) | ||
| 134 | #define CyRBPR (0xcb) | ||
| 135 | #define CyRCOR (0xc8) | ||
| 136 | #define CyTBPR (0xc3) | ||
| 137 | #define CyTCOR (0xc0) | ||
| 138 | #define CySCHR1 (0x1f) | ||
| 139 | #define CySCHR2 (0x1e) | ||
| 140 | #define CyTPR (0xda) | ||
| 141 | #define CyPILR1 (0xe3) | ||
| 142 | #define CyPILR2 (0xe0) | ||
| 143 | #define CyPILR3 (0xe1) | ||
| 144 | #define CyCMR (0x1b) | ||
| 145 | #define CyASYNC (0x02) | ||
| 146 | #define CyLICR (0x26) | ||
| 147 | #define CyLIVR (0x09) | ||
| 148 | #define CySCRL (0x23) | ||
| 149 | #define CySCRH (0x22) | ||
| 150 | #define CyTFTC (0x80) | ||
| 151 | |||
| 152 | |||
| 153 | /* max number of chars in the FIFO */ | ||
| 154 | |||
| 155 | #define CyMAX_CHAR_FIFO 12 | ||
| 156 | |||
| 157 | /***************************************************************************/ | ||
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index a416e92012ef..c174c90fb3fb 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h | |||
| @@ -65,11 +65,38 @@ enum { | |||
| 65 | * platform device. Using these will make your driver | 65 | * platform device. Using these will make your driver |
| 66 | * dependent on the 8250 driver. | 66 | * dependent on the 8250 driver. |
| 67 | */ | 67 | */ |
| 68 | struct uart_port; | 68 | |
| 69 | struct uart_8250_port; | 69 | struct uart_8250_port { |
| 70 | struct uart_port port; | ||
| 71 | struct timer_list timer; /* "no irq" timer */ | ||
| 72 | struct list_head list; /* ports on this IRQ */ | ||
| 73 | unsigned short capabilities; /* port capabilities */ | ||
| 74 | unsigned short bugs; /* port bugs */ | ||
| 75 | unsigned int tx_loadsz; /* transmit fifo load size */ | ||
| 76 | unsigned char acr; | ||
| 77 | unsigned char ier; | ||
| 78 | unsigned char lcr; | ||
| 79 | unsigned char mcr; | ||
| 80 | unsigned char mcr_mask; /* mask of user bits */ | ||
| 81 | unsigned char mcr_force; /* mask of forced bits */ | ||
| 82 | unsigned char cur_iotype; /* Running I/O type */ | ||
| 83 | |||
| 84 | /* | ||
| 85 | * Some bits in registers are cleared on a read, so they must | ||
| 86 | * be saved whenever the register is read but the bits will not | ||
| 87 | * be immediately processed. | ||
| 88 | */ | ||
| 89 | #define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS | ||
| 90 | unsigned char lsr_saved_flags; | ||
| 91 | #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA | ||
| 92 | unsigned char msr_saved_flags; | ||
| 93 | |||
| 94 | /* 8250 specific callbacks */ | ||
| 95 | int (*dl_read)(struct uart_8250_port *); | ||
| 96 | void (*dl_write)(struct uart_8250_port *, int); | ||
| 97 | }; | ||
| 70 | 98 | ||
| 71 | int serial8250_register_8250_port(struct uart_8250_port *); | 99 | int serial8250_register_8250_port(struct uart_8250_port *); |
| 72 | int serial8250_register_port(struct uart_port *); | ||
| 73 | void serial8250_unregister_port(int line); | 100 | void serial8250_unregister_port(int line); |
| 74 | void serial8250_suspend_port(int line); | 101 | void serial8250_suspend_port(int line); |
| 75 | void serial8250_resume_port(int line); | 102 | void serial8250_resume_port(int line); |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 0253c2022e53..f9b22ec7a9f3 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
| @@ -48,7 +48,8 @@ | |||
| 48 | #define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */ | 48 | #define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */ |
| 49 | #define PORT_XR17D15X 21 /* Exar XR17D15x UART */ | 49 | #define PORT_XR17D15X 21 /* Exar XR17D15x UART */ |
| 50 | #define PORT_LPC3220 22 /* NXP LPC32xx SoC "Standard" UART */ | 50 | #define PORT_LPC3220 22 /* NXP LPC32xx SoC "Standard" UART */ |
| 51 | #define PORT_MAX_8250 22 /* max port ID */ | 51 | #define PORT_8250_CIR 23 /* CIR infrared port, has its own driver */ |
| 52 | #define PORT_MAX_8250 23 /* max port ID */ | ||
| 52 | 53 | ||
| 53 | /* | 54 | /* |
| 54 | * ARM specific type numbers. These are not currently guaranteed | 55 | * ARM specific type numbers. These are not currently guaranteed |
| @@ -193,8 +194,8 @@ | |||
| 193 | /* SH-SCI */ | 194 | /* SH-SCI */ |
| 194 | #define PORT_SCIFB 93 | 195 | #define PORT_SCIFB 93 |
| 195 | 196 | ||
| 196 | /* MAX3107 */ | 197 | /* MAX310X */ |
| 197 | #define PORT_MAX3107 94 | 198 | #define PORT_MAX310X 94 |
| 198 | 199 | ||
| 199 | /* High Speed UART for Medfield */ | 200 | /* High Speed UART for Medfield */ |
| 200 | #define PORT_MFD 95 | 201 | #define PORT_MFD 95 |
| @@ -274,6 +275,7 @@ struct uart_ops { | |||
| 274 | int (*verify_port)(struct uart_port *, struct serial_struct *); | 275 | int (*verify_port)(struct uart_port *, struct serial_struct *); |
| 275 | int (*ioctl)(struct uart_port *, unsigned int, unsigned long); | 276 | int (*ioctl)(struct uart_port *, unsigned int, unsigned long); |
| 276 | #ifdef CONFIG_CONSOLE_POLL | 277 | #ifdef CONFIG_CONSOLE_POLL |
| 278 | int (*poll_init)(struct uart_port *); | ||
| 277 | void (*poll_put_char)(struct uart_port *, unsigned char); | 279 | void (*poll_put_char)(struct uart_port *, unsigned char); |
| 278 | int (*poll_get_char)(struct uart_port *); | 280 | int (*poll_get_char)(struct uart_port *); |
| 279 | #endif | 281 | #endif |
diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h index 8ce70d76f836..5ed325e88a81 100644 --- a/include/linux/serial_reg.h +++ b/include/linux/serial_reg.h | |||
| @@ -40,6 +40,10 @@ | |||
| 40 | 40 | ||
| 41 | #define UART_IIR_BUSY 0x07 /* DesignWare APB Busy Detect */ | 41 | #define UART_IIR_BUSY 0x07 /* DesignWare APB Busy Detect */ |
| 42 | 42 | ||
| 43 | #define UART_IIR_RX_TIMEOUT 0x0c /* OMAP RX Timeout interrupt */ | ||
| 44 | #define UART_IIR_XOFF 0x10 /* OMAP XOFF/Special Character */ | ||
| 45 | #define UART_IIR_CTS_RTS_DSR 0x20 /* OMAP CTS/RTS/DSR Change */ | ||
| 46 | |||
| 43 | #define UART_FCR 2 /* Out: FIFO Control Register */ | 47 | #define UART_FCR 2 /* Out: FIFO Control Register */ |
| 44 | #define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */ | 48 | #define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */ |
| 45 | #define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ | 49 | #define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ |
diff --git a/include/linux/stallion.h b/include/linux/stallion.h deleted file mode 100644 index 336af33c6ea4..000000000000 --- a/include/linux/stallion.h +++ /dev/null | |||
| @@ -1,147 +0,0 @@ | |||
| 1 | /*****************************************************************************/ | ||
| 2 | |||
| 3 | /* | ||
| 4 | * stallion.h -- stallion multiport serial driver. | ||
| 5 | * | ||
| 6 | * Copyright (C) 1996-1998 Stallion Technologies | ||
| 7 | * Copyright (C) 1994-1996 Greg Ungerer. | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | /*****************************************************************************/ | ||
| 25 | #ifndef _STALLION_H | ||
| 26 | #define _STALLION_H | ||
| 27 | /*****************************************************************************/ | ||
| 28 | |||
| 29 | /* | ||
| 30 | * Define important driver constants here. | ||
| 31 | */ | ||
| 32 | #define STL_MAXBRDS 4 | ||
| 33 | #define STL_MAXPANELS 4 | ||
| 34 | #define STL_MAXBANKS 8 | ||
| 35 | #define STL_PORTSPERPANEL 16 | ||
| 36 | #define STL_MAXPORTS 64 | ||
| 37 | #define STL_MAXDEVS (STL_MAXBRDS * STL_MAXPORTS) | ||
| 38 | |||
| 39 | |||
| 40 | /* | ||
| 41 | * Define a set of structures to hold all the board/panel/port info | ||
| 42 | * for our ports. These will be dynamically allocated as required. | ||
| 43 | */ | ||
| 44 | |||
| 45 | /* | ||
| 46 | * Define a ring queue structure for each port. This will hold the | ||
| 47 | * TX data waiting to be output. Characters are fed into this buffer | ||
| 48 | * from the line discipline (or even direct from user space!) and | ||
| 49 | * then fed into the UARTs during interrupts. Will use a classic ring | ||
| 50 | * queue here for this. The good thing about this type of ring queue | ||
| 51 | * is that the head and tail pointers can be updated without interrupt | ||
| 52 | * protection - since "write" code only needs to change the head, and | ||
| 53 | * interrupt code only needs to change the tail. | ||
| 54 | */ | ||
| 55 | struct stlrq { | ||
| 56 | char *buf; | ||
| 57 | char *head; | ||
| 58 | char *tail; | ||
| 59 | }; | ||
| 60 | |||
| 61 | /* | ||
| 62 | * Port, panel and board structures to hold status info about each. | ||
| 63 | * The board structure contains pointers to structures for each panel | ||
| 64 | * connected to it, and in turn each panel structure contains pointers | ||
| 65 | * for each port structure for each port on that panel. Note that | ||
| 66 | * the port structure also contains the board and panel number that it | ||
| 67 | * is associated with, this makes it (fairly) easy to get back to the | ||
| 68 | * board/panel info for a port. | ||
| 69 | */ | ||
| 70 | struct stlport { | ||
| 71 | unsigned long magic; | ||
| 72 | struct tty_port port; | ||
| 73 | unsigned int portnr; | ||
| 74 | unsigned int panelnr; | ||
| 75 | unsigned int brdnr; | ||
| 76 | int ioaddr; | ||
| 77 | int uartaddr; | ||
| 78 | unsigned int pagenr; | ||
| 79 | unsigned long istate; | ||
| 80 | int baud_base; | ||
| 81 | int custom_divisor; | ||
| 82 | int close_delay; | ||
| 83 | int closing_wait; | ||
| 84 | int openwaitcnt; | ||
| 85 | int brklen; | ||
| 86 | unsigned int sigs; | ||
| 87 | unsigned int rxignoremsk; | ||
| 88 | unsigned int rxmarkmsk; | ||
| 89 | unsigned int imr; | ||
| 90 | unsigned int crenable; | ||
| 91 | unsigned long clk; | ||
| 92 | unsigned long hwid; | ||
| 93 | void *uartp; | ||
| 94 | comstats_t stats; | ||
| 95 | struct stlrq tx; | ||
| 96 | }; | ||
| 97 | |||
| 98 | struct stlpanel { | ||
| 99 | unsigned long magic; | ||
| 100 | unsigned int panelnr; | ||
| 101 | unsigned int brdnr; | ||
| 102 | unsigned int pagenr; | ||
| 103 | unsigned int nrports; | ||
| 104 | int iobase; | ||
| 105 | void *uartp; | ||
| 106 | void (*isr)(struct stlpanel *panelp, unsigned int iobase); | ||
| 107 | unsigned int hwid; | ||
| 108 | unsigned int ackmask; | ||
| 109 | struct stlport *ports[STL_PORTSPERPANEL]; | ||
| 110 | }; | ||
| 111 | |||
| 112 | struct stlbrd { | ||
| 113 | unsigned long magic; | ||
| 114 | unsigned int brdnr; | ||
| 115 | unsigned int brdtype; | ||
| 116 | unsigned int state; | ||
| 117 | unsigned int nrpanels; | ||
| 118 | unsigned int nrports; | ||
| 119 | unsigned int nrbnks; | ||
| 120 | int irq; | ||
| 121 | int irqtype; | ||
| 122 | int (*isr)(struct stlbrd *brdp); | ||
| 123 | unsigned int ioaddr1; | ||
| 124 | unsigned int ioaddr2; | ||
| 125 | unsigned int iosize1; | ||
| 126 | unsigned int iosize2; | ||
| 127 | unsigned int iostatus; | ||
| 128 | unsigned int ioctrl; | ||
| 129 | unsigned int ioctrlval; | ||
| 130 | unsigned int hwid; | ||
| 131 | unsigned long clk; | ||
| 132 | unsigned int bnkpageaddr[STL_MAXBANKS]; | ||
| 133 | unsigned int bnkstataddr[STL_MAXBANKS]; | ||
| 134 | struct stlpanel *bnk2panel[STL_MAXBANKS]; | ||
| 135 | struct stlpanel *panels[STL_MAXPANELS]; | ||
| 136 | }; | ||
| 137 | |||
| 138 | |||
| 139 | /* | ||
| 140 | * Define MAGIC numbers used for above structures. | ||
| 141 | */ | ||
| 142 | #define STL_PORTMAGIC 0x5a7182c9 | ||
| 143 | #define STL_PANELMAGIC 0x7ef621a1 | ||
| 144 | #define STL_BOARDMAGIC 0xa2267f52 | ||
| 145 | |||
| 146 | /*****************************************************************************/ | ||
| 147 | #endif | ||
diff --git a/include/linux/tty.h b/include/linux/tty.h index 9f47ab540f65..1509b86825d8 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include <linux/tty_driver.h> | 43 | #include <linux/tty_driver.h> |
| 44 | #include <linux/tty_ldisc.h> | 44 | #include <linux/tty_ldisc.h> |
| 45 | #include <linux/mutex.h> | 45 | #include <linux/mutex.h> |
| 46 | #include <linux/tty_flags.h> | ||
| 46 | 47 | ||
| 47 | 48 | ||
| 48 | 49 | ||
| @@ -103,28 +104,28 @@ struct tty_bufhead { | |||
| 103 | #define TTY_PARITY 3 | 104 | #define TTY_PARITY 3 |
| 104 | #define TTY_OVERRUN 4 | 105 | #define TTY_OVERRUN 4 |
| 105 | 106 | ||
| 106 | #define INTR_CHAR(tty) ((tty)->termios->c_cc[VINTR]) | 107 | #define INTR_CHAR(tty) ((tty)->termios.c_cc[VINTR]) |
| 107 | #define QUIT_CHAR(tty) ((tty)->termios->c_cc[VQUIT]) | 108 | #define QUIT_CHAR(tty) ((tty)->termios.c_cc[VQUIT]) |
| 108 | #define ERASE_CHAR(tty) ((tty)->termios->c_cc[VERASE]) | 109 | #define ERASE_CHAR(tty) ((tty)->termios.c_cc[VERASE]) |
| 109 | #define KILL_CHAR(tty) ((tty)->termios->c_cc[VKILL]) | 110 | #define KILL_CHAR(tty) ((tty)->termios.c_cc[VKILL]) |
| 110 | #define EOF_CHAR(tty) ((tty)->termios->c_cc[VEOF]) | 111 | #define EOF_CHAR(tty) ((tty)->termios.c_cc[VEOF]) |
| 111 | #define TIME_CHAR(tty) ((tty)->termios->c_cc[VTIME]) | 112 | #define TIME_CHAR(tty) ((tty)->termios.c_cc[VTIME]) |
| 112 | #define MIN_CHAR(tty) ((tty)->termios->c_cc[VMIN]) | 113 | #define MIN_CHAR(tty) ((tty)->termios.c_cc[VMIN]) |
| 113 | #define SWTC_CHAR(tty) ((tty)->termios->c_cc[VSWTC]) | 114 | #define SWTC_CHAR(tty) ((tty)->termios.c_cc[VSWTC]) |
| 114 | #define START_CHAR(tty) ((tty)->termios->c_cc[VSTART]) | 115 | #define START_CHAR(tty) ((tty)->termios.c_cc[VSTART]) |
| 115 | #define STOP_CHAR(tty) ((tty)->termios->c_cc[VSTOP]) | 116 | #define STOP_CHAR(tty) ((tty)->termios.c_cc[VSTOP]) |
| 116 | #define SUSP_CHAR(tty) ((tty)->termios->c_cc[VSUSP]) | 117 | #define SUSP_CHAR(tty) ((tty)->termios.c_cc[VSUSP]) |
| 117 | #define EOL_CHAR(tty) ((tty)->termios->c_cc[VEOL]) | 118 | #define EOL_CHAR(tty) ((tty)->termios.c_cc[VEOL]) |
| 118 | #define REPRINT_CHAR(tty) ((tty)->termios->c_cc[VREPRINT]) | 119 | #define REPRINT_CHAR(tty) ((tty)->termios.c_cc[VREPRINT]) |
| 119 | #define DISCARD_CHAR(tty) ((tty)->termios->c_cc[VDISCARD]) | 120 | #define DISCARD_CHAR(tty) ((tty)->termios.c_cc[VDISCARD]) |
| 120 | #define WERASE_CHAR(tty) ((tty)->termios->c_cc[VWERASE]) | 121 | #define WERASE_CHAR(tty) ((tty)->termios.c_cc[VWERASE]) |
| 121 | #define LNEXT_CHAR(tty) ((tty)->termios->c_cc[VLNEXT]) | 122 | #define LNEXT_CHAR(tty) ((tty)->termios.c_cc[VLNEXT]) |
| 122 | #define EOL2_CHAR(tty) ((tty)->termios->c_cc[VEOL2]) | 123 | #define EOL2_CHAR(tty) ((tty)->termios.c_cc[VEOL2]) |
| 123 | 124 | ||
| 124 | #define _I_FLAG(tty, f) ((tty)->termios->c_iflag & (f)) | 125 | #define _I_FLAG(tty, f) ((tty)->termios.c_iflag & (f)) |
| 125 | #define _O_FLAG(tty, f) ((tty)->termios->c_oflag & (f)) | 126 | #define _O_FLAG(tty, f) ((tty)->termios.c_oflag & (f)) |
| 126 | #define _C_FLAG(tty, f) ((tty)->termios->c_cflag & (f)) | 127 | #define _C_FLAG(tty, f) ((tty)->termios.c_cflag & (f)) |
| 127 | #define _L_FLAG(tty, f) ((tty)->termios->c_lflag & (f)) | 128 | #define _L_FLAG(tty, f) ((tty)->termios.c_lflag & (f)) |
| 128 | 129 | ||
| 129 | #define I_IGNBRK(tty) _I_FLAG((tty), IGNBRK) | 130 | #define I_IGNBRK(tty) _I_FLAG((tty), IGNBRK) |
| 130 | #define I_BRKINT(tty) _I_FLAG((tty), BRKINT) | 131 | #define I_BRKINT(tty) _I_FLAG((tty), BRKINT) |
| @@ -268,10 +269,11 @@ struct tty_struct { | |||
| 268 | struct mutex ldisc_mutex; | 269 | struct mutex ldisc_mutex; |
| 269 | struct tty_ldisc *ldisc; | 270 | struct tty_ldisc *ldisc; |
| 270 | 271 | ||
| 272 | struct mutex legacy_mutex; | ||
| 271 | struct mutex termios_mutex; | 273 | struct mutex termios_mutex; |
| 272 | spinlock_t ctrl_lock; | 274 | spinlock_t ctrl_lock; |
| 273 | /* Termios values are protected by the termios mutex */ | 275 | /* Termios values are protected by the termios mutex */ |
| 274 | struct ktermios *termios, *termios_locked; | 276 | struct ktermios termios, termios_locked; |
| 275 | struct termiox *termiox; /* May be NULL for unsupported */ | 277 | struct termiox *termiox; /* May be NULL for unsupported */ |
| 276 | char name[64]; | 278 | char name[64]; |
| 277 | struct pid *pgrp; /* Protected by ctrl lock */ | 279 | struct pid *pgrp; /* Protected by ctrl lock */ |
| @@ -410,6 +412,10 @@ extern int tty_register_driver(struct tty_driver *driver); | |||
| 410 | extern int tty_unregister_driver(struct tty_driver *driver); | 412 | extern int tty_unregister_driver(struct tty_driver *driver); |
| 411 | extern struct device *tty_register_device(struct tty_driver *driver, | 413 | extern struct device *tty_register_device(struct tty_driver *driver, |
| 412 | unsigned index, struct device *dev); | 414 | unsigned index, struct device *dev); |
| 415 | extern struct device *tty_register_device_attr(struct tty_driver *driver, | ||
| 416 | unsigned index, struct device *device, | ||
| 417 | void *drvdata, | ||
| 418 | const struct attribute_group **attr_grp); | ||
| 413 | extern void tty_unregister_device(struct tty_driver *driver, unsigned index); | 419 | extern void tty_unregister_device(struct tty_driver *driver, unsigned index); |
| 414 | extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, | 420 | extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, |
| 415 | int buflen); | 421 | int buflen); |
| @@ -423,7 +429,6 @@ extern void tty_unthrottle(struct tty_struct *tty); | |||
| 423 | extern int tty_do_resize(struct tty_struct *tty, struct winsize *ws); | 429 | extern int tty_do_resize(struct tty_struct *tty, struct winsize *ws); |
| 424 | extern void tty_driver_remove_tty(struct tty_driver *driver, | 430 | extern void tty_driver_remove_tty(struct tty_driver *driver, |
| 425 | struct tty_struct *tty); | 431 | struct tty_struct *tty); |
| 426 | extern void tty_shutdown(struct tty_struct *tty); | ||
| 427 | extern void tty_free_termios(struct tty_struct *tty); | 432 | extern void tty_free_termios(struct tty_struct *tty); |
| 428 | extern int is_current_pgrp_orphaned(void); | 433 | extern int is_current_pgrp_orphaned(void); |
| 429 | extern struct pid *tty_get_pgrp(struct tty_struct *tty); | 434 | extern struct pid *tty_get_pgrp(struct tty_struct *tty); |
| @@ -497,6 +502,15 @@ extern int tty_write_lock(struct tty_struct *tty, int ndelay); | |||
| 497 | #define tty_is_writelocked(tty) (mutex_is_locked(&tty->atomic_write_lock)) | 502 | #define tty_is_writelocked(tty) (mutex_is_locked(&tty->atomic_write_lock)) |
| 498 | 503 | ||
| 499 | extern void tty_port_init(struct tty_port *port); | 504 | extern void tty_port_init(struct tty_port *port); |
| 505 | extern void tty_port_link_device(struct tty_port *port, | ||
| 506 | struct tty_driver *driver, unsigned index); | ||
| 507 | extern struct device *tty_port_register_device(struct tty_port *port, | ||
| 508 | struct tty_driver *driver, unsigned index, | ||
| 509 | struct device *device); | ||
| 510 | extern struct device *tty_port_register_device_attr(struct tty_port *port, | ||
| 511 | struct tty_driver *driver, unsigned index, | ||
| 512 | struct device *device, void *drvdata, | ||
| 513 | const struct attribute_group **attr_grp); | ||
| 500 | extern int tty_port_alloc_xmit_buf(struct tty_port *port); | 514 | extern int tty_port_alloc_xmit_buf(struct tty_port *port); |
| 501 | extern void tty_port_free_xmit_buf(struct tty_port *port); | 515 | extern void tty_port_free_xmit_buf(struct tty_port *port); |
| 502 | extern void tty_port_put(struct tty_port *port); | 516 | extern void tty_port_put(struct tty_port *port); |
| @@ -508,6 +522,12 @@ static inline struct tty_port *tty_port_get(struct tty_port *port) | |||
| 508 | return port; | 522 | return port; |
| 509 | } | 523 | } |
| 510 | 524 | ||
| 525 | /* If the cts flow control is enabled, return true. */ | ||
| 526 | static inline bool tty_port_cts_enabled(struct tty_port *port) | ||
| 527 | { | ||
| 528 | return port->flags & ASYNC_CTS_FLOW; | ||
| 529 | } | ||
| 530 | |||
| 511 | extern struct tty_struct *tty_port_tty_get(struct tty_port *port); | 531 | extern struct tty_struct *tty_port_tty_get(struct tty_port *port); |
| 512 | extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); | 532 | extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); |
| 513 | extern int tty_port_carrier_raised(struct tty_port *port); | 533 | extern int tty_port_carrier_raised(struct tty_port *port); |
| @@ -521,6 +541,8 @@ extern int tty_port_close_start(struct tty_port *port, | |||
| 521 | extern void tty_port_close_end(struct tty_port *port, struct tty_struct *tty); | 541 | extern void tty_port_close_end(struct tty_port *port, struct tty_struct *tty); |
| 522 | extern void tty_port_close(struct tty_port *port, | 542 | extern void tty_port_close(struct tty_port *port, |
| 523 | struct tty_struct *tty, struct file *filp); | 543 | struct tty_struct *tty, struct file *filp); |
| 544 | extern int tty_port_install(struct tty_port *port, struct tty_driver *driver, | ||
| 545 | struct tty_struct *tty); | ||
| 524 | extern int tty_port_open(struct tty_port *port, | 546 | extern int tty_port_open(struct tty_port *port, |
| 525 | struct tty_struct *tty, struct file *filp); | 547 | struct tty_struct *tty, struct file *filp); |
| 526 | static inline int tty_port_users(struct tty_port *port) | 548 | static inline int tty_port_users(struct tty_port *port) |
| @@ -605,8 +627,12 @@ extern long vt_compat_ioctl(struct tty_struct *tty, | |||
| 605 | 627 | ||
| 606 | /* tty_mutex.c */ | 628 | /* tty_mutex.c */ |
| 607 | /* functions for preparation of BKL removal */ | 629 | /* functions for preparation of BKL removal */ |
| 608 | extern void __lockfunc tty_lock(void) __acquires(tty_lock); | 630 | extern void __lockfunc tty_lock(struct tty_struct *tty); |
| 609 | extern void __lockfunc tty_unlock(void) __releases(tty_lock); | 631 | extern void __lockfunc tty_unlock(struct tty_struct *tty); |
| 632 | extern void __lockfunc tty_lock_pair(struct tty_struct *tty, | ||
| 633 | struct tty_struct *tty2); | ||
| 634 | extern void __lockfunc tty_unlock_pair(struct tty_struct *tty, | ||
| 635 | struct tty_struct *tty2); | ||
| 610 | 636 | ||
| 611 | /* | 637 | /* |
| 612 | * this shall be called only from where BTM is held (like close) | 638 | * this shall be called only from where BTM is held (like close) |
| @@ -621,9 +647,9 @@ extern void __lockfunc tty_unlock(void) __releases(tty_lock); | |||
| 621 | static inline void tty_wait_until_sent_from_close(struct tty_struct *tty, | 647 | static inline void tty_wait_until_sent_from_close(struct tty_struct *tty, |
| 622 | long timeout) | 648 | long timeout) |
| 623 | { | 649 | { |
| 624 | tty_unlock(); /* tty->ops->close holds the BTM, drop it while waiting */ | 650 | tty_unlock(tty); /* tty->ops->close holds the BTM, drop it while waiting */ |
| 625 | tty_wait_until_sent(tty, timeout); | 651 | tty_wait_until_sent(tty, timeout); |
| 626 | tty_lock(); | 652 | tty_lock(tty); |
| 627 | } | 653 | } |
| 628 | 654 | ||
| 629 | /* | 655 | /* |
| @@ -638,16 +664,16 @@ static inline void tty_wait_until_sent_from_close(struct tty_struct *tty, | |||
| 638 | * | 664 | * |
| 639 | * Do not use in new code. | 665 | * Do not use in new code. |
| 640 | */ | 666 | */ |
| 641 | #define wait_event_interruptible_tty(wq, condition) \ | 667 | #define wait_event_interruptible_tty(tty, wq, condition) \ |
| 642 | ({ \ | 668 | ({ \ |
| 643 | int __ret = 0; \ | 669 | int __ret = 0; \ |
| 644 | if (!(condition)) { \ | 670 | if (!(condition)) { \ |
| 645 | __wait_event_interruptible_tty(wq, condition, __ret); \ | 671 | __wait_event_interruptible_tty(tty, wq, condition, __ret); \ |
| 646 | } \ | 672 | } \ |
| 647 | __ret; \ | 673 | __ret; \ |
| 648 | }) | 674 | }) |
| 649 | 675 | ||
| 650 | #define __wait_event_interruptible_tty(wq, condition, ret) \ | 676 | #define __wait_event_interruptible_tty(tty, wq, condition, ret) \ |
| 651 | do { \ | 677 | do { \ |
| 652 | DEFINE_WAIT(__wait); \ | 678 | DEFINE_WAIT(__wait); \ |
| 653 | \ | 679 | \ |
| @@ -656,9 +682,9 @@ do { \ | |||
| 656 | if (condition) \ | 682 | if (condition) \ |
| 657 | break; \ | 683 | break; \ |
| 658 | if (!signal_pending(current)) { \ | 684 | if (!signal_pending(current)) { \ |
| 659 | tty_unlock(); \ | 685 | tty_unlock(tty); \ |
| 660 | schedule(); \ | 686 | schedule(); \ |
| 661 | tty_lock(); \ | 687 | tty_lock(tty); \ |
| 662 | continue; \ | 688 | continue; \ |
| 663 | } \ | 689 | } \ |
| 664 | ret = -ERESTARTSYS; \ | 690 | ret = -ERESTARTSYS; \ |
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 6e6dbb7447b6..dd976cfb6131 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h | |||
| @@ -45,14 +45,9 @@ | |||
| 45 | * | 45 | * |
| 46 | * void (*shutdown)(struct tty_struct * tty); | 46 | * void (*shutdown)(struct tty_struct * tty); |
| 47 | * | 47 | * |
| 48 | * This routine is called synchronously when a particular tty device | 48 | * This routine is called under the tty lock when a particular tty device |
| 49 | * is closed for the last time freeing up the resources. | 49 | * is closed for the last time. It executes before the tty resources |
| 50 | * Note that tty_shutdown() is not called if ops->shutdown is defined. | 50 | * are freed so may execute while another function holds a tty kref. |
| 51 | * This means one is responsible to take care of calling ops->remove (e.g. | ||
| 52 | * via tty_driver_remove_tty) and releasing tty->termios. | ||
| 53 | * Note that this hook may be called from *all* the contexts where one | ||
| 54 | * uses tty refcounting (e.g. tty_port_tty_get). | ||
| 55 | * | ||
| 56 | * | 51 | * |
| 57 | * void (*cleanup)(struct tty_struct * tty); | 52 | * void (*cleanup)(struct tty_struct * tty); |
| 58 | * | 53 | * |
| @@ -294,18 +289,18 @@ struct tty_operations { | |||
| 294 | struct tty_driver { | 289 | struct tty_driver { |
| 295 | int magic; /* magic number for this structure */ | 290 | int magic; /* magic number for this structure */ |
| 296 | struct kref kref; /* Reference management */ | 291 | struct kref kref; /* Reference management */ |
| 297 | struct cdev cdev; | 292 | struct cdev *cdevs; |
| 298 | struct module *owner; | 293 | struct module *owner; |
| 299 | const char *driver_name; | 294 | const char *driver_name; |
| 300 | const char *name; | 295 | const char *name; |
| 301 | int name_base; /* offset of printed name */ | 296 | int name_base; /* offset of printed name */ |
| 302 | int major; /* major device number */ | 297 | int major; /* major device number */ |
| 303 | int minor_start; /* start of minor device number */ | 298 | int minor_start; /* start of minor device number */ |
| 304 | int num; /* number of devices allocated */ | 299 | unsigned int num; /* number of devices allocated */ |
| 305 | short type; /* type of tty driver */ | 300 | short type; /* type of tty driver */ |
| 306 | short subtype; /* subtype of tty driver */ | 301 | short subtype; /* subtype of tty driver */ |
| 307 | struct ktermios init_termios; /* Initial termios */ | 302 | struct ktermios init_termios; /* Initial termios */ |
| 308 | int flags; /* tty driver flags */ | 303 | unsigned long flags; /* tty driver flags */ |
| 309 | struct proc_dir_entry *proc_entry; /* /proc fs entry */ | 304 | struct proc_dir_entry *proc_entry; /* /proc fs entry */ |
| 310 | struct tty_driver *other; /* only used for the PTY driver */ | 305 | struct tty_driver *other; /* only used for the PTY driver */ |
| 311 | 306 | ||
| @@ -313,6 +308,7 @@ struct tty_driver { | |||
| 313 | * Pointer to the tty data structures | 308 | * Pointer to the tty data structures |
| 314 | */ | 309 | */ |
| 315 | struct tty_struct **ttys; | 310 | struct tty_struct **ttys; |
| 311 | struct tty_port **ports; | ||
| 316 | struct ktermios **termios; | 312 | struct ktermios **termios; |
| 317 | void *driver_state; | 313 | void *driver_state; |
| 318 | 314 | ||
| @@ -326,7 +322,8 @@ struct tty_driver { | |||
| 326 | 322 | ||
| 327 | extern struct list_head tty_drivers; | 323 | extern struct list_head tty_drivers; |
| 328 | 324 | ||
| 329 | extern struct tty_driver *__alloc_tty_driver(int lines, struct module *owner); | 325 | extern struct tty_driver *__tty_alloc_driver(unsigned int lines, |
| 326 | struct module *owner, unsigned long flags); | ||
| 330 | extern void put_tty_driver(struct tty_driver *driver); | 327 | extern void put_tty_driver(struct tty_driver *driver); |
| 331 | extern void tty_set_operations(struct tty_driver *driver, | 328 | extern void tty_set_operations(struct tty_driver *driver, |
| 332 | const struct tty_operations *op); | 329 | const struct tty_operations *op); |
| @@ -334,7 +331,21 @@ extern struct tty_driver *tty_find_polling_driver(char *name, int *line); | |||
| 334 | 331 | ||
| 335 | extern void tty_driver_kref_put(struct tty_driver *driver); | 332 | extern void tty_driver_kref_put(struct tty_driver *driver); |
| 336 | 333 | ||
| 337 | #define alloc_tty_driver(lines) __alloc_tty_driver(lines, THIS_MODULE) | 334 | /* Use TTY_DRIVER_* flags below */ |
| 335 | #define tty_alloc_driver(lines, flags) \ | ||
| 336 | __tty_alloc_driver(lines, THIS_MODULE, flags) | ||
| 337 | |||
| 338 | /* | ||
| 339 | * DEPRECATED Do not use this in new code, use tty_alloc_driver instead. | ||
| 340 | * (And change the return value checks.) | ||
| 341 | */ | ||
| 342 | static inline struct tty_driver *alloc_tty_driver(unsigned int lines) | ||
| 343 | { | ||
| 344 | struct tty_driver *ret = tty_alloc_driver(lines, 0); | ||
| 345 | if (IS_ERR(ret)) | ||
| 346 | return NULL; | ||
| 347 | return ret; | ||
| 348 | } | ||
| 338 | 349 | ||
| 339 | static inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d) | 350 | static inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d) |
| 340 | { | 351 | { |
| @@ -380,6 +391,14 @@ static inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d) | |||
| 380 | * the requested timeout to the caller instead of using a simple | 391 | * the requested timeout to the caller instead of using a simple |
| 381 | * on/off interface. | 392 | * on/off interface. |
| 382 | * | 393 | * |
| 394 | * TTY_DRIVER_DYNAMIC_ALLOC -- do not allocate structures which are | ||
| 395 | * needed per line for this driver as it would waste memory. | ||
| 396 | * The driver will take care. | ||
| 397 | * | ||
| 398 | * TTY_DRIVER_UNNUMBERED_NODE -- do not create numbered /dev nodes. In | ||
| 399 | * other words create /dev/ttyprintk and not /dev/ttyprintk0. | ||
| 400 | * Applicable only when a driver for a single tty device is | ||
| 401 | * being allocated. | ||
| 383 | */ | 402 | */ |
| 384 | #define TTY_DRIVER_INSTALLED 0x0001 | 403 | #define TTY_DRIVER_INSTALLED 0x0001 |
| 385 | #define TTY_DRIVER_RESET_TERMIOS 0x0002 | 404 | #define TTY_DRIVER_RESET_TERMIOS 0x0002 |
| @@ -387,6 +406,8 @@ static inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d) | |||
| 387 | #define TTY_DRIVER_DYNAMIC_DEV 0x0008 | 406 | #define TTY_DRIVER_DYNAMIC_DEV 0x0008 |
| 388 | #define TTY_DRIVER_DEVPTS_MEM 0x0010 | 407 | #define TTY_DRIVER_DEVPTS_MEM 0x0010 |
| 389 | #define TTY_DRIVER_HARDWARE_BREAK 0x0020 | 408 | #define TTY_DRIVER_HARDWARE_BREAK 0x0020 |
| 409 | #define TTY_DRIVER_DYNAMIC_ALLOC 0x0040 | ||
| 410 | #define TTY_DRIVER_UNNUMBERED_NODE 0x0080 | ||
| 390 | 411 | ||
| 391 | /* tty driver types */ | 412 | /* tty driver types */ |
| 392 | #define TTY_DRIVER_TYPE_SYSTEM 0x0001 | 413 | #define TTY_DRIVER_TYPE_SYSTEM 0x0001 |
diff --git a/include/linux/tty_flags.h b/include/linux/tty_flags.h new file mode 100644 index 000000000000..eefcb483a2c0 --- /dev/null +++ b/include/linux/tty_flags.h | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | #ifndef _LINUX_TTY_FLAGS_H | ||
| 2 | #define _LINUX_TTY_FLAGS_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Definitions for async_struct (and serial_struct) flags field also | ||
| 6 | * shared by the tty_port flags structures. | ||
| 7 | * | ||
| 8 | * Define ASYNCB_* for convenient use with {test,set,clear}_bit. | ||
| 9 | */ | ||
| 10 | #define ASYNCB_HUP_NOTIFY 0 /* Notify getty on hangups and closes | ||
| 11 | * on the callout port */ | ||
| 12 | #define ASYNCB_FOURPORT 1 /* Set OU1, OUT2 per AST Fourport settings */ | ||
| 13 | #define ASYNCB_SAK 2 /* Secure Attention Key (Orange book) */ | ||
| 14 | #define ASYNCB_SPLIT_TERMIOS 3 /* Separate termios for dialin/callout */ | ||
| 15 | #define ASYNCB_SPD_HI 4 /* Use 56000 instead of 38400 bps */ | ||
| 16 | #define ASYNCB_SPD_VHI 5 /* Use 115200 instead of 38400 bps */ | ||
| 17 | #define ASYNCB_SKIP_TEST 6 /* Skip UART test during autoconfiguration */ | ||
| 18 | #define ASYNCB_AUTO_IRQ 7 /* Do automatic IRQ during | ||
| 19 | * autoconfiguration */ | ||
| 20 | #define ASYNCB_SESSION_LOCKOUT 8 /* Lock out cua opens based on session */ | ||
| 21 | #define ASYNCB_PGRP_LOCKOUT 9 /* Lock out cua opens based on pgrp */ | ||
| 22 | #define ASYNCB_CALLOUT_NOHUP 10 /* Don't do hangups for cua device */ | ||
| 23 | #define ASYNCB_HARDPPS_CD 11 /* Call hardpps when CD goes high */ | ||
| 24 | #define ASYNCB_SPD_SHI 12 /* Use 230400 instead of 38400 bps */ | ||
| 25 | #define ASYNCB_LOW_LATENCY 13 /* Request low latency behaviour */ | ||
| 26 | #define ASYNCB_BUGGY_UART 14 /* This is a buggy UART, skip some safety | ||
| 27 | * checks. Note: can be dangerous! */ | ||
| 28 | #define ASYNCB_AUTOPROBE 15 /* Port was autoprobed by PCI or PNP code */ | ||
| 29 | #define ASYNCB_LAST_USER 15 | ||
| 30 | |||
| 31 | /* Internal flags used only by kernel */ | ||
| 32 | #define ASYNCB_INITIALIZED 31 /* Serial port was initialized */ | ||
| 33 | #define ASYNCB_SUSPENDED 30 /* Serial port is suspended */ | ||
| 34 | #define ASYNCB_NORMAL_ACTIVE 29 /* Normal device is active */ | ||
| 35 | #define ASYNCB_BOOT_AUTOCONF 28 /* Autoconfigure port on bootup */ | ||
| 36 | #define ASYNCB_CLOSING 27 /* Serial port is closing */ | ||
| 37 | #define ASYNCB_CTS_FLOW 26 /* Do CTS flow control */ | ||
| 38 | #define ASYNCB_CHECK_CD 25 /* i.e., CLOCAL */ | ||
| 39 | #define ASYNCB_SHARE_IRQ 24 /* for multifunction cards, no longer used */ | ||
| 40 | #define ASYNCB_CONS_FLOW 23 /* flow control for console */ | ||
| 41 | #define ASYNCB_FIRST_KERNEL 22 | ||
| 42 | |||
| 43 | #define ASYNC_HUP_NOTIFY (1U << ASYNCB_HUP_NOTIFY) | ||
| 44 | #define ASYNC_SUSPENDED (1U << ASYNCB_SUSPENDED) | ||
| 45 | #define ASYNC_FOURPORT (1U << ASYNCB_FOURPORT) | ||
| 46 | #define ASYNC_SAK (1U << ASYNCB_SAK) | ||
| 47 | #define ASYNC_SPLIT_TERMIOS (1U << ASYNCB_SPLIT_TERMIOS) | ||
| 48 | #define ASYNC_SPD_HI (1U << ASYNCB_SPD_HI) | ||
| 49 | #define ASYNC_SPD_VHI (1U << ASYNCB_SPD_VHI) | ||
| 50 | #define ASYNC_SKIP_TEST (1U << ASYNCB_SKIP_TEST) | ||
| 51 | #define ASYNC_AUTO_IRQ (1U << ASYNCB_AUTO_IRQ) | ||
| 52 | #define ASYNC_SESSION_LOCKOUT (1U << ASYNCB_SESSION_LOCKOUT) | ||
| 53 | #define ASYNC_PGRP_LOCKOUT (1U << ASYNCB_PGRP_LOCKOUT) | ||
| 54 | #define ASYNC_CALLOUT_NOHUP (1U << ASYNCB_CALLOUT_NOHUP) | ||
| 55 | #define ASYNC_HARDPPS_CD (1U << ASYNCB_HARDPPS_CD) | ||
| 56 | #define ASYNC_SPD_SHI (1U << ASYNCB_SPD_SHI) | ||
| 57 | #define ASYNC_LOW_LATENCY (1U << ASYNCB_LOW_LATENCY) | ||
| 58 | #define ASYNC_BUGGY_UART (1U << ASYNCB_BUGGY_UART) | ||
| 59 | #define ASYNC_AUTOPROBE (1U << ASYNCB_AUTOPROBE) | ||
| 60 | |||
| 61 | #define ASYNC_FLAGS ((1U << (ASYNCB_LAST_USER + 1)) - 1) | ||
| 62 | #define ASYNC_USR_MASK (ASYNC_SPD_MASK|ASYNC_CALLOUT_NOHUP| \ | ||
| 63 | ASYNC_LOW_LATENCY) | ||
| 64 | #define ASYNC_SPD_CUST (ASYNC_SPD_HI|ASYNC_SPD_VHI) | ||
| 65 | #define ASYNC_SPD_WARP (ASYNC_SPD_HI|ASYNC_SPD_SHI) | ||
| 66 | #define ASYNC_SPD_MASK (ASYNC_SPD_HI|ASYNC_SPD_VHI|ASYNC_SPD_SHI) | ||
| 67 | |||
| 68 | #define ASYNC_INITIALIZED (1U << ASYNCB_INITIALIZED) | ||
| 69 | #define ASYNC_NORMAL_ACTIVE (1U << ASYNCB_NORMAL_ACTIVE) | ||
| 70 | #define ASYNC_BOOT_AUTOCONF (1U << ASYNCB_BOOT_AUTOCONF) | ||
| 71 | #define ASYNC_CLOSING (1U << ASYNCB_CLOSING) | ||
| 72 | #define ASYNC_CTS_FLOW (1U << ASYNCB_CTS_FLOW) | ||
| 73 | #define ASYNC_CHECK_CD (1U << ASYNCB_CHECK_CD) | ||
| 74 | #define ASYNC_SHARE_IRQ (1U << ASYNCB_SHARE_IRQ) | ||
| 75 | #define ASYNC_CONS_FLOW (1U << ASYNCB_CONS_FLOW) | ||
| 76 | #define ASYNC_INTERNAL_FLAGS (~((1U << ASYNCB_FIRST_KERNEL) - 1)) | ||
| 77 | |||
| 78 | #endif | ||
diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h index 59ba38bc400f..80ffde3bb164 100644 --- a/include/net/irda/ircomm_tty.h +++ b/include/net/irda/ircomm_tty.h | |||
| @@ -52,21 +52,16 @@ | |||
| 52 | /* Same for payload size. See qos.c for the smallest max data size */ | 52 | /* Same for payload size. See qos.c for the smallest max data size */ |
| 53 | #define IRCOMM_TTY_DATA_UNINITIALISED (64 - IRCOMM_TTY_HDR_UNINITIALISED) | 53 | #define IRCOMM_TTY_DATA_UNINITIALISED (64 - IRCOMM_TTY_HDR_UNINITIALISED) |
| 54 | 54 | ||
| 55 | /* Those are really defined in include/linux/serial.h - Jean II */ | ||
| 56 | #define ASYNC_B_INITIALIZED 31 /* Serial port was initialized */ | ||
| 57 | #define ASYNC_B_NORMAL_ACTIVE 29 /* Normal device is active */ | ||
| 58 | #define ASYNC_B_CLOSING 27 /* Serial port is closing */ | ||
| 59 | |||
| 60 | /* | 55 | /* |
| 61 | * IrCOMM TTY driver state | 56 | * IrCOMM TTY driver state |
| 62 | */ | 57 | */ |
| 63 | struct ircomm_tty_cb { | 58 | struct ircomm_tty_cb { |
| 64 | irda_queue_t queue; /* Must be first */ | 59 | irda_queue_t queue; /* Must be first */ |
| 60 | struct tty_port port; | ||
| 65 | magic_t magic; | 61 | magic_t magic; |
| 66 | 62 | ||
| 67 | int state; /* Connect state */ | 63 | int state; /* Connect state */ |
| 68 | 64 | ||
| 69 | struct tty_struct *tty; | ||
| 70 | struct ircomm_cb *ircomm; /* IrCOMM layer instance */ | 65 | struct ircomm_cb *ircomm; /* IrCOMM layer instance */ |
| 71 | 66 | ||
| 72 | struct sk_buff *tx_skb; /* Transmit buffer */ | 67 | struct sk_buff *tx_skb; /* Transmit buffer */ |
| @@ -80,7 +75,6 @@ struct ircomm_tty_cb { | |||
| 80 | LOCAL_FLOW flow; /* IrTTP flow status */ | 75 | LOCAL_FLOW flow; /* IrTTP flow status */ |
| 81 | 76 | ||
| 82 | int line; | 77 | int line; |
| 83 | unsigned long flags; | ||
| 84 | 78 | ||
| 85 | __u8 dlsap_sel; | 79 | __u8 dlsap_sel; |
| 86 | __u8 slsap_sel; | 80 | __u8 slsap_sel; |
| @@ -97,19 +91,10 @@ struct ircomm_tty_cb { | |||
| 97 | void *skey; | 91 | void *skey; |
| 98 | void *ckey; | 92 | void *ckey; |
| 99 | 93 | ||
| 100 | wait_queue_head_t open_wait; | ||
| 101 | wait_queue_head_t close_wait; | ||
| 102 | struct timer_list watchdog_timer; | 94 | struct timer_list watchdog_timer; |
| 103 | struct work_struct tqueue; | 95 | struct work_struct tqueue; |
| 104 | 96 | ||
| 105 | unsigned short close_delay; | ||
| 106 | unsigned short closing_wait; /* time to wait before closing */ | ||
| 107 | |||
| 108 | int open_count; | ||
| 109 | int blocked_open; /* # of blocked opens */ | ||
| 110 | |||
| 111 | /* Protect concurent access to : | 97 | /* Protect concurent access to : |
| 112 | * o self->open_count | ||
| 113 | * o self->ctrl_skb | 98 | * o self->ctrl_skb |
| 114 | * o self->tx_skb | 99 | * o self->tx_skb |
| 115 | * Maybe other things may gain to be protected as well... | 100 | * Maybe other things may gain to be protected as well... |
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 0557f24c6bca..17e073c309e6 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c | |||
| @@ -672,6 +672,10 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) | |||
| 672 | { | 672 | { |
| 673 | struct kgdb_state kgdb_var; | 673 | struct kgdb_state kgdb_var; |
| 674 | struct kgdb_state *ks = &kgdb_var; | 674 | struct kgdb_state *ks = &kgdb_var; |
| 675 | int ret = 0; | ||
| 676 | |||
| 677 | if (arch_kgdb_ops.enable_nmi) | ||
| 678 | arch_kgdb_ops.enable_nmi(0); | ||
| 675 | 679 | ||
| 676 | ks->cpu = raw_smp_processor_id(); | 680 | ks->cpu = raw_smp_processor_id(); |
| 677 | ks->ex_vector = evector; | 681 | ks->ex_vector = evector; |
| @@ -681,11 +685,15 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) | |||
| 681 | ks->linux_regs = regs; | 685 | ks->linux_regs = regs; |
| 682 | 686 | ||
| 683 | if (kgdb_reenter_check(ks)) | 687 | if (kgdb_reenter_check(ks)) |
| 684 | return 0; /* Ouch, double exception ! */ | 688 | goto out; /* Ouch, double exception ! */ |
| 685 | if (kgdb_info[ks->cpu].enter_kgdb != 0) | 689 | if (kgdb_info[ks->cpu].enter_kgdb != 0) |
| 686 | return 0; | 690 | goto out; |
| 687 | 691 | ||
| 688 | return kgdb_cpu_enter(ks, regs, DCPU_WANT_MASTER); | 692 | ret = kgdb_cpu_enter(ks, regs, DCPU_WANT_MASTER); |
| 693 | out: | ||
| 694 | if (arch_kgdb_ops.enable_nmi) | ||
| 695 | arch_kgdb_ops.enable_nmi(1); | ||
| 696 | return ret; | ||
| 689 | } | 697 | } |
| 690 | 698 | ||
| 691 | int kgdb_nmicallback(int cpu, void *regs) | 699 | int kgdb_nmicallback(int cpu, void *regs) |
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 31df1706b9a9..1261dc7eaeb9 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
| 22 | #include <linux/utsname.h> | 22 | #include <linux/utsname.h> |
| 23 | #include <linux/vmalloc.h> | 23 | #include <linux/vmalloc.h> |
| 24 | #include <linux/atomic.h> | ||
| 24 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 25 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
| 26 | #include <linux/init.h> | 27 | #include <linux/init.h> |
| @@ -2107,6 +2108,32 @@ static int kdb_dmesg(int argc, const char **argv) | |||
| 2107 | return 0; | 2108 | return 0; |
| 2108 | } | 2109 | } |
| 2109 | #endif /* CONFIG_PRINTK */ | 2110 | #endif /* CONFIG_PRINTK */ |
| 2111 | |||
| 2112 | /* Make sure we balance enable/disable calls, must disable first. */ | ||
| 2113 | static atomic_t kdb_nmi_disabled; | ||
| 2114 | |||
| 2115 | static int kdb_disable_nmi(int argc, const char *argv[]) | ||
| 2116 | { | ||
| 2117 | if (atomic_read(&kdb_nmi_disabled)) | ||
| 2118 | return 0; | ||
| 2119 | atomic_set(&kdb_nmi_disabled, 1); | ||
| 2120 | arch_kgdb_ops.enable_nmi(0); | ||
| 2121 | return 0; | ||
| 2122 | } | ||
| 2123 | |||
| 2124 | static int kdb_param_enable_nmi(const char *val, const struct kernel_param *kp) | ||
| 2125 | { | ||
| 2126 | if (!atomic_add_unless(&kdb_nmi_disabled, -1, 0)) | ||
| 2127 | return -EINVAL; | ||
| 2128 | arch_kgdb_ops.enable_nmi(1); | ||
| 2129 | return 0; | ||
| 2130 | } | ||
| 2131 | |||
| 2132 | static const struct kernel_param_ops kdb_param_ops_enable_nmi = { | ||
| 2133 | .set = kdb_param_enable_nmi, | ||
| 2134 | }; | ||
| 2135 | module_param_cb(enable_nmi, &kdb_param_ops_enable_nmi, NULL, 0600); | ||
| 2136 | |||
| 2110 | /* | 2137 | /* |
| 2111 | * kdb_cpu - This function implements the 'cpu' command. | 2138 | * kdb_cpu - This function implements the 'cpu' command. |
| 2112 | * cpu [<cpunum>] | 2139 | * cpu [<cpunum>] |
| @@ -2851,6 +2878,10 @@ static void __init kdb_inittab(void) | |||
| 2851 | kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", | 2878 | kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", |
| 2852 | "Display syslog buffer", 0, KDB_REPEAT_NONE); | 2879 | "Display syslog buffer", 0, KDB_REPEAT_NONE); |
| 2853 | #endif | 2880 | #endif |
| 2881 | if (arch_kgdb_ops.enable_nmi) { | ||
| 2882 | kdb_register_repeat("disable_nmi", kdb_disable_nmi, "", | ||
| 2883 | "Disable NMI entry to KDB", 0, KDB_REPEAT_NONE); | ||
| 2884 | } | ||
| 2854 | kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", | 2885 | kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", |
| 2855 | "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE); | 2886 | "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE); |
| 2856 | kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", | 2887 | kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 56f182393c4c..ccc248791d50 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
| @@ -278,8 +278,8 @@ out: | |||
| 278 | if (err < 0) | 278 | if (err < 0) |
| 279 | goto free; | 279 | goto free; |
| 280 | 280 | ||
| 281 | dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL); | 281 | dev->tty_dev = tty_port_register_device(&dev->port, rfcomm_tty_driver, |
| 282 | 282 | dev->id, NULL); | |
| 283 | if (IS_ERR(dev->tty_dev)) { | 283 | if (IS_ERR(dev->tty_dev)) { |
| 284 | err = PTR_ERR(dev->tty_dev); | 284 | err = PTR_ERR(dev->tty_dev); |
| 285 | list_del(&dev->list); | 285 | list_del(&dev->list); |
| @@ -705,9 +705,9 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 705 | break; | 705 | break; |
| 706 | } | 706 | } |
| 707 | 707 | ||
| 708 | tty_unlock(); | 708 | tty_unlock(tty); |
| 709 | schedule(); | 709 | schedule(); |
| 710 | tty_lock(); | 710 | tty_lock(tty); |
| 711 | } | 711 | } |
| 712 | set_current_state(TASK_RUNNING); | 712 | set_current_state(TASK_RUNNING); |
| 713 | remove_wait_queue(&dev->wait, &wait); | 713 | remove_wait_queue(&dev->wait, &wait); |
| @@ -861,7 +861,7 @@ static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned l | |||
| 861 | 861 | ||
| 862 | static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | 862 | static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old) |
| 863 | { | 863 | { |
| 864 | struct ktermios *new = tty->termios; | 864 | struct ktermios *new = &tty->termios; |
| 865 | int old_baud_rate = tty_termios_baud_rate(old); | 865 | int old_baud_rate = tty_termios_baud_rate(old); |
| 866 | int new_baud_rate = tty_termios_baud_rate(new); | 866 | int new_baud_rate = tty_termios_baud_rate(new); |
| 867 | 867 | ||
diff --git a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c index 8b915f3ac3b9..308939128359 100644 --- a/net/irda/ircomm/ircomm_param.c +++ b/net/irda/ircomm/ircomm_param.c | |||
| @@ -99,7 +99,6 @@ pi_param_info_t ircomm_param_info = { pi_major_call_table, 3, 0x0f, 4 }; | |||
| 99 | */ | 99 | */ |
| 100 | int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) | 100 | int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) |
| 101 | { | 101 | { |
| 102 | struct tty_struct *tty; | ||
| 103 | unsigned long flags; | 102 | unsigned long flags; |
| 104 | struct sk_buff *skb; | 103 | struct sk_buff *skb; |
| 105 | int count; | 104 | int count; |
| @@ -109,10 +108,6 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) | |||
| 109 | IRDA_ASSERT(self != NULL, return -1;); | 108 | IRDA_ASSERT(self != NULL, return -1;); |
| 110 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 109 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
| 111 | 110 | ||
| 112 | tty = self->tty; | ||
| 113 | if (!tty) | ||
| 114 | return 0; | ||
| 115 | |||
| 116 | /* Make sure we don't send parameters for raw mode */ | 111 | /* Make sure we don't send parameters for raw mode */ |
| 117 | if (self->service_type == IRCOMM_3_WIRE_RAW) | 112 | if (self->service_type == IRCOMM_3_WIRE_RAW) |
| 118 | return 0; | 113 | return 0; |
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 6b9d5a0e42f9..95a3a7a336ba 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c | |||
| @@ -52,6 +52,8 @@ | |||
| 52 | #include <net/irda/ircomm_tty_attach.h> | 52 | #include <net/irda/ircomm_tty_attach.h> |
| 53 | #include <net/irda/ircomm_tty.h> | 53 | #include <net/irda/ircomm_tty.h> |
| 54 | 54 | ||
| 55 | static int ircomm_tty_install(struct tty_driver *driver, | ||
| 56 | struct tty_struct *tty); | ||
| 55 | static int ircomm_tty_open(struct tty_struct *tty, struct file *filp); | 57 | static int ircomm_tty_open(struct tty_struct *tty, struct file *filp); |
| 56 | static void ircomm_tty_close(struct tty_struct * tty, struct file *filp); | 58 | static void ircomm_tty_close(struct tty_struct * tty, struct file *filp); |
| 57 | static int ircomm_tty_write(struct tty_struct * tty, | 59 | static int ircomm_tty_write(struct tty_struct * tty, |
| @@ -82,6 +84,7 @@ static struct tty_driver *driver; | |||
| 82 | static hashbin_t *ircomm_tty = NULL; | 84 | static hashbin_t *ircomm_tty = NULL; |
| 83 | 85 | ||
| 84 | static const struct tty_operations ops = { | 86 | static const struct tty_operations ops = { |
| 87 | .install = ircomm_tty_install, | ||
| 85 | .open = ircomm_tty_open, | 88 | .open = ircomm_tty_open, |
| 86 | .close = ircomm_tty_close, | 89 | .close = ircomm_tty_close, |
| 87 | .write = ircomm_tty_write, | 90 | .write = ircomm_tty_write, |
| @@ -104,6 +107,35 @@ static const struct tty_operations ops = { | |||
| 104 | #endif /* CONFIG_PROC_FS */ | 107 | #endif /* CONFIG_PROC_FS */ |
| 105 | }; | 108 | }; |
| 106 | 109 | ||
| 110 | static void ircomm_port_raise_dtr_rts(struct tty_port *port, int raise) | ||
| 111 | { | ||
| 112 | struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb, | ||
| 113 | port); | ||
| 114 | /* | ||
| 115 | * Here, we use to lock those two guys, but as ircomm_param_request() | ||
| 116 | * does it itself, I don't see the point (and I see the deadlock). | ||
| 117 | * Jean II | ||
| 118 | */ | ||
| 119 | if (raise) | ||
| 120 | self->settings.dte |= IRCOMM_RTS | IRCOMM_DTR; | ||
| 121 | else | ||
| 122 | self->settings.dte &= ~(IRCOMM_RTS | IRCOMM_DTR); | ||
| 123 | |||
| 124 | ircomm_param_request(self, IRCOMM_DTE, TRUE); | ||
| 125 | } | ||
| 126 | |||
| 127 | static int ircomm_port_carrier_raised(struct tty_port *port) | ||
| 128 | { | ||
| 129 | struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb, | ||
| 130 | port); | ||
| 131 | return self->settings.dce & IRCOMM_CD; | ||
| 132 | } | ||
| 133 | |||
| 134 | static const struct tty_port_operations ircomm_port_ops = { | ||
| 135 | .dtr_rts = ircomm_port_raise_dtr_rts, | ||
| 136 | .carrier_raised = ircomm_port_carrier_raised, | ||
| 137 | }; | ||
| 138 | |||
| 107 | /* | 139 | /* |
| 108 | * Function ircomm_tty_init() | 140 | * Function ircomm_tty_init() |
| 109 | * | 141 | * |
| @@ -194,7 +226,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self) | |||
| 194 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 226 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
| 195 | 227 | ||
| 196 | /* Check if already open */ | 228 | /* Check if already open */ |
| 197 | if (test_and_set_bit(ASYNC_B_INITIALIZED, &self->flags)) { | 229 | if (test_and_set_bit(ASYNCB_INITIALIZED, &self->port.flags)) { |
| 198 | IRDA_DEBUG(2, "%s(), already open so break out!\n", __func__ ); | 230 | IRDA_DEBUG(2, "%s(), already open so break out!\n", __func__ ); |
| 199 | return 0; | 231 | return 0; |
| 200 | } | 232 | } |
| @@ -231,7 +263,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self) | |||
| 231 | 263 | ||
| 232 | return 0; | 264 | return 0; |
| 233 | err: | 265 | err: |
| 234 | clear_bit(ASYNC_B_INITIALIZED, &self->flags); | 266 | clear_bit(ASYNCB_INITIALIZED, &self->port.flags); |
| 235 | return ret; | 267 | return ret; |
| 236 | } | 268 | } |
| 237 | 269 | ||
| @@ -242,72 +274,62 @@ err: | |||
| 242 | * | 274 | * |
| 243 | */ | 275 | */ |
| 244 | static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | 276 | static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, |
| 245 | struct file *filp) | 277 | struct tty_struct *tty, struct file *filp) |
| 246 | { | 278 | { |
| 279 | struct tty_port *port = &self->port; | ||
| 247 | DECLARE_WAITQUEUE(wait, current); | 280 | DECLARE_WAITQUEUE(wait, current); |
| 248 | int retval; | 281 | int retval; |
| 249 | int do_clocal = 0, extra_count = 0; | 282 | int do_clocal = 0, extra_count = 0; |
| 250 | unsigned long flags; | 283 | unsigned long flags; |
| 251 | struct tty_struct *tty; | ||
| 252 | 284 | ||
| 253 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 285 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
| 254 | 286 | ||
| 255 | tty = self->tty; | ||
| 256 | |||
| 257 | /* | 287 | /* |
| 258 | * If non-blocking mode is set, or the port is not enabled, | 288 | * If non-blocking mode is set, or the port is not enabled, |
| 259 | * then make the check up front and then exit. | 289 | * then make the check up front and then exit. |
| 260 | */ | 290 | */ |
| 261 | if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ | 291 | if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ |
| 262 | /* nonblock mode is set or port is not enabled */ | 292 | /* nonblock mode is set or port is not enabled */ |
| 263 | self->flags |= ASYNC_NORMAL_ACTIVE; | 293 | port->flags |= ASYNC_NORMAL_ACTIVE; |
| 264 | IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __func__ ); | 294 | IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __func__ ); |
| 265 | return 0; | 295 | return 0; |
| 266 | } | 296 | } |
| 267 | 297 | ||
| 268 | if (tty->termios->c_cflag & CLOCAL) { | 298 | if (tty->termios.c_cflag & CLOCAL) { |
| 269 | IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __func__ ); | 299 | IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __func__ ); |
| 270 | do_clocal = 1; | 300 | do_clocal = 1; |
| 271 | } | 301 | } |
| 272 | 302 | ||
| 273 | /* Wait for carrier detect and the line to become | 303 | /* Wait for carrier detect and the line to become |
| 274 | * free (i.e., not in use by the callout). While we are in | 304 | * free (i.e., not in use by the callout). While we are in |
| 275 | * this loop, self->open_count is dropped by one, so that | 305 | * this loop, port->count is dropped by one, so that |
| 276 | * mgsl_close() knows when to free things. We restore it upon | 306 | * mgsl_close() knows when to free things. We restore it upon |
| 277 | * exit, either normal or abnormal. | 307 | * exit, either normal or abnormal. |
| 278 | */ | 308 | */ |
| 279 | 309 | ||
| 280 | retval = 0; | 310 | retval = 0; |
| 281 | add_wait_queue(&self->open_wait, &wait); | 311 | add_wait_queue(&port->open_wait, &wait); |
| 282 | 312 | ||
| 283 | IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n", | 313 | IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n", |
| 284 | __FILE__,__LINE__, tty->driver->name, self->open_count ); | 314 | __FILE__, __LINE__, tty->driver->name, port->count); |
| 285 | 315 | ||
| 286 | /* As far as I can see, we protect open_count - Jean II */ | 316 | spin_lock_irqsave(&port->lock, flags); |
| 287 | spin_lock_irqsave(&self->spinlock, flags); | ||
| 288 | if (!tty_hung_up_p(filp)) { | 317 | if (!tty_hung_up_p(filp)) { |
| 289 | extra_count = 1; | 318 | extra_count = 1; |
| 290 | self->open_count--; | 319 | port->count--; |
| 291 | } | 320 | } |
| 292 | spin_unlock_irqrestore(&self->spinlock, flags); | 321 | spin_unlock_irqrestore(&port->lock, flags); |
| 293 | self->blocked_open++; | 322 | port->blocked_open++; |
| 294 | 323 | ||
| 295 | while (1) { | 324 | while (1) { |
| 296 | if (tty->termios->c_cflag & CBAUD) { | 325 | if (tty->termios.c_cflag & CBAUD) |
| 297 | /* Here, we use to lock those two guys, but | 326 | tty_port_raise_dtr_rts(port); |
| 298 | * as ircomm_param_request() does it itself, | ||
| 299 | * I don't see the point (and I see the deadlock). | ||
| 300 | * Jean II */ | ||
| 301 | self->settings.dte |= IRCOMM_RTS + IRCOMM_DTR; | ||
| 302 | |||
| 303 | ircomm_param_request(self, IRCOMM_DTE, TRUE); | ||
| 304 | } | ||
| 305 | 327 | ||
| 306 | current->state = TASK_INTERRUPTIBLE; | 328 | current->state = TASK_INTERRUPTIBLE; |
| 307 | 329 | ||
| 308 | if (tty_hung_up_p(filp) || | 330 | if (tty_hung_up_p(filp) || |
| 309 | !test_bit(ASYNC_B_INITIALIZED, &self->flags)) { | 331 | !test_bit(ASYNCB_INITIALIZED, &port->flags)) { |
| 310 | retval = (self->flags & ASYNC_HUP_NOTIFY) ? | 332 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? |
| 311 | -EAGAIN : -ERESTARTSYS; | 333 | -EAGAIN : -ERESTARTSYS; |
| 312 | break; | 334 | break; |
| 313 | } | 335 | } |
| @@ -317,8 +339,8 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | |||
| 317 | * specified, we cannot return before the IrCOMM link is | 339 | * specified, we cannot return before the IrCOMM link is |
| 318 | * ready | 340 | * ready |
| 319 | */ | 341 | */ |
| 320 | if (!test_bit(ASYNC_B_CLOSING, &self->flags) && | 342 | if (!test_bit(ASYNCB_CLOSING, &port->flags) && |
| 321 | (do_clocal || (self->settings.dce & IRCOMM_CD)) && | 343 | (do_clocal || tty_port_carrier_raised(port)) && |
| 322 | self->state == IRCOMM_TTY_READY) | 344 | self->state == IRCOMM_TTY_READY) |
| 323 | { | 345 | { |
| 324 | break; | 346 | break; |
| @@ -330,46 +352,36 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | |||
| 330 | } | 352 | } |
| 331 | 353 | ||
| 332 | IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n", | 354 | IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n", |
| 333 | __FILE__,__LINE__, tty->driver->name, self->open_count ); | 355 | __FILE__, __LINE__, tty->driver->name, port->count); |
| 334 | 356 | ||
| 335 | schedule(); | 357 | schedule(); |
| 336 | } | 358 | } |
| 337 | 359 | ||
| 338 | __set_current_state(TASK_RUNNING); | 360 | __set_current_state(TASK_RUNNING); |
| 339 | remove_wait_queue(&self->open_wait, &wait); | 361 | remove_wait_queue(&port->open_wait, &wait); |
| 340 | 362 | ||
| 341 | if (extra_count) { | 363 | if (extra_count) { |
| 342 | /* ++ is not atomic, so this should be protected - Jean II */ | 364 | /* ++ is not atomic, so this should be protected - Jean II */ |
| 343 | spin_lock_irqsave(&self->spinlock, flags); | 365 | spin_lock_irqsave(&port->lock, flags); |
| 344 | self->open_count++; | 366 | port->count++; |
| 345 | spin_unlock_irqrestore(&self->spinlock, flags); | 367 | spin_unlock_irqrestore(&port->lock, flags); |
| 346 | } | 368 | } |
| 347 | self->blocked_open--; | 369 | port->blocked_open--; |
| 348 | 370 | ||
| 349 | IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n", | 371 | IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n", |
| 350 | __FILE__,__LINE__, tty->driver->name, self->open_count); | 372 | __FILE__, __LINE__, tty->driver->name, port->count); |
| 351 | 373 | ||
| 352 | if (!retval) | 374 | if (!retval) |
| 353 | self->flags |= ASYNC_NORMAL_ACTIVE; | 375 | port->flags |= ASYNC_NORMAL_ACTIVE; |
| 354 | 376 | ||
| 355 | return retval; | 377 | return retval; |
| 356 | } | 378 | } |
| 357 | 379 | ||
| 358 | /* | 380 | |
| 359 | * Function ircomm_tty_open (tty, filp) | 381 | static int ircomm_tty_install(struct tty_driver *driver, struct tty_struct *tty) |
| 360 | * | ||
| 361 | * This routine is called when a particular tty device is opened. This | ||
| 362 | * routine is mandatory; if this routine is not filled in, the attempted | ||
| 363 | * open will fail with ENODEV. | ||
| 364 | */ | ||
| 365 | static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | ||
| 366 | { | 382 | { |
| 367 | struct ircomm_tty_cb *self; | 383 | struct ircomm_tty_cb *self; |
| 368 | unsigned int line = tty->index; | 384 | unsigned int line = tty->index; |
| 369 | unsigned long flags; | ||
| 370 | int ret; | ||
| 371 | |||
| 372 | IRDA_DEBUG(2, "%s()\n", __func__ ); | ||
| 373 | 385 | ||
| 374 | /* Check if instance already exists */ | 386 | /* Check if instance already exists */ |
| 375 | self = hashbin_lock_find(ircomm_tty, line, NULL); | 387 | self = hashbin_lock_find(ircomm_tty, line, NULL); |
| @@ -381,6 +393,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 381 | return -ENOMEM; | 393 | return -ENOMEM; |
| 382 | } | 394 | } |
| 383 | 395 | ||
| 396 | tty_port_init(&self->port); | ||
| 397 | self->port.ops = &ircomm_port_ops; | ||
| 384 | self->magic = IRCOMM_TTY_MAGIC; | 398 | self->magic = IRCOMM_TTY_MAGIC; |
| 385 | self->flow = FLOW_STOP; | 399 | self->flow = FLOW_STOP; |
| 386 | 400 | ||
| @@ -388,13 +402,9 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 388 | INIT_WORK(&self->tqueue, ircomm_tty_do_softint); | 402 | INIT_WORK(&self->tqueue, ircomm_tty_do_softint); |
| 389 | self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED; | 403 | self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED; |
| 390 | self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED; | 404 | self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED; |
| 391 | self->close_delay = 5*HZ/10; | ||
| 392 | self->closing_wait = 30*HZ; | ||
| 393 | 405 | ||
| 394 | /* Init some important stuff */ | 406 | /* Init some important stuff */ |
| 395 | init_timer(&self->watchdog_timer); | 407 | init_timer(&self->watchdog_timer); |
| 396 | init_waitqueue_head(&self->open_wait); | ||
| 397 | init_waitqueue_head(&self->close_wait); | ||
| 398 | spin_lock_init(&self->spinlock); | 408 | spin_lock_init(&self->spinlock); |
| 399 | 409 | ||
| 400 | /* | 410 | /* |
| @@ -404,31 +414,48 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 404 | * | 414 | * |
| 405 | * Note this is completely usafe and doesn't work properly | 415 | * Note this is completely usafe and doesn't work properly |
| 406 | */ | 416 | */ |
| 407 | tty->termios->c_iflag = 0; | 417 | tty->termios.c_iflag = 0; |
| 408 | tty->termios->c_oflag = 0; | 418 | tty->termios.c_oflag = 0; |
| 409 | 419 | ||
| 410 | /* Insert into hash */ | 420 | /* Insert into hash */ |
| 411 | hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL); | 421 | hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL); |
| 412 | } | 422 | } |
| 413 | /* ++ is not atomic, so this should be protected - Jean II */ | ||
| 414 | spin_lock_irqsave(&self->spinlock, flags); | ||
| 415 | self->open_count++; | ||
| 416 | 423 | ||
| 417 | tty->driver_data = self; | 424 | return tty_port_install(&self->port, driver, tty); |
| 418 | self->tty = tty; | 425 | } |
| 419 | spin_unlock_irqrestore(&self->spinlock, flags); | 426 | |
| 427 | /* | ||
| 428 | * Function ircomm_tty_open (tty, filp) | ||
| 429 | * | ||
| 430 | * This routine is called when a particular tty device is opened. This | ||
| 431 | * routine is mandatory; if this routine is not filled in, the attempted | ||
| 432 | * open will fail with ENODEV. | ||
| 433 | */ | ||
| 434 | static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | ||
| 435 | { | ||
| 436 | struct ircomm_tty_cb *self = tty->driver_data; | ||
| 437 | unsigned long flags; | ||
| 438 | int ret; | ||
| 439 | |||
| 440 | IRDA_DEBUG(2, "%s()\n", __func__ ); | ||
| 441 | |||
| 442 | /* ++ is not atomic, so this should be protected - Jean II */ | ||
| 443 | spin_lock_irqsave(&self->port.lock, flags); | ||
| 444 | self->port.count++; | ||
| 445 | spin_unlock_irqrestore(&self->port.lock, flags); | ||
| 446 | tty_port_tty_set(&self->port, tty); | ||
| 420 | 447 | ||
| 421 | IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name, | 448 | IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name, |
| 422 | self->line, self->open_count); | 449 | self->line, self->port.count); |
| 423 | 450 | ||
| 424 | /* Not really used by us, but lets do it anyway */ | 451 | /* Not really used by us, but lets do it anyway */ |
| 425 | self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 452 | tty->low_latency = (self->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
| 426 | 453 | ||
| 427 | /* | 454 | /* |
| 428 | * If the port is the middle of closing, bail out now | 455 | * If the port is the middle of closing, bail out now |
| 429 | */ | 456 | */ |
| 430 | if (tty_hung_up_p(filp) || | 457 | if (tty_hung_up_p(filp) || |
| 431 | test_bit(ASYNC_B_CLOSING, &self->flags)) { | 458 | test_bit(ASYNCB_CLOSING, &self->port.flags)) { |
| 432 | 459 | ||
| 433 | /* Hm, why are we blocking on ASYNC_CLOSING if we | 460 | /* Hm, why are we blocking on ASYNC_CLOSING if we |
| 434 | * do return -EAGAIN/-ERESTARTSYS below anyway? | 461 | * do return -EAGAIN/-ERESTARTSYS below anyway? |
| @@ -438,14 +465,15 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 438 | * probably better sleep uninterruptible? | 465 | * probably better sleep uninterruptible? |
| 439 | */ | 466 | */ |
| 440 | 467 | ||
| 441 | if (wait_event_interruptible(self->close_wait, !test_bit(ASYNC_B_CLOSING, &self->flags))) { | 468 | if (wait_event_interruptible(self->port.close_wait, |
| 469 | !test_bit(ASYNCB_CLOSING, &self->port.flags))) { | ||
| 442 | IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n", | 470 | IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n", |
| 443 | __func__); | 471 | __func__); |
| 444 | return -ERESTARTSYS; | 472 | return -ERESTARTSYS; |
| 445 | } | 473 | } |
| 446 | 474 | ||
| 447 | #ifdef SERIAL_DO_RESTART | 475 | #ifdef SERIAL_DO_RESTART |
| 448 | return (self->flags & ASYNC_HUP_NOTIFY) ? | 476 | return (self->port.flags & ASYNC_HUP_NOTIFY) ? |
| 449 | -EAGAIN : -ERESTARTSYS; | 477 | -EAGAIN : -ERESTARTSYS; |
| 450 | #else | 478 | #else |
| 451 | return -EAGAIN; | 479 | return -EAGAIN; |
| @@ -453,7 +481,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 453 | } | 481 | } |
| 454 | 482 | ||
| 455 | /* Check if this is a "normal" ircomm device, or an irlpt device */ | 483 | /* Check if this is a "normal" ircomm device, or an irlpt device */ |
| 456 | if (line < 0x10) { | 484 | if (self->line < 0x10) { |
| 457 | self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE; | 485 | self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE; |
| 458 | self->settings.service_type = IRCOMM_9_WIRE; /* 9 wire as default */ | 486 | self->settings.service_type = IRCOMM_9_WIRE; /* 9 wire as default */ |
| 459 | /* Jan Kiszka -> add DSR/RI -> Conform to IrCOMM spec */ | 487 | /* Jan Kiszka -> add DSR/RI -> Conform to IrCOMM spec */ |
| @@ -469,7 +497,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 469 | if (ret) | 497 | if (ret) |
| 470 | return ret; | 498 | return ret; |
| 471 | 499 | ||
| 472 | ret = ircomm_tty_block_til_ready(self, filp); | 500 | ret = ircomm_tty_block_til_ready(self, tty, filp); |
| 473 | if (ret) { | 501 | if (ret) { |
| 474 | IRDA_DEBUG(2, | 502 | IRDA_DEBUG(2, |
| 475 | "%s(), returning after block_til_ready with %d\n", __func__ , | 503 | "%s(), returning after block_til_ready with %d\n", __func__ , |
| @@ -489,81 +517,22 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 489 | static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) | 517 | static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) |
| 490 | { | 518 | { |
| 491 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 519 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
| 492 | unsigned long flags; | 520 | struct tty_port *port = &self->port; |
| 493 | 521 | ||
| 494 | IRDA_DEBUG(0, "%s()\n", __func__ ); | 522 | IRDA_DEBUG(0, "%s()\n", __func__ ); |
| 495 | 523 | ||
| 496 | IRDA_ASSERT(self != NULL, return;); | 524 | IRDA_ASSERT(self != NULL, return;); |
| 497 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 525 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
| 498 | 526 | ||
| 499 | spin_lock_irqsave(&self->spinlock, flags); | 527 | if (tty_port_close_start(port, tty, filp) == 0) |
| 500 | |||
| 501 | if (tty_hung_up_p(filp)) { | ||
| 502 | spin_unlock_irqrestore(&self->spinlock, flags); | ||
| 503 | |||
| 504 | IRDA_DEBUG(0, "%s(), returning 1\n", __func__ ); | ||
| 505 | return; | ||
| 506 | } | ||
| 507 | |||
| 508 | if ((tty->count == 1) && (self->open_count != 1)) { | ||
| 509 | /* | ||
| 510 | * Uh, oh. tty->count is 1, which means that the tty | ||
| 511 | * structure will be freed. state->count should always | ||
| 512 | * be one in these conditions. If it's greater than | ||
| 513 | * one, we've got real problems, since it means the | ||
| 514 | * serial port won't be shutdown. | ||
| 515 | */ | ||
| 516 | IRDA_DEBUG(0, "%s(), bad serial port count; " | ||
| 517 | "tty->count is 1, state->count is %d\n", __func__ , | ||
| 518 | self->open_count); | ||
| 519 | self->open_count = 1; | ||
| 520 | } | ||
| 521 | |||
| 522 | if (--self->open_count < 0) { | ||
| 523 | IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n", | ||
| 524 | __func__, self->line, self->open_count); | ||
| 525 | self->open_count = 0; | ||
| 526 | } | ||
| 527 | if (self->open_count) { | ||
| 528 | spin_unlock_irqrestore(&self->spinlock, flags); | ||
| 529 | |||
| 530 | IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ ); | ||
| 531 | return; | 528 | return; |
| 532 | } | ||
| 533 | |||
| 534 | /* Hum... Should be test_and_set_bit ??? - Jean II */ | ||
| 535 | set_bit(ASYNC_B_CLOSING, &self->flags); | ||
| 536 | |||
| 537 | /* We need to unlock here (we were unlocking at the end of this | ||
| 538 | * function), because tty_wait_until_sent() may schedule. | ||
| 539 | * I don't know if the rest should be protected somehow, | ||
| 540 | * so someone should check. - Jean II */ | ||
| 541 | spin_unlock_irqrestore(&self->spinlock, flags); | ||
| 542 | |||
| 543 | /* | ||
| 544 | * Now we wait for the transmit buffer to clear; and we notify | ||
| 545 | * the line discipline to only process XON/XOFF characters. | ||
| 546 | */ | ||
| 547 | tty->closing = 1; | ||
| 548 | if (self->closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
| 549 | tty_wait_until_sent_from_close(tty, self->closing_wait); | ||
| 550 | 529 | ||
| 551 | ircomm_tty_shutdown(self); | 530 | ircomm_tty_shutdown(self); |
| 552 | 531 | ||
| 553 | tty_driver_flush_buffer(tty); | 532 | tty_driver_flush_buffer(tty); |
| 554 | tty_ldisc_flush(tty); | ||
| 555 | |||
| 556 | tty->closing = 0; | ||
| 557 | self->tty = NULL; | ||
| 558 | 533 | ||
| 559 | if (self->blocked_open) { | 534 | tty_port_close_end(port, tty); |
| 560 | if (self->close_delay) | 535 | tty_port_tty_set(port, NULL); |
| 561 | schedule_timeout_interruptible(self->close_delay); | ||
| 562 | wake_up_interruptible(&self->open_wait); | ||
| 563 | } | ||
| 564 | |||
| 565 | self->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | ||
| 566 | wake_up_interruptible(&self->close_wait); | ||
| 567 | } | 536 | } |
| 568 | 537 | ||
| 569 | /* | 538 | /* |
| @@ -606,7 +575,7 @@ static void ircomm_tty_do_softint(struct work_struct *work) | |||
| 606 | if (!self || self->magic != IRCOMM_TTY_MAGIC) | 575 | if (!self || self->magic != IRCOMM_TTY_MAGIC) |
| 607 | return; | 576 | return; |
| 608 | 577 | ||
| 609 | tty = self->tty; | 578 | tty = tty_port_tty_get(&self->port); |
| 610 | if (!tty) | 579 | if (!tty) |
| 611 | return; | 580 | return; |
| 612 | 581 | ||
| @@ -627,7 +596,7 @@ static void ircomm_tty_do_softint(struct work_struct *work) | |||
| 627 | } | 596 | } |
| 628 | 597 | ||
| 629 | if (tty->hw_stopped) | 598 | if (tty->hw_stopped) |
| 630 | return; | 599 | goto put; |
| 631 | 600 | ||
| 632 | /* Unlink transmit buffer */ | 601 | /* Unlink transmit buffer */ |
| 633 | spin_lock_irqsave(&self->spinlock, flags); | 602 | spin_lock_irqsave(&self->spinlock, flags); |
| @@ -646,6 +615,8 @@ static void ircomm_tty_do_softint(struct work_struct *work) | |||
| 646 | 615 | ||
| 647 | /* Check if user (still) wants to be waken up */ | 616 | /* Check if user (still) wants to be waken up */ |
| 648 | tty_wakeup(tty); | 617 | tty_wakeup(tty); |
| 618 | put: | ||
| 619 | tty_kref_put(tty); | ||
| 649 | } | 620 | } |
| 650 | 621 | ||
| 651 | /* | 622 | /* |
| @@ -880,7 +851,7 @@ static void ircomm_tty_throttle(struct tty_struct *tty) | |||
| 880 | ircomm_tty_send_xchar(tty, STOP_CHAR(tty)); | 851 | ircomm_tty_send_xchar(tty, STOP_CHAR(tty)); |
| 881 | 852 | ||
| 882 | /* Hardware flow control? */ | 853 | /* Hardware flow control? */ |
| 883 | if (tty->termios->c_cflag & CRTSCTS) { | 854 | if (tty->termios.c_cflag & CRTSCTS) { |
| 884 | self->settings.dte &= ~IRCOMM_RTS; | 855 | self->settings.dte &= ~IRCOMM_RTS; |
| 885 | self->settings.dte |= IRCOMM_DELTA_RTS; | 856 | self->settings.dte |= IRCOMM_DELTA_RTS; |
| 886 | 857 | ||
| @@ -912,7 +883,7 @@ static void ircomm_tty_unthrottle(struct tty_struct *tty) | |||
| 912 | } | 883 | } |
| 913 | 884 | ||
| 914 | /* Using hardware flow control? */ | 885 | /* Using hardware flow control? */ |
| 915 | if (tty->termios->c_cflag & CRTSCTS) { | 886 | if (tty->termios.c_cflag & CRTSCTS) { |
| 916 | self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS); | 887 | self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS); |
| 917 | 888 | ||
| 918 | ircomm_param_request(self, IRCOMM_DTE, TRUE); | 889 | ircomm_param_request(self, IRCOMM_DTE, TRUE); |
| @@ -955,7 +926,7 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self) | |||
| 955 | 926 | ||
| 956 | IRDA_DEBUG(0, "%s()\n", __func__ ); | 927 | IRDA_DEBUG(0, "%s()\n", __func__ ); |
| 957 | 928 | ||
| 958 | if (!test_and_clear_bit(ASYNC_B_INITIALIZED, &self->flags)) | 929 | if (!test_and_clear_bit(ASYNCB_INITIALIZED, &self->port.flags)) |
| 959 | return; | 930 | return; |
| 960 | 931 | ||
| 961 | ircomm_tty_detach_cable(self); | 932 | ircomm_tty_detach_cable(self); |
| @@ -994,6 +965,7 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self) | |||
| 994 | static void ircomm_tty_hangup(struct tty_struct *tty) | 965 | static void ircomm_tty_hangup(struct tty_struct *tty) |
| 995 | { | 966 | { |
| 996 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 967 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
| 968 | struct tty_port *port = &self->port; | ||
| 997 | unsigned long flags; | 969 | unsigned long flags; |
| 998 | 970 | ||
| 999 | IRDA_DEBUG(0, "%s()\n", __func__ ); | 971 | IRDA_DEBUG(0, "%s()\n", __func__ ); |
| @@ -1004,14 +976,17 @@ static void ircomm_tty_hangup(struct tty_struct *tty) | |||
| 1004 | /* ircomm_tty_flush_buffer(tty); */ | 976 | /* ircomm_tty_flush_buffer(tty); */ |
| 1005 | ircomm_tty_shutdown(self); | 977 | ircomm_tty_shutdown(self); |
| 1006 | 978 | ||
| 1007 | /* I guess we need to lock here - Jean II */ | 979 | spin_lock_irqsave(&port->lock, flags); |
| 1008 | spin_lock_irqsave(&self->spinlock, flags); | 980 | port->flags &= ~ASYNC_NORMAL_ACTIVE; |
| 1009 | self->flags &= ~ASYNC_NORMAL_ACTIVE; | 981 | if (port->tty) { |
| 1010 | self->tty = NULL; | 982 | set_bit(TTY_IO_ERROR, &port->tty->flags); |
| 1011 | self->open_count = 0; | 983 | tty_kref_put(port->tty); |
| 1012 | spin_unlock_irqrestore(&self->spinlock, flags); | 984 | } |
| 985 | port->tty = NULL; | ||
| 986 | port->count = 0; | ||
| 987 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 1013 | 988 | ||
| 1014 | wake_up_interruptible(&self->open_wait); | 989 | wake_up_interruptible(&port->open_wait); |
| 1015 | } | 990 | } |
| 1016 | 991 | ||
| 1017 | /* | 992 | /* |
| @@ -1071,20 +1046,20 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | |||
| 1071 | IRDA_ASSERT(self != NULL, return;); | 1046 | IRDA_ASSERT(self != NULL, return;); |
| 1072 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 1047 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
| 1073 | 1048 | ||
| 1074 | tty = self->tty; | 1049 | tty = tty_port_tty_get(&self->port); |
| 1075 | 1050 | ||
| 1076 | status = self->settings.dce; | 1051 | status = self->settings.dce; |
| 1077 | 1052 | ||
| 1078 | if (status & IRCOMM_DCE_DELTA_ANY) { | 1053 | if (status & IRCOMM_DCE_DELTA_ANY) { |
| 1079 | /*wake_up_interruptible(&self->delta_msr_wait);*/ | 1054 | /*wake_up_interruptible(&self->delta_msr_wait);*/ |
| 1080 | } | 1055 | } |
| 1081 | if ((self->flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) { | 1056 | if ((self->port.flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) { |
| 1082 | IRDA_DEBUG(2, | 1057 | IRDA_DEBUG(2, |
| 1083 | "%s(), ircomm%d CD now %s...\n", __func__ , self->line, | 1058 | "%s(), ircomm%d CD now %s...\n", __func__ , self->line, |
| 1084 | (status & IRCOMM_CD) ? "on" : "off"); | 1059 | (status & IRCOMM_CD) ? "on" : "off"); |
| 1085 | 1060 | ||
| 1086 | if (status & IRCOMM_CD) { | 1061 | if (status & IRCOMM_CD) { |
| 1087 | wake_up_interruptible(&self->open_wait); | 1062 | wake_up_interruptible(&self->port.open_wait); |
| 1088 | } else { | 1063 | } else { |
| 1089 | IRDA_DEBUG(2, | 1064 | IRDA_DEBUG(2, |
| 1090 | "%s(), Doing serial hangup..\n", __func__ ); | 1065 | "%s(), Doing serial hangup..\n", __func__ ); |
| @@ -1092,10 +1067,10 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | |||
| 1092 | tty_hangup(tty); | 1067 | tty_hangup(tty); |
| 1093 | 1068 | ||
| 1094 | /* Hangup will remote the tty, so better break out */ | 1069 | /* Hangup will remote the tty, so better break out */ |
| 1095 | return; | 1070 | goto put; |
| 1096 | } | 1071 | } |
| 1097 | } | 1072 | } |
| 1098 | if (self->flags & ASYNC_CTS_FLOW) { | 1073 | if (tty && tty_port_cts_enabled(&self->port)) { |
| 1099 | if (tty->hw_stopped) { | 1074 | if (tty->hw_stopped) { |
| 1100 | if (status & IRCOMM_CTS) { | 1075 | if (status & IRCOMM_CTS) { |
| 1101 | IRDA_DEBUG(2, | 1076 | IRDA_DEBUG(2, |
| @@ -1103,10 +1078,10 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | |||
| 1103 | tty->hw_stopped = 0; | 1078 | tty->hw_stopped = 0; |
| 1104 | 1079 | ||
| 1105 | /* Wake up processes blocked on open */ | 1080 | /* Wake up processes blocked on open */ |
| 1106 | wake_up_interruptible(&self->open_wait); | 1081 | wake_up_interruptible(&self->port.open_wait); |
| 1107 | 1082 | ||
| 1108 | schedule_work(&self->tqueue); | 1083 | schedule_work(&self->tqueue); |
| 1109 | return; | 1084 | goto put; |
| 1110 | } | 1085 | } |
| 1111 | } else { | 1086 | } else { |
| 1112 | if (!(status & IRCOMM_CTS)) { | 1087 | if (!(status & IRCOMM_CTS)) { |
| @@ -1116,6 +1091,8 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | |||
| 1116 | } | 1091 | } |
| 1117 | } | 1092 | } |
| 1118 | } | 1093 | } |
| 1094 | put: | ||
| 1095 | tty_kref_put(tty); | ||
| 1119 | } | 1096 | } |
| 1120 | 1097 | ||
| 1121 | /* | 1098 | /* |
| @@ -1128,6 +1105,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap, | |||
| 1128 | struct sk_buff *skb) | 1105 | struct sk_buff *skb) |
| 1129 | { | 1106 | { |
| 1130 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; | 1107 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; |
| 1108 | struct tty_struct *tty; | ||
| 1131 | 1109 | ||
| 1132 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 1110 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
| 1133 | 1111 | ||
| @@ -1135,7 +1113,8 @@ static int ircomm_tty_data_indication(void *instance, void *sap, | |||
| 1135 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 1113 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
| 1136 | IRDA_ASSERT(skb != NULL, return -1;); | 1114 | IRDA_ASSERT(skb != NULL, return -1;); |
| 1137 | 1115 | ||
| 1138 | if (!self->tty) { | 1116 | tty = tty_port_tty_get(&self->port); |
| 1117 | if (!tty) { | ||
| 1139 | IRDA_DEBUG(0, "%s(), no tty!\n", __func__ ); | 1118 | IRDA_DEBUG(0, "%s(), no tty!\n", __func__ ); |
| 1140 | return 0; | 1119 | return 0; |
| 1141 | } | 1120 | } |
| @@ -1146,7 +1125,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap, | |||
| 1146 | * Devices like WinCE can do this, and since they don't send any | 1125 | * Devices like WinCE can do this, and since they don't send any |
| 1147 | * params, we can just as well declare the hardware for running. | 1126 | * params, we can just as well declare the hardware for running. |
| 1148 | */ | 1127 | */ |
| 1149 | if (self->tty->hw_stopped && (self->flow == FLOW_START)) { | 1128 | if (tty->hw_stopped && (self->flow == FLOW_START)) { |
| 1150 | IRDA_DEBUG(0, "%s(), polling for line settings!\n", __func__ ); | 1129 | IRDA_DEBUG(0, "%s(), polling for line settings!\n", __func__ ); |
| 1151 | ircomm_param_request(self, IRCOMM_POLL, TRUE); | 1130 | ircomm_param_request(self, IRCOMM_POLL, TRUE); |
| 1152 | 1131 | ||
| @@ -1159,8 +1138,9 @@ static int ircomm_tty_data_indication(void *instance, void *sap, | |||
| 1159 | * Use flip buffer functions since the code may be called from interrupt | 1138 | * Use flip buffer functions since the code may be called from interrupt |
| 1160 | * context | 1139 | * context |
| 1161 | */ | 1140 | */ |
| 1162 | tty_insert_flip_string(self->tty, skb->data, skb->len); | 1141 | tty_insert_flip_string(tty, skb->data, skb->len); |
| 1163 | tty_flip_buffer_push(self->tty); | 1142 | tty_flip_buffer_push(tty); |
| 1143 | tty_kref_put(tty); | ||
| 1164 | 1144 | ||
| 1165 | /* No need to kfree_skb - see ircomm_ttp_data_indication() */ | 1145 | /* No need to kfree_skb - see ircomm_ttp_data_indication() */ |
| 1166 | 1146 | ||
| @@ -1211,12 +1191,13 @@ static void ircomm_tty_flow_indication(void *instance, void *sap, | |||
| 1211 | IRDA_ASSERT(self != NULL, return;); | 1191 | IRDA_ASSERT(self != NULL, return;); |
| 1212 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 1192 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
| 1213 | 1193 | ||
| 1214 | tty = self->tty; | 1194 | tty = tty_port_tty_get(&self->port); |
| 1215 | 1195 | ||
| 1216 | switch (cmd) { | 1196 | switch (cmd) { |
| 1217 | case FLOW_START: | 1197 | case FLOW_START: |
| 1218 | IRDA_DEBUG(2, "%s(), hw start!\n", __func__ ); | 1198 | IRDA_DEBUG(2, "%s(), hw start!\n", __func__ ); |
| 1219 | tty->hw_stopped = 0; | 1199 | if (tty) |
| 1200 | tty->hw_stopped = 0; | ||
| 1220 | 1201 | ||
| 1221 | /* ircomm_tty_do_softint will take care of the rest */ | 1202 | /* ircomm_tty_do_softint will take care of the rest */ |
| 1222 | schedule_work(&self->tqueue); | 1203 | schedule_work(&self->tqueue); |
| @@ -1224,15 +1205,19 @@ static void ircomm_tty_flow_indication(void *instance, void *sap, | |||
| 1224 | default: /* If we get here, something is very wrong, better stop */ | 1205 | default: /* If we get here, something is very wrong, better stop */ |
| 1225 | case FLOW_STOP: | 1206 | case FLOW_STOP: |
| 1226 | IRDA_DEBUG(2, "%s(), hw stopped!\n", __func__ ); | 1207 | IRDA_DEBUG(2, "%s(), hw stopped!\n", __func__ ); |
| 1227 | tty->hw_stopped = 1; | 1208 | if (tty) |
| 1209 | tty->hw_stopped = 1; | ||
| 1228 | break; | 1210 | break; |
| 1229 | } | 1211 | } |
| 1212 | |||
| 1213 | tty_kref_put(tty); | ||
| 1230 | self->flow = cmd; | 1214 | self->flow = cmd; |
| 1231 | } | 1215 | } |
| 1232 | 1216 | ||
| 1233 | #ifdef CONFIG_PROC_FS | 1217 | #ifdef CONFIG_PROC_FS |
| 1234 | static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) | 1218 | static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) |
| 1235 | { | 1219 | { |
| 1220 | struct tty_struct *tty; | ||
| 1236 | char sep; | 1221 | char sep; |
| 1237 | 1222 | ||
| 1238 | seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]); | 1223 | seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]); |
| @@ -1328,40 +1313,43 @@ static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) | |||
| 1328 | 1313 | ||
| 1329 | seq_puts(m, "Flags:"); | 1314 | seq_puts(m, "Flags:"); |
| 1330 | sep = ' '; | 1315 | sep = ' '; |
| 1331 | if (self->flags & ASYNC_CTS_FLOW) { | 1316 | if (tty_port_cts_enabled(&self->port)) { |
| 1332 | seq_printf(m, "%cASYNC_CTS_FLOW", sep); | 1317 | seq_printf(m, "%cASYNC_CTS_FLOW", sep); |
| 1333 | sep = '|'; | 1318 | sep = '|'; |
| 1334 | } | 1319 | } |
| 1335 | if (self->flags & ASYNC_CHECK_CD) { | 1320 | if (self->port.flags & ASYNC_CHECK_CD) { |
| 1336 | seq_printf(m, "%cASYNC_CHECK_CD", sep); | 1321 | seq_printf(m, "%cASYNC_CHECK_CD", sep); |
| 1337 | sep = '|'; | 1322 | sep = '|'; |
| 1338 | } | 1323 | } |
| 1339 | if (self->flags & ASYNC_INITIALIZED) { | 1324 | if (self->port.flags & ASYNC_INITIALIZED) { |
| 1340 | seq_printf(m, "%cASYNC_INITIALIZED", sep); | 1325 | seq_printf(m, "%cASYNC_INITIALIZED", sep); |
| 1341 | sep = '|'; | 1326 | sep = '|'; |
| 1342 | } | 1327 | } |
| 1343 | if (self->flags & ASYNC_LOW_LATENCY) { | 1328 | if (self->port.flags & ASYNC_LOW_LATENCY) { |
| 1344 | seq_printf(m, "%cASYNC_LOW_LATENCY", sep); | 1329 | seq_printf(m, "%cASYNC_LOW_LATENCY", sep); |
| 1345 | sep = '|'; | 1330 | sep = '|'; |
| 1346 | } | 1331 | } |
| 1347 | if (self->flags & ASYNC_CLOSING) { | 1332 | if (self->port.flags & ASYNC_CLOSING) { |
| 1348 | seq_printf(m, "%cASYNC_CLOSING", sep); | 1333 | seq_printf(m, "%cASYNC_CLOSING", sep); |
| 1349 | sep = '|'; | 1334 | sep = '|'; |
| 1350 | } | 1335 | } |
| 1351 | if (self->flags & ASYNC_NORMAL_ACTIVE) { | 1336 | if (self->port.flags & ASYNC_NORMAL_ACTIVE) { |
| 1352 | seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep); | 1337 | seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep); |
| 1353 | sep = '|'; | 1338 | sep = '|'; |
| 1354 | } | 1339 | } |
| 1355 | seq_putc(m, '\n'); | 1340 | seq_putc(m, '\n'); |
| 1356 | 1341 | ||
| 1357 | seq_printf(m, "Role: %s\n", self->client ? "client" : "server"); | 1342 | seq_printf(m, "Role: %s\n", self->client ? "client" : "server"); |
| 1358 | seq_printf(m, "Open count: %d\n", self->open_count); | 1343 | seq_printf(m, "Open count: %d\n", self->port.count); |
| 1359 | seq_printf(m, "Max data size: %d\n", self->max_data_size); | 1344 | seq_printf(m, "Max data size: %d\n", self->max_data_size); |
| 1360 | seq_printf(m, "Max header size: %d\n", self->max_header_size); | 1345 | seq_printf(m, "Max header size: %d\n", self->max_header_size); |
| 1361 | 1346 | ||
| 1362 | if (self->tty) | 1347 | tty = tty_port_tty_get(&self->port); |
| 1348 | if (tty) { | ||
| 1363 | seq_printf(m, "Hardware: %s\n", | 1349 | seq_printf(m, "Hardware: %s\n", |
| 1364 | self->tty->hw_stopped ? "Stopped" : "Running"); | 1350 | tty->hw_stopped ? "Stopped" : "Running"); |
| 1351 | tty_kref_put(tty); | ||
| 1352 | } | ||
| 1365 | } | 1353 | } |
| 1366 | 1354 | ||
| 1367 | static int ircomm_tty_proc_show(struct seq_file *m, void *v) | 1355 | static int ircomm_tty_proc_show(struct seq_file *m, void *v) |
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c index b65d66e0d817..edab393e0c82 100644 --- a/net/irda/ircomm/ircomm_tty_attach.c +++ b/net/irda/ircomm/ircomm_tty_attach.c | |||
| @@ -130,6 +130,8 @@ static int (*state[])(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event, | |||
| 130 | */ | 130 | */ |
| 131 | int ircomm_tty_attach_cable(struct ircomm_tty_cb *self) | 131 | int ircomm_tty_attach_cable(struct ircomm_tty_cb *self) |
| 132 | { | 132 | { |
| 133 | struct tty_struct *tty; | ||
| 134 | |||
| 133 | IRDA_DEBUG(0, "%s()\n", __func__ ); | 135 | IRDA_DEBUG(0, "%s()\n", __func__ ); |
| 134 | 136 | ||
| 135 | IRDA_ASSERT(self != NULL, return -1;); | 137 | IRDA_ASSERT(self != NULL, return -1;); |
| @@ -142,7 +144,11 @@ int ircomm_tty_attach_cable(struct ircomm_tty_cb *self) | |||
| 142 | } | 144 | } |
| 143 | 145 | ||
| 144 | /* Make sure nobody tries to write before the link is up */ | 146 | /* Make sure nobody tries to write before the link is up */ |
| 145 | self->tty->hw_stopped = 1; | 147 | tty = tty_port_tty_get(&self->port); |
| 148 | if (tty) { | ||
| 149 | tty->hw_stopped = 1; | ||
| 150 | tty_kref_put(tty); | ||
| 151 | } | ||
| 146 | 152 | ||
| 147 | ircomm_tty_ias_register(self); | 153 | ircomm_tty_ias_register(self); |
| 148 | 154 | ||
| @@ -398,23 +404,26 @@ void ircomm_tty_disconnect_indication(void *instance, void *sap, | |||
| 398 | struct sk_buff *skb) | 404 | struct sk_buff *skb) |
| 399 | { | 405 | { |
| 400 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; | 406 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; |
| 407 | struct tty_struct *tty; | ||
| 401 | 408 | ||
| 402 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 409 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
| 403 | 410 | ||
| 404 | IRDA_ASSERT(self != NULL, return;); | 411 | IRDA_ASSERT(self != NULL, return;); |
| 405 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 412 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
| 406 | 413 | ||
| 407 | if (!self->tty) | 414 | tty = tty_port_tty_get(&self->port); |
| 415 | if (!tty) | ||
| 408 | return; | 416 | return; |
| 409 | 417 | ||
| 410 | /* This will stop control data transfers */ | 418 | /* This will stop control data transfers */ |
| 411 | self->flow = FLOW_STOP; | 419 | self->flow = FLOW_STOP; |
| 412 | 420 | ||
| 413 | /* Stop data transfers */ | 421 | /* Stop data transfers */ |
| 414 | self->tty->hw_stopped = 1; | 422 | tty->hw_stopped = 1; |
| 415 | 423 | ||
| 416 | ircomm_tty_do_event(self, IRCOMM_TTY_DISCONNECT_INDICATION, NULL, | 424 | ircomm_tty_do_event(self, IRCOMM_TTY_DISCONNECT_INDICATION, NULL, |
| 417 | NULL); | 425 | NULL); |
| 426 | tty_kref_put(tty); | ||
| 418 | } | 427 | } |
| 419 | 428 | ||
| 420 | /* | 429 | /* |
| @@ -550,12 +559,15 @@ void ircomm_tty_connect_indication(void *instance, void *sap, | |||
| 550 | */ | 559 | */ |
| 551 | void ircomm_tty_link_established(struct ircomm_tty_cb *self) | 560 | void ircomm_tty_link_established(struct ircomm_tty_cb *self) |
| 552 | { | 561 | { |
| 562 | struct tty_struct *tty; | ||
| 563 | |||
| 553 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 564 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
| 554 | 565 | ||
| 555 | IRDA_ASSERT(self != NULL, return;); | 566 | IRDA_ASSERT(self != NULL, return;); |
| 556 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 567 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
| 557 | 568 | ||
| 558 | if (!self->tty) | 569 | tty = tty_port_tty_get(&self->port); |
| 570 | if (!tty) | ||
| 559 | return; | 571 | return; |
| 560 | 572 | ||
| 561 | del_timer(&self->watchdog_timer); | 573 | del_timer(&self->watchdog_timer); |
| @@ -566,19 +578,22 @@ void ircomm_tty_link_established(struct ircomm_tty_cb *self) | |||
| 566 | * will have to wait for the peer device (DCE) to raise the CTS | 578 | * will have to wait for the peer device (DCE) to raise the CTS |
| 567 | * line. | 579 | * line. |
| 568 | */ | 580 | */ |
| 569 | if ((self->flags & ASYNC_CTS_FLOW) && ((self->settings.dce & IRCOMM_CTS) == 0)) { | 581 | if (tty_port_cts_enabled(&self->port) && |
| 582 | ((self->settings.dce & IRCOMM_CTS) == 0)) { | ||
| 570 | IRDA_DEBUG(0, "%s(), waiting for CTS ...\n", __func__ ); | 583 | IRDA_DEBUG(0, "%s(), waiting for CTS ...\n", __func__ ); |
| 571 | return; | 584 | goto put; |
| 572 | } else { | 585 | } else { |
| 573 | IRDA_DEBUG(1, "%s(), starting hardware!\n", __func__ ); | 586 | IRDA_DEBUG(1, "%s(), starting hardware!\n", __func__ ); |
| 574 | 587 | ||
| 575 | self->tty->hw_stopped = 0; | 588 | tty->hw_stopped = 0; |
| 576 | 589 | ||
| 577 | /* Wake up processes blocked on open */ | 590 | /* Wake up processes blocked on open */ |
| 578 | wake_up_interruptible(&self->open_wait); | 591 | wake_up_interruptible(&self->port.open_wait); |
| 579 | } | 592 | } |
| 580 | 593 | ||
| 581 | schedule_work(&self->tqueue); | 594 | schedule_work(&self->tqueue); |
| 595 | put: | ||
| 596 | tty_kref_put(tty); | ||
| 582 | } | 597 | } |
| 583 | 598 | ||
| 584 | /* | 599 | /* |
| @@ -977,14 +992,17 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self, | |||
| 977 | ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH); | 992 | ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH); |
| 978 | ircomm_tty_start_watchdog_timer(self, 3*HZ); | 993 | ircomm_tty_start_watchdog_timer(self, 3*HZ); |
| 979 | 994 | ||
| 980 | if (self->flags & ASYNC_CHECK_CD) { | 995 | if (self->port.flags & ASYNC_CHECK_CD) { |
| 981 | /* Drop carrier */ | 996 | /* Drop carrier */ |
| 982 | self->settings.dce = IRCOMM_DELTA_CD; | 997 | self->settings.dce = IRCOMM_DELTA_CD; |
| 983 | ircomm_tty_check_modem_status(self); | 998 | ircomm_tty_check_modem_status(self); |
| 984 | } else { | 999 | } else { |
| 1000 | struct tty_struct *tty = tty_port_tty_get(&self->port); | ||
| 985 | IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ ); | 1001 | IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ ); |
| 986 | if (self->tty) | 1002 | if (tty) { |
| 987 | tty_hangup(self->tty); | 1003 | tty_hangup(tty); |
| 1004 | tty_kref_put(tty); | ||
| 1005 | } | ||
| 988 | } | 1006 | } |
| 989 | break; | 1007 | break; |
| 990 | default: | 1008 | default: |
diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c index d0667d68351d..b343f50dc8d7 100644 --- a/net/irda/ircomm/ircomm_tty_ioctl.c +++ b/net/irda/ircomm/ircomm_tty_ioctl.c | |||
| @@ -52,17 +52,18 @@ | |||
| 52 | * Change speed of the driver. If the remote device is a DCE, then this | 52 | * Change speed of the driver. If the remote device is a DCE, then this |
| 53 | * should make it change the speed of its serial port | 53 | * should make it change the speed of its serial port |
| 54 | */ | 54 | */ |
| 55 | static void ircomm_tty_change_speed(struct ircomm_tty_cb *self) | 55 | static void ircomm_tty_change_speed(struct ircomm_tty_cb *self, |
| 56 | struct tty_struct *tty) | ||
| 56 | { | 57 | { |
| 57 | unsigned int cflag, cval; | 58 | unsigned int cflag, cval; |
| 58 | int baud; | 59 | int baud; |
| 59 | 60 | ||
| 60 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 61 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
| 61 | 62 | ||
| 62 | if (!self->tty || !self->tty->termios || !self->ircomm) | 63 | if (!self->ircomm) |
| 63 | return; | 64 | return; |
| 64 | 65 | ||
| 65 | cflag = self->tty->termios->c_cflag; | 66 | cflag = tty->termios.c_cflag; |
| 66 | 67 | ||
| 67 | /* byte size and parity */ | 68 | /* byte size and parity */ |
| 68 | switch (cflag & CSIZE) { | 69 | switch (cflag & CSIZE) { |
| @@ -81,7 +82,7 @@ static void ircomm_tty_change_speed(struct ircomm_tty_cb *self) | |||
| 81 | cval |= IRCOMM_PARITY_EVEN; | 82 | cval |= IRCOMM_PARITY_EVEN; |
| 82 | 83 | ||
| 83 | /* Determine divisor based on baud rate */ | 84 | /* Determine divisor based on baud rate */ |
| 84 | baud = tty_get_baud_rate(self->tty); | 85 | baud = tty_get_baud_rate(tty); |
| 85 | if (!baud) | 86 | if (!baud) |
| 86 | baud = 9600; /* B0 transition handled in rs_set_termios */ | 87 | baud = 9600; /* B0 transition handled in rs_set_termios */ |
| 87 | 88 | ||
| @@ -90,19 +91,19 @@ static void ircomm_tty_change_speed(struct ircomm_tty_cb *self) | |||
| 90 | 91 | ||
| 91 | /* CTS flow control flag and modem status interrupts */ | 92 | /* CTS flow control flag and modem status interrupts */ |
| 92 | if (cflag & CRTSCTS) { | 93 | if (cflag & CRTSCTS) { |
| 93 | self->flags |= ASYNC_CTS_FLOW; | 94 | self->port.flags |= ASYNC_CTS_FLOW; |
| 94 | self->settings.flow_control |= IRCOMM_RTS_CTS_IN; | 95 | self->settings.flow_control |= IRCOMM_RTS_CTS_IN; |
| 95 | /* This got me. Bummer. Jean II */ | 96 | /* This got me. Bummer. Jean II */ |
| 96 | if (self->service_type == IRCOMM_3_WIRE_RAW) | 97 | if (self->service_type == IRCOMM_3_WIRE_RAW) |
| 97 | IRDA_WARNING("%s(), enabling RTS/CTS on link that doesn't support it (3-wire-raw)\n", __func__); | 98 | IRDA_WARNING("%s(), enabling RTS/CTS on link that doesn't support it (3-wire-raw)\n", __func__); |
| 98 | } else { | 99 | } else { |
| 99 | self->flags &= ~ASYNC_CTS_FLOW; | 100 | self->port.flags &= ~ASYNC_CTS_FLOW; |
| 100 | self->settings.flow_control &= ~IRCOMM_RTS_CTS_IN; | 101 | self->settings.flow_control &= ~IRCOMM_RTS_CTS_IN; |
| 101 | } | 102 | } |
| 102 | if (cflag & CLOCAL) | 103 | if (cflag & CLOCAL) |
| 103 | self->flags &= ~ASYNC_CHECK_CD; | 104 | self->port.flags &= ~ASYNC_CHECK_CD; |
| 104 | else | 105 | else |
| 105 | self->flags |= ASYNC_CHECK_CD; | 106 | self->port.flags |= ASYNC_CHECK_CD; |
| 106 | #if 0 | 107 | #if 0 |
| 107 | /* | 108 | /* |
| 108 | * Set up parity check flag | 109 | * Set up parity check flag |
| @@ -148,18 +149,18 @@ void ircomm_tty_set_termios(struct tty_struct *tty, | |||
| 148 | struct ktermios *old_termios) | 149 | struct ktermios *old_termios) |
| 149 | { | 150 | { |
| 150 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 151 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
| 151 | unsigned int cflag = tty->termios->c_cflag; | 152 | unsigned int cflag = tty->termios.c_cflag; |
| 152 | 153 | ||
| 153 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 154 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
| 154 | 155 | ||
| 155 | if ((cflag == old_termios->c_cflag) && | 156 | if ((cflag == old_termios->c_cflag) && |
| 156 | (RELEVANT_IFLAG(tty->termios->c_iflag) == | 157 | (RELEVANT_IFLAG(tty->termios.c_iflag) == |
| 157 | RELEVANT_IFLAG(old_termios->c_iflag))) | 158 | RELEVANT_IFLAG(old_termios->c_iflag))) |
| 158 | { | 159 | { |
| 159 | return; | 160 | return; |
| 160 | } | 161 | } |
| 161 | 162 | ||
| 162 | ircomm_tty_change_speed(self); | 163 | ircomm_tty_change_speed(self, tty); |
| 163 | 164 | ||
| 164 | /* Handle transition to B0 status */ | 165 | /* Handle transition to B0 status */ |
| 165 | if ((old_termios->c_cflag & CBAUD) && | 166 | if ((old_termios->c_cflag & CBAUD) && |
| @@ -172,7 +173,7 @@ void ircomm_tty_set_termios(struct tty_struct *tty, | |||
| 172 | if (!(old_termios->c_cflag & CBAUD) && | 173 | if (!(old_termios->c_cflag & CBAUD) && |
| 173 | (cflag & CBAUD)) { | 174 | (cflag & CBAUD)) { |
| 174 | self->settings.dte |= IRCOMM_DTR; | 175 | self->settings.dte |= IRCOMM_DTR; |
| 175 | if (!(tty->termios->c_cflag & CRTSCTS) || | 176 | if (!(tty->termios.c_cflag & CRTSCTS) || |
| 176 | !test_bit(TTY_THROTTLED, &tty->flags)) { | 177 | !test_bit(TTY_THROTTLED, &tty->flags)) { |
| 177 | self->settings.dte |= IRCOMM_RTS; | 178 | self->settings.dte |= IRCOMM_RTS; |
| 178 | } | 179 | } |
| @@ -181,7 +182,7 @@ void ircomm_tty_set_termios(struct tty_struct *tty, | |||
| 181 | 182 | ||
| 182 | /* Handle turning off CRTSCTS */ | 183 | /* Handle turning off CRTSCTS */ |
| 183 | if ((old_termios->c_cflag & CRTSCTS) && | 184 | if ((old_termios->c_cflag & CRTSCTS) && |
| 184 | !(tty->termios->c_cflag & CRTSCTS)) | 185 | !(tty->termios.c_cflag & CRTSCTS)) |
| 185 | { | 186 | { |
| 186 | tty->hw_stopped = 0; | 187 | tty->hw_stopped = 0; |
| 187 | ircomm_tty_start(tty); | 188 | ircomm_tty_start(tty); |
| @@ -270,10 +271,10 @@ static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self, | |||
| 270 | 271 | ||
| 271 | memset(&info, 0, sizeof(info)); | 272 | memset(&info, 0, sizeof(info)); |
| 272 | info.line = self->line; | 273 | info.line = self->line; |
| 273 | info.flags = self->flags; | 274 | info.flags = self->port.flags; |
| 274 | info.baud_base = self->settings.data_rate; | 275 | info.baud_base = self->settings.data_rate; |
| 275 | info.close_delay = self->close_delay; | 276 | info.close_delay = self->port.close_delay; |
| 276 | info.closing_wait = self->closing_wait; | 277 | info.closing_wait = self->port.closing_wait; |
| 277 | 278 | ||
| 278 | /* For compatibility */ | 279 | /* For compatibility */ |
| 279 | info.type = PORT_16550A; | 280 | info.type = PORT_16550A; |
