diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/arch/arm/plat-mxc/ehci.c linux-2.6.32-rc6-staging/arch/arm/plat-mxc/ehci.c --- linux-2.6.32-rc6/arch/arm/plat-mxc/ehci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.32-rc6-staging/arch/arm/plat-mxc/ehci.c 2009-11-06 20:57:32.000000000 -0800 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2009 Daniel Mack + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include +#include + +#define USBCTRL_OTGBASE_OFFSET 0x600 + +#define MX31_OTG_SIC_SHIFT 29 +#define MX31_OTG_SIC_MASK (0xf << MX31_OTG_SIC_SHIFT) +#define MX31_OTG_PM_BIT (1 << 24) + +#define MX31_H2_SIC_SHIFT 21 +#define MX31_H2_SIC_MASK (0xf << MX31_H2_SIC_SHIFT) +#define MX31_H2_PM_BIT (1 << 16) +#define MX31_H2_DT_BIT (1 << 5) + +#define MX31_H1_SIC_SHIFT 13 +#define MX31_H1_SIC_MASK (0xf << MX31_H1_SIC_SHIFT) +#define MX31_H1_PM_BIT (1 << 8) +#define MX31_H1_DT_BIT (1 << 4) + +int mxc_set_usbcontrol(int port, unsigned int flags) +{ + unsigned int v; + + if (cpu_is_mx31()) { + v = readl(IO_ADDRESS(MX31_OTG_BASE_ADDR + + USBCTRL_OTGBASE_OFFSET)); + + switch (port) { + case 0: /* OTG port */ + v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); + v |= (flags & MXC_EHCI_INTERFACE_MASK) + << MX31_OTG_SIC_SHIFT; + if (flags & MXC_EHCI_POWER_PINS_ENABLED) + v |= MX31_OTG_PM_BIT; + + break; + case 1: /* H1 port */ + v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT); + v |= (flags & MXC_EHCI_INTERFACE_MASK) + << MX31_H1_SIC_SHIFT; + if (flags & MXC_EHCI_POWER_PINS_ENABLED) + v |= MX31_H1_PM_BIT; + + if (!(flags & MXC_EHCI_TTL_ENABLED)) + v |= MX31_H1_DT_BIT; + + break; + case 2: /* H2 port */ + v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT); + v |= (flags & MXC_EHCI_INTERFACE_MASK) + << MX31_H2_SIC_SHIFT; + if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) + v |= MX31_H2_PM_BIT; + + if (!(flags & MXC_EHCI_TTL_ENABLED)) + v |= MX31_H2_DT_BIT; + + break; + } + + writel(v, IO_ADDRESS(MX31_OTG_BASE_ADDR + + USBCTRL_OTGBASE_OFFSET)); + return 0; + } + + printk(KERN_WARNING + "%s() unable to setup USBCONTROL for this CPU\n", __func__); + return -EINVAL; +} +EXPORT_SYMBOL(mxc_set_usbcontrol); + diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/arch/arm/plat-mxc/include/mach/mxc_ehci.h linux-2.6.32-rc6-staging/arch/arm/plat-mxc/include/mach/mxc_ehci.h --- linux-2.6.32-rc6/arch/arm/plat-mxc/include/mach/mxc_ehci.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.32-rc6-staging/arch/arm/plat-mxc/include/mach/mxc_ehci.h 2009-11-06 20:57:32.000000000 -0800 @@ -0,0 +1,37 @@ +#ifndef __INCLUDE_ASM_ARCH_MXC_EHCI_H +#define __INCLUDE_ASM_ARCH_MXC_EHCI_H + +/* values for portsc field */ +#define MXC_EHCI_PHY_LOW_POWER_SUSPEND (1 << 23) +#define MXC_EHCI_FORCE_FS (1 << 24) +#define MXC_EHCI_UTMI_8BIT (0 << 28) +#define MXC_EHCI_UTMI_16BIT (1 << 28) +#define MXC_EHCI_SERIAL (1 << 29) +#define MXC_EHCI_MODE_UTMI (0 << 30) +#define MXC_EHCI_MODE_PHILIPS (1 << 30) +#define MXC_EHCI_MODE_ULPI (2 << 30) +#define MXC_EHCI_MODE_SERIAL (3 << 30) + +/* values for flags field */ +#define MXC_EHCI_INTERFACE_DIFF_UNI (0 << 0) +#define MXC_EHCI_INTERFACE_DIFF_BI (1 << 0) +#define MXC_EHCI_INTERFACE_SINGLE_UNI (2 << 0) +#define MXC_EHCI_INTERFACE_SINGLE_BI (3 << 0) +#define MXC_EHCI_INTERFACE_MASK (0xf) + +#define MXC_EHCI_POWER_PINS_ENABLED (1 << 5) +#define MXC_EHCI_TTL_ENABLED (1 << 6) + +struct mxc_usbh_platform_data { + int (*init)(struct platform_device *pdev); + int (*exit)(struct platform_device *pdev); + + unsigned int portsc; + unsigned int flags; + struct otg_transceiver *otg; +}; + +int mxc_set_usbcontrol(int port, unsigned int flags); + +#endif /* __INCLUDE_ASM_ARCH_MXC_EHCI_H */ + diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/arch/arm/plat-mxc/Makefile linux-2.6.32-rc6-staging/arch/arm/plat-mxc/Makefile --- linux-2.6.32-rc6/arch/arm/plat-mxc/Makefile 2009-10-05 16:45:01.000000000 -0700 +++ linux-2.6.32-rc6-staging/arch/arm/plat-mxc/Makefile 2009-11-06 20:57:32.000000000 -0800 @@ -9,3 +9,4 @@ obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o obj-$(CONFIG_MXC_PWM) += pwm.o +obj-$(CONFIG_USB_EHCI_MXC) += ehci.o diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/arch/arm/plat-omap/include/mach/usb.h linux-2.6.32-rc6-staging/arch/arm/plat-omap/include/mach/usb.h --- linux-2.6.32-rc6/arch/arm/plat-omap/include/mach/usb.h 2009-10-05 16:45:02.000000000 -0700 +++ linux-2.6.32-rc6-staging/arch/arm/plat-omap/include/mach/usb.h 2009-11-06 20:57:32.000000000 -0800 @@ -5,6 +5,21 @@ #include +#define OMAP3_HS_USB_PORTS 3 +enum ehci_hcd_omap_mode { + EHCI_HCD_OMAP_MODE_UNKNOWN, + EHCI_HCD_OMAP_MODE_PHY, + EHCI_HCD_OMAP_MODE_TLL, +}; + +struct ehci_hcd_omap_platform_data { + enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; + unsigned phy_reset:1; + + /* have to be valid if phy_reset is true and portx is in phy mode */ + int reset_gpio_port[OMAP3_HS_USB_PORTS]; +}; + /*-------------------------------------------------------------------------*/ #define OMAP1_OTG_BASE 0xfffb0400 @@ -29,6 +44,8 @@ extern void usb_musb_init(void); +extern void usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata); + #endif void omap_usb_init(struct omap_usb_config *pdata); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/arch/xtensa/platforms/iss/console.c linux-2.6.32-rc6-staging/arch/xtensa/platforms/iss/console.c --- linux-2.6.32-rc6/arch/xtensa/platforms/iss/console.c 2009-10-05 16:43:42.000000000 -0700 +++ linux-2.6.32-rc6-staging/arch/xtensa/platforms/iss/console.c 2009-11-06 20:57:19.000000000 -0800 @@ -196,7 +196,7 @@ .release = single_release, }; -static struct tty_operations serial_ops = { +static const struct tty_operations serial_ops = { .open = rs_open, .close = rs_close, .write = rs_write, diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc linux-2.6.32-rc6-staging/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc --- linux-2.6.32-rc6/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc 2009-11-04 15:20:08.000000000 -0800 +++ linux-2.6.32-rc6-staging/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc 2009-11-06 20:57:32.000000000 -0800 @@ -23,3 +23,16 @@ Since this relates to security (specifically, the lifetime of PTKs and GTKs) it should not be changed from the default. + +What: /sys/class/uwb_rc/uwbN/wusbhc/wusb_phy_rate +Date: August 2009 +KernelVersion: 2.6.32 +Contact: David Vrabel +Description: + The maximum PHY rate to use for all connected devices. + This is only of limited use for testing and + development as the hardware's automatic rate + adaptation is better then this simple control. + + Refer to [ECMA-368] section 10.3.1.1 for the value to + use. diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/Documentation/powerpc/dts-bindings/xilinx.txt linux-2.6.32-rc6-staging/Documentation/powerpc/dts-bindings/xilinx.txt --- linux-2.6.32-rc6/Documentation/powerpc/dts-bindings/xilinx.txt 2009-10-05 16:45:00.000000000 -0700 +++ linux-2.6.32-rc6-staging/Documentation/powerpc/dts-bindings/xilinx.txt 2009-11-06 20:57:32.000000000 -0800 @@ -292,4 +292,15 @@ - reg-offset : A value of 3 is required - reg-shift : A value of 2 is required + vii) Xilinx USB Host controller + + The Xilinx USB host controller is EHCI compatible but with a different + base address for the EHCI registers, and it is always a big-endian + USB Host controller. The hardware can be configured as high speed only, + or high speed/full speed hybrid. + + Required properties: + - xlnx,support-usb-fs: A value 0 means the core is built as high speed + only. A value 1 means the core also supports + full speed devices. diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/Documentation/serial/hayes-esp.txt linux-2.6.32-rc6-staging/Documentation/serial/hayes-esp.txt --- linux-2.6.32-rc6/Documentation/serial/hayes-esp.txt 2009-03-23 16:12:14.000000000 -0700 +++ linux-2.6.32-rc6-staging/Documentation/serial/hayes-esp.txt 1969-12-31 16:00:00.000000000 -0800 @@ -1,154 +0,0 @@ -HAYES ESP DRIVER VERSION 2.1 - -A big thanks to the people at Hayes, especially Alan Adamson. Their support -has enabled me to provide enhancements to the driver. - -Please report your experiences with this driver to me (arobinso@nyx.net). I -am looking for both positive and negative feedback. - -*** IMPORTANT CHANGES FOR 2.1 *** -Support for PIO mode. Five situations will cause PIO mode to be used: -1) A multiport card is detected. PIO mode will always be used. (8 port cards -do not support DMA). -2) The DMA channel is set to an invalid value (anything other than 1 or 3). -3) The DMA buffer/channel could not be allocated. The port will revert to PIO -mode until it is reopened. -4) Less than a specified number of bytes need to be transferred to/from the -FIFOs. PIO mode will be used for that transfer only. -5) A port needs to do a DMA transfer and another port is already using the -DMA channel. PIO mode will be used for that transfer only. - -Since the Hayes ESP seems to conflict with other cards (notably sound cards) -when using DMA, DMA is turned off by default. To use DMA, it must be turned -on explicitly, either with the "dma=" option described below or with -setserial. A multiport card can be forced into DMA mode by using setserial; -however, most multiport cards don't support DMA. - -The latest version of setserial allows the enhanced configuration of the ESP -card to be viewed and modified. -*** - -This package contains the files needed to compile a module to support the Hayes -ESP card. The drivers are basically a modified version of the serial drivers. - -Features: - -- Uses the enhanced mode of the ESP card, allowing a wider range of - interrupts and features than compatibility mode -- Uses DMA and 16 bit PIO mode to transfer data to and from the ESP's FIFOs, - reducing CPU load -- Supports primary and secondary ports - - -If the driver is compiled as a module, the IRQs to use can be specified by -using the irq= option. The format is: - -irq=[0x100],[0x140],[0x180],[0x200],[0x240],[0x280],[0x300],[0x380] - -The address in brackets is the base address of the card. The IRQ of -nonexistent cards can be set to 0. If an IRQ of a card that does exist is set -to 0, the driver will attempt to guess at the correct IRQ. For example, to set -the IRQ of the card at address 0x300 to 12, the insmod command would be: - -insmod esp irq=0,0,0,0,0,0,12,0 - -The custom divisor can be set by using the divisor= option. The format is the -same as for the irq= option. Each divisor value is a series of hex digits, -with each digit representing the divisor to use for a corresponding port. The -divisor value is constructed RIGHT TO LEFT. Specifying a nonzero divisor value -will automatically set the spd_cust flag. To calculate the divisor to use for -a certain baud rate, divide the port's base baud (generally 921600) by the -desired rate. For example, to set the divisor of the primary port at 0x300 to -4 and the divisor of the secondary port at 0x308 to 8, the insmod command would -be: - -insmod esp divisor=0,0,0,0,0,0,0x84,0 - -The dma= option can be used to set the DMA channel. The channel can be either -1 or 3. Specifying any other value will force the driver to use PIO mode. -For example, to set the DMA channel to 3, the insmod command would be: - -insmod esp dma=3 - -The rx_trigger= and tx_trigger= options can be used to set the FIFO trigger -levels. They specify when the ESP card should send an interrupt. Larger -values will decrease the number of interrupts; however, a value too high may -result in data loss. Valid values are 1 through 1023, with 768 being the -default. For example, to set the receive trigger level to 512 bytes and the -transmit trigger level to 700 bytes, the insmod command would be: - -insmod esp rx_trigger=512 tx_trigger=700 - -The flow_off= and flow_on= options can be used to set the hardware flow off/ -flow on levels. The flow on level must be lower than the flow off level, and -the flow off level should be higher than rx_trigger. Valid values are 1 -through 1023, with 1016 being the default flow off level and 944 being the -default flow on level. For example, to set the flow off level to 1000 bytes -and the flow on level to 935 bytes, the insmod command would be: - -insmod esp flow_off=1000 flow_on=935 - -The rx_timeout= option can be used to set the receive timeout value. This -value indicates how long after receiving the last character that the ESP card -should wait before signalling an interrupt. Valid values are 0 though 255, -with 128 being the default. A value too high will increase latency, and a -value too low will cause unnecessary interrupts. For example, to set the -receive timeout to 255, the insmod command would be: - -insmod esp rx_timeout=255 - -The pio_threshold= option sets the threshold (in number of characters) for -using PIO mode instead of DMA mode. For example, if this value is 32, -transfers of 32 bytes or less will always use PIO mode. - -insmod esp pio_threshold=32 - -Multiple options can be listed on the insmod command line by separating each -option with a space. For example: - -insmod esp dma=3 trigger=512 - -The esp module can be automatically loaded when needed. To cause this to -happen, add the following lines to /etc/modprobe.conf (replacing the last line -with options for your configuration): - -alias char-major-57 esp -alias char-major-58 esp -options esp irq=0,0,0,0,0,0,3,0 divisor=0,0,0,0,0,0,0x4,0 - -You may also need to run 'depmod -a'. - -Devices must be created manually. To create the devices, note the output from -the module after it is inserted. The output will appear in the location where -kernel messages usually appear (usually /var/adm/messages). Create two devices -for each 'tty' mentioned, one with major of 57 and the other with major of 58. -The minor number should be the same as the tty number reported. The commands -would be (replace ? with the tty number): - -mknod /dev/ttyP? c 57 ? -mknod /dev/cup? c 58 ? - -For example, if the following line appears: - -Oct 24 18:17:23 techno kernel: ttyP8 at 0x0140 (irq = 3) is an ESP primary port - -...two devices should be created: - -mknod /dev/ttyP8 c 57 8 -mknod /dev/cup8 c 58 8 - -You may need to set the permissions on the devices: - -chmod 666 /dev/ttyP* -chmod 666 /dev/cup* - -The ESP module and the serial module should not conflict (they can be used at -the same time). After the ESP module has been loaded the ports on the ESP card -will no longer be accessible by the serial driver. - -If I/O errors are experienced when accessing the port, check for IRQ and DMA -conflicts ('cat /proc/interrupts' and 'cat /proc/dma' for a list of IRQs and -DMAs currently in use). - -Enjoy! -Andrew J. Robinson diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/Documentation/serial/tty.txt linux-2.6.32-rc6-staging/Documentation/serial/tty.txt --- linux-2.6.32-rc6/Documentation/serial/tty.txt 2009-03-23 16:12:14.000000000 -0700 +++ linux-2.6.32-rc6-staging/Documentation/serial/tty.txt 2009-11-06 20:57:19.000000000 -0800 @@ -42,7 +42,8 @@ open() - Called when the line discipline is attached to the terminal. No other call into the line discipline for this tty will occur until it - completes successfully. Can sleep. + completes successfully. Returning an error will + prevent the ldisc from being attached. Can sleep. close() - This is called on a terminal when the line discipline is being unplugged. At the point of @@ -52,7 +53,7 @@ hangup() - Called when the tty line is hung up. The line discipline should cease I/O to the tty. No further calls into the ldisc code will occur. - Can sleep. + The return value is ignored. Can sleep. write() - A process is writing data through the line discipline. Multiple write calls are serialized @@ -83,6 +84,10 @@ that might be for the ldisc. Multiple ioctl calls may occur in parallel. May sleep. +compat_ioctl() - Called when a 32 bit ioctl is handed to the tty layer + that might be for the ldisc. Multiple ioctl calls + may occur in parallel. May sleep. + Driver Side Interfaces: receive_buf() - Hand buffers of bytes from the driver to the ldisc diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/base/core.c linux-2.6.32-rc6-staging/drivers/base/core.c --- linux-2.6.32-rc6/drivers/base/core.c 2009-11-04 15:20:15.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/base/core.c 2009-11-06 20:57:04.000000000 -0800 @@ -987,6 +987,8 @@ device_remove_class_symlinks(dev); SymlinkError: if (MAJOR(dev->devt)) + devtmpfs_delete_node(dev); + if (MAJOR(dev->devt)) device_remove_sys_dev_entry(dev); devtattrError: if (MAJOR(dev->devt)) @@ -1728,8 +1730,5 @@ dev->driver->shutdown(dev); } } - kobject_put(sysfs_dev_char_kobj); - kobject_put(sysfs_dev_block_kobj); - kobject_put(dev_kobj); async_synchronize_full(); } diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/base/devtmpfs.c linux-2.6.32-rc6-staging/drivers/base/devtmpfs.c --- linux-2.6.32-rc6/drivers/base/devtmpfs.c 2009-11-04 15:20:15.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/base/devtmpfs.c 2009-11-06 20:57:04.000000000 -0800 @@ -32,6 +32,8 @@ static int dev_mount; #endif +static rwlock_t dirlock; + static int __init mount_param(char *str) { dev_mount = simple_strtoul(str, NULL, 0); @@ -74,47 +76,35 @@ dentry = lookup_create(&nd, 1); if (!IS_ERR(dentry)) { err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); + if (!err) + /* mark as kernel-created inode */ + dentry->d_inode->i_private = &dev_mnt; dput(dentry); } else { err = PTR_ERR(dentry); } - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); + mutex_unlock(&nd.path.dentry->d_inode->i_mutex); path_put(&nd.path); return err; } static int create_path(const char *nodepath) { - char *path; - struct nameidata nd; - int err = 0; - - path = kstrdup(nodepath, GFP_KERNEL); - if (!path) - return -ENOMEM; - - err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, - path, LOOKUP_PARENT, &nd); - if (err == 0) { - struct dentry *dentry; - - /* create directory right away */ - dentry = lookup_create(&nd, 1); - if (!IS_ERR(dentry)) { - err = vfs_mkdir(nd.path.dentry->d_inode, - dentry, 0755); - dput(dentry); - } - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); + int err; - path_put(&nd.path); - } else if (err == -ENOENT) { + read_lock(&dirlock); + err = dev_mkdir(nodepath, 0755); + if (err == -ENOENT) { + char *path; char *s; /* parent directories do not exist, create them */ + path = kstrdup(nodepath, GFP_KERNEL); + if (!path) + return -ENOMEM; s = path; - while (1) { + for (;;) { s = strchr(s, '/'); if (!s) break; @@ -125,9 +115,9 @@ s[0] = '/'; s++; } + kfree(path); } - - kfree(path); + read_unlock(&dirlock); return err; } @@ -156,34 +146,38 @@ mode |= S_IFCHR; curr_cred = override_creds(&init_cred); + err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, nodename, LOOKUP_PARENT, &nd); if (err == -ENOENT) { - /* create missing parent directories */ create_path(nodename); err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, nodename, LOOKUP_PARENT, &nd); - if (err) - goto out; } + if (err) + goto out; dentry = lookup_create(&nd, 0); if (!IS_ERR(dentry)) { - int umask; - - umask = sys_umask(0000); err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, dev->devt); - sys_umask(umask); - /* mark as kernel created inode */ - if (!err) + if (!err) { + struct iattr newattrs; + + /* fixup possibly umasked mode */ + newattrs.ia_mode = mode; + newattrs.ia_valid = ATTR_MODE; + notify_change(dentry, &newattrs); + + /* mark as kernel-created inode */ dentry->d_inode->i_private = &dev_mnt; + } dput(dentry); } else { err = PTR_ERR(dentry); } - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); + mutex_unlock(&nd.path.dentry->d_inode->i_mutex); path_put(&nd.path); out: kfree(tmp); @@ -205,16 +199,21 @@ mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len); if (!IS_ERR(dentry)) { - if (dentry->d_inode) - err = vfs_rmdir(nd.path.dentry->d_inode, dentry); - else + if (dentry->d_inode) { + if (dentry->d_inode->i_private == &dev_mnt) + err = vfs_rmdir(nd.path.dentry->d_inode, + dentry); + else + err = -EPERM; + } else { err = -ENOENT; + } dput(dentry); } else { err = PTR_ERR(dentry); } - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); + mutex_unlock(&nd.path.dentry->d_inode->i_mutex); path_put(&nd.path); return err; } @@ -228,7 +227,8 @@ if (!path) return -ENOMEM; - while (1) { + write_lock(&dirlock); + for (;;) { char *base; base = strrchr(path, '/'); @@ -239,6 +239,7 @@ if (err) break; } + write_unlock(&dirlock); kfree(path); return err; @@ -322,9 +323,8 @@ * If configured, or requested by the commandline, devtmpfs will be * auto-mounted after the kernel mounted the root filesystem. */ -int devtmpfs_mount(const char *mountpoint) +int devtmpfs_mount(const char *mntdir) { - struct path path; int err; if (!dev_mount) @@ -333,15 +333,11 @@ if (!dev_mnt) return 0; - err = kern_path(mountpoint, LOOKUP_FOLLOW, &path); - if (err) - return err; - err = do_add_mount(dev_mnt, &path, 0, NULL); + err = sys_mount("none", (char *)mntdir, "devtmpfs", MS_SILENT, NULL); if (err) printk(KERN_INFO "devtmpfs: error mounting %i\n", err); else printk(KERN_INFO "devtmpfs: mounted\n"); - path_put(&path); return err; } @@ -354,6 +350,8 @@ int err; struct vfsmount *mnt; + rwlock_init(&dirlock); + err = register_filesystem(&dev_fs_type); if (err) { printk(KERN_ERR "devtmpfs: unable to register devtmpfs " @@ -361,7 +359,7 @@ return err; } - mnt = kern_mount(&dev_fs_type); + mnt = kern_mount_data(&dev_fs_type, "mode=0755"); if (IS_ERR(mnt)) { err = PTR_ERR(mnt); printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/base/firmware_class.c linux-2.6.32-rc6-staging/drivers/base/firmware_class.c --- linux-2.6.32-rc6/drivers/base/firmware_class.c 2009-10-05 16:45:07.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/base/firmware_class.c 2009-11-06 20:57:04.000000000 -0800 @@ -601,12 +601,9 @@ } ret = _request_firmware(&fw, fw_work->name, fw_work->device, fw_work->uevent); - if (ret < 0) - fw_work->cont(NULL, fw_work->context); - else { - fw_work->cont(fw, fw_work->context); - release_firmware(fw); - } + + fw_work->cont(fw, fw_work->context); + module_put(fw_work->module); kfree(fw_work); return ret; @@ -619,6 +616,7 @@ * is non-zero else the firmware copy must be done manually. * @name: name of firmware file * @device: device for which firmware is being loaded + * @gfp: allocation flags * @context: will be passed over to @cont, and * @fw may be %NULL if firmware request fails. * @cont: function will be called asynchronously when the firmware @@ -631,12 +629,12 @@ int request_firmware_nowait( struct module *module, int uevent, - const char *name, struct device *device, void *context, + const char *name, struct device *device, gfp_t gfp, void *context, void (*cont)(const struct firmware *fw, void *context)) { struct task_struct *task; struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work), - GFP_ATOMIC); + gfp); if (!fw_work) return -ENOMEM; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/char/bfin_jtag_comm.c linux-2.6.32-rc6-staging/drivers/char/bfin_jtag_comm.c --- linux-2.6.32-rc6/drivers/char/bfin_jtag_comm.c 2009-10-05 16:45:07.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/char/bfin_jtag_comm.c 2009-11-06 20:57:19.000000000 -0800 @@ -226,7 +226,7 @@ } } -static struct tty_operations bfin_jc_ops = { +static const struct tty_operations bfin_jc_ops = { .open = bfin_jc_open, .close = bfin_jc_close, .write = bfin_jc_write, diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/char/epca.c linux-2.6.32-rc6-staging/drivers/char/epca.c --- linux-2.6.32-rc6/drivers/char/epca.c 2009-11-04 15:20:15.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/char/epca.c 2009-11-06 20:57:19.000000000 -0800 @@ -935,7 +935,7 @@ return 0; } -static struct tty_operations info_ops = { +static const struct tty_operations info_ops = { .open = info_open, .ioctl = info_ioctl, }; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/char/esp.c linux-2.6.32-rc6-staging/drivers/char/esp.c --- linux-2.6.32-rc6/drivers/char/esp.c 2009-11-04 15:20:15.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/char/esp.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,2533 +0,0 @@ -/* - * esp.c - driver for Hayes ESP serial cards - * - * --- Notices from serial.c, upon which this driver is based --- - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92. Now - * much more extensible to support other serial cards based on the - * 16450/16550A UART's. Added support for the AST FourPort and the - * Accent Async board. - * - * set_serial_info fixed to set the flags, custom divisor, and uart - * type fields. Fix suggested by Michael K. Johnson 12/12/92. - * - * 11/95: TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis - * - * 03/96: Modularised by Angelo Haritsis - * - * rs_set_termios fixed to look also for changes of the input - * flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK. - * Bernd Anhäupl 05/17/96. - * - * --- End of notices from serial.c --- - * - * Support for the ESP serial card by Andrew J. Robinson - * (Card detection routine taken from a patch - * by Dennis J. Boylan). Patches to allow use with 2.1.x contributed - * by Chris Faylor. - * - * Most recent changes: (Andrew J. Robinson) - * Support for PIO mode. This allows the driver to work properly with - * multiport cards. - * - * Arnaldo Carvalho de Melo - - * several cleanups, use module_init/module_exit, etc - * - * This module exports the following rs232 io functions: - * - * int espserial_init(void); - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include - -#define NR_PORTS 64 /* maximum number of ports */ -#define NR_PRIMARY 8 /* maximum number of primary ports */ -#define REGION_SIZE 8 /* size of io region to request */ - -/* The following variables can be set by giving module options */ -static int irq[NR_PRIMARY]; /* IRQ for each base port */ -static unsigned int divisor[NR_PRIMARY]; /* custom divisor for each port */ -static unsigned int dma = ESP_DMA_CHANNEL; /* DMA channel */ -static unsigned int rx_trigger = ESP_RX_TRIGGER; -static unsigned int tx_trigger = ESP_TX_TRIGGER; -static unsigned int flow_off = ESP_FLOW_OFF; -static unsigned int flow_on = ESP_FLOW_ON; -static unsigned int rx_timeout = ESP_RX_TMOUT; -static unsigned int pio_threshold = ESP_PIO_THRESHOLD; - -MODULE_LICENSE("GPL"); - -module_param_array(irq, int, NULL, 0); -module_param_array(divisor, uint, NULL, 0); -module_param(dma, uint, 0); -module_param(rx_trigger, uint, 0); -module_param(tx_trigger, uint, 0); -module_param(flow_off, uint, 0); -module_param(flow_on, uint, 0); -module_param(rx_timeout, uint, 0); -module_param(pio_threshold, uint, 0); - -/* END */ - -static char *dma_buffer; -static int dma_bytes; -static struct esp_pio_buffer *free_pio_buf; - -#define DMA_BUFFER_SZ 1024 - -#define WAKEUP_CHARS 1024 - -static char serial_name[] __initdata = "ESP serial driver"; -static char serial_version[] __initdata = "2.2"; - -static struct tty_driver *esp_driver; - -/* - * Serial driver configuration section. Here are the various options: - * - * SERIAL_PARANOIA_CHECK - * Check the magic number for the esp_structure where - * ever possible. - */ - -#undef SERIAL_PARANOIA_CHECK -#define SERIAL_DO_RESTART - -#undef SERIAL_DEBUG_INTR -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_FLOW - -#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) -#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ - tty->name, info->port.flags, \ - serial_driver.refcount, \ - info->port.count, tty->count, s) -#else -#define DBG_CNT(s) -#endif - -static struct esp_struct *ports; - -static void change_speed(struct esp_struct *info); -static void rs_wait_until_sent(struct tty_struct *, int); - -/* - * The ESP card has a clock rate of 14.7456 MHz (that is, 2**ESPC_SCALE - * times the normal 1.8432 Mhz clock of most serial boards). - */ -#define BASE_BAUD ((1843200 / 16) * (1 << ESPC_SCALE)) - -/* Standard COM flags (except for COM4, because of the 8514 problem) */ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) - -static inline int serial_paranoia_check(struct esp_struct *info, - char *name, const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - static const char badmagic[] = KERN_WARNING - "Warning: bad magic number for serial struct (%s) in %s\n"; - static const char badinfo[] = KERN_WARNING - "Warning: null esp_struct for (%s) in %s\n"; - - if (!info) { - printk(badinfo, name, routine); - return 1; - } - if (info->magic != ESP_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#endif - return 0; -} - -static inline unsigned int serial_in(struct esp_struct *info, int offset) -{ - return inb(info->io_port + offset); -} - -static inline void serial_out(struct esp_struct *info, int offset, - unsigned char value) -{ - outb(value, info->io_port+offset); -} - -/* - * ------------------------------------------------------------ - * rs_stop() and rs_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rs_stop(struct tty_struct *tty) -{ - struct esp_struct *info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_stop")) - return; - - spin_lock_irqsave(&info->lock, flags); - if (info->IER & UART_IER_THRI) { - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); - serial_out(info, UART_ESI_CMD2, info->IER); - } - spin_unlock_irqrestore(&info->lock, flags); -} - -static void rs_start(struct tty_struct *tty) -{ - struct esp_struct *info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_start")) - return; - - spin_lock_irqsave(&info->lock, flags); - if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) { - info->IER |= UART_IER_THRI; - serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); - serial_out(info, UART_ESI_CMD2, info->IER); - } - spin_unlock_irqrestore(&info->lock, flags); -} - -/* - * ---------------------------------------------------------------------- - * - * Here starts the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * rs_interrupt(). They were separated out for readability's sake. - * - * Note: rs_interrupt() is a "fast" interrupt, which means that it - * runs with interrupts turned off. People who may want to modify - * rs_interrupt() should try to keep the interrupt handler as fast as - * possible. After you are done making modifications, it is not a bad - * idea to do: - * - * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c - * - * and look at the resulting assemble code in serial.s. - * - * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 - * ----------------------------------------------------------------------- - */ - -static DEFINE_SPINLOCK(pio_lock); - -static inline struct esp_pio_buffer *get_pio_buffer(void) -{ - struct esp_pio_buffer *buf; - unsigned long flags; - - spin_lock_irqsave(&pio_lock, flags); - if (free_pio_buf) { - buf = free_pio_buf; - free_pio_buf = buf->next; - } else { - buf = kmalloc(sizeof(struct esp_pio_buffer), GFP_ATOMIC); - } - spin_unlock_irqrestore(&pio_lock, flags); - return buf; -} - -static inline void release_pio_buffer(struct esp_pio_buffer *buf) -{ - unsigned long flags; - spin_lock_irqsave(&pio_lock, flags); - buf->next = free_pio_buf; - free_pio_buf = buf; - spin_unlock_irqrestore(&pio_lock, flags); -} - -static inline void receive_chars_pio(struct esp_struct *info, int num_bytes) -{ - struct tty_struct *tty = info->port.tty; - int i; - struct esp_pio_buffer *pio_buf; - struct esp_pio_buffer *err_buf; - unsigned char status_mask; - - pio_buf = get_pio_buffer(); - - if (!pio_buf) - return; - - err_buf = get_pio_buffer(); - - if (!err_buf) { - release_pio_buffer(pio_buf); - return; - } - - status_mask = (info->read_status_mask >> 2) & 0x07; - - for (i = 0; i < num_bytes - 1; i += 2) { - *((unsigned short *)(pio_buf->data + i)) = - inw(info->io_port + UART_ESI_RX); - err_buf->data[i] = serial_in(info, UART_ESI_RWS); - err_buf->data[i + 1] = (err_buf->data[i] >> 3) & status_mask; - err_buf->data[i] &= status_mask; - } - - if (num_bytes & 0x0001) { - pio_buf->data[num_bytes - 1] = serial_in(info, UART_ESI_RX); - err_buf->data[num_bytes - 1] = - (serial_in(info, UART_ESI_RWS) >> 3) & status_mask; - } - - /* make sure everything is still ok since interrupts were enabled */ - tty = info->port.tty; - - if (!tty) { - release_pio_buffer(pio_buf); - release_pio_buffer(err_buf); - info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; - return; - } - - status_mask = (info->ignore_status_mask >> 2) & 0x07; - - for (i = 0; i < num_bytes; i++) { - if (!(err_buf->data[i] & status_mask)) { - int flag = 0; - - if (err_buf->data[i] & 0x04) { - flag = TTY_BREAK; - if (info->port.flags & ASYNC_SAK) - do_SAK(tty); - } else if (err_buf->data[i] & 0x02) - flag = TTY_FRAME; - else if (err_buf->data[i] & 0x01) - flag = TTY_PARITY; - tty_insert_flip_char(tty, pio_buf->data[i], flag); - } - } - - tty_schedule_flip(tty); - - info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; - release_pio_buffer(pio_buf); - release_pio_buffer(err_buf); -} - -static void program_isa_dma(int dma, int dir, unsigned long addr, int len) -{ - unsigned long flags; - - flags = claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - set_dma_mode(dma, dir); - set_dma_addr(dma, addr); - set_dma_count(dma, len); - enable_dma(dma); - release_dma_lock(flags); -} - -static void receive_chars_dma(struct esp_struct *info, int num_bytes) -{ - info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; - dma_bytes = num_bytes; - info->stat_flags |= ESP_STAT_DMA_RX; - - program_isa_dma(dma, DMA_MODE_READ, isa_virt_to_bus(dma_buffer), - dma_bytes); - serial_out(info, UART_ESI_CMD1, ESI_START_DMA_RX); -} - -static inline void receive_chars_dma_done(struct esp_struct *info, - int status) -{ - struct tty_struct *tty = info->port.tty; - int num_bytes; - unsigned long flags; - - flags = claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - - info->stat_flags &= ~ESP_STAT_DMA_RX; - num_bytes = dma_bytes - get_dma_residue(dma); - release_dma_lock(flags); - - info->icount.rx += num_bytes; - - if (num_bytes > 0) { - tty_insert_flip_string(tty, dma_buffer, num_bytes - 1); - - status &= (0x1c & info->read_status_mask); - - /* Is the status significant or do we throw the last byte ? */ - if (!(status & info->ignore_status_mask)) { - int statflag = 0; - - if (status & 0x10) { - statflag = TTY_BREAK; - (info->icount.brk)++; - if (info->port.flags & ASYNC_SAK) - do_SAK(tty); - } else if (status & 0x08) { - statflag = TTY_FRAME; - info->icount.frame++; - } else if (status & 0x04) { - statflag = TTY_PARITY; - info->icount.parity++; - } - tty_insert_flip_char(tty, dma_buffer[num_bytes - 1], - statflag); - } - tty_schedule_flip(tty); - } - - if (dma_bytes != num_bytes) { - num_bytes = dma_bytes - num_bytes; - dma_bytes = 0; - receive_chars_dma(info, num_bytes); - } else - dma_bytes = 0; -} - -/* Caller must hold info->lock */ - -static inline void transmit_chars_pio(struct esp_struct *info, - int space_avail) -{ - int i; - struct esp_pio_buffer *pio_buf; - - pio_buf = get_pio_buffer(); - - if (!pio_buf) - return; - - while (space_avail && info->xmit_cnt) { - if (info->xmit_tail + space_avail <= ESP_XMIT_SIZE) { - memcpy(pio_buf->data, - &(info->xmit_buf[info->xmit_tail]), - space_avail); - } else { - i = ESP_XMIT_SIZE - info->xmit_tail; - memcpy(pio_buf->data, - &(info->xmit_buf[info->xmit_tail]), i); - memcpy(&(pio_buf->data[i]), info->xmit_buf, - space_avail - i); - } - - info->xmit_cnt -= space_avail; - info->xmit_tail = (info->xmit_tail + space_avail) & - (ESP_XMIT_SIZE - 1); - - for (i = 0; i < space_avail - 1; i += 2) { - outw(*((unsigned short *)(pio_buf->data + i)), - info->io_port + UART_ESI_TX); - } - - if (space_avail & 0x0001) - serial_out(info, UART_ESI_TX, - pio_buf->data[space_avail - 1]); - - if (info->xmit_cnt) { - serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); - serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL); - space_avail = serial_in(info, UART_ESI_STAT1) << 8; - space_avail |= serial_in(info, UART_ESI_STAT2); - - if (space_avail > info->xmit_cnt) - space_avail = info->xmit_cnt; - } - } - - if (info->xmit_cnt < WAKEUP_CHARS) { - if (info->port.tty) - tty_wakeup(info->port.tty); - -#ifdef SERIAL_DEBUG_INTR - printk("THRE..."); -#endif - - if (info->xmit_cnt <= 0) { - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_ESI_CMD1, - ESI_SET_SRV_MASK); - serial_out(info, UART_ESI_CMD2, info->IER); - } - } - - release_pio_buffer(pio_buf); -} - -/* Caller must hold info->lock */ -static inline void transmit_chars_dma(struct esp_struct *info, int num_bytes) -{ - dma_bytes = num_bytes; - - if (info->xmit_tail + dma_bytes <= ESP_XMIT_SIZE) { - memcpy(dma_buffer, &(info->xmit_buf[info->xmit_tail]), - dma_bytes); - } else { - int i = ESP_XMIT_SIZE - info->xmit_tail; - memcpy(dma_buffer, &(info->xmit_buf[info->xmit_tail]), - i); - memcpy(&(dma_buffer[i]), info->xmit_buf, dma_bytes - i); - } - - info->xmit_cnt -= dma_bytes; - info->xmit_tail = (info->xmit_tail + dma_bytes) & (ESP_XMIT_SIZE - 1); - - if (info->xmit_cnt < WAKEUP_CHARS) { - if (info->port.tty) - tty_wakeup(info->port.tty); - -#ifdef SERIAL_DEBUG_INTR - printk("THRE..."); -#endif - - if (info->xmit_cnt <= 0) { - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); - serial_out(info, UART_ESI_CMD2, info->IER); - } - } - - info->stat_flags |= ESP_STAT_DMA_TX; - - program_isa_dma(dma, DMA_MODE_WRITE, isa_virt_to_bus(dma_buffer), - dma_bytes); - serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX); -} - -static inline void transmit_chars_dma_done(struct esp_struct *info) -{ - int num_bytes; - unsigned long flags; - - flags = claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - - num_bytes = dma_bytes - get_dma_residue(dma); - info->icount.tx += dma_bytes; - release_dma_lock(flags); - - if (dma_bytes != num_bytes) { - dma_bytes -= num_bytes; - memmove(dma_buffer, dma_buffer + num_bytes, dma_bytes); - - program_isa_dma(dma, DMA_MODE_WRITE, - isa_virt_to_bus(dma_buffer), dma_bytes); - - serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX); - } else { - dma_bytes = 0; - info->stat_flags &= ~ESP_STAT_DMA_TX; - } -} - -static void check_modem_status(struct esp_struct *info) -{ - int status; - - serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT); - status = serial_in(info, UART_ESI_STAT2); - - if (status & UART_MSR_ANY_DELTA) { - /* update input line counters */ - if (status & UART_MSR_TERI) - info->icount.rng++; - if (status & UART_MSR_DDSR) - info->icount.dsr++; - if (status & UART_MSR_DDCD) - info->icount.dcd++; - if (status & UART_MSR_DCTS) - info->icount.cts++; - wake_up_interruptible(&info->port.delta_msr_wait); - } - - if ((info->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { -#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) - printk("ttys%d CD now %s...", info->line, - (status & UART_MSR_DCD) ? "on" : "off"); -#endif - if (status & UART_MSR_DCD) - wake_up_interruptible(&info->port.open_wait); - else { -#ifdef SERIAL_DEBUG_OPEN - printk("scheduling hangup..."); -#endif - tty_hangup(info->port.tty); - } - } -} - -/* - * This is the serial driver's interrupt routine - */ -static irqreturn_t rs_interrupt_single(int irq, void *dev_id) -{ - struct esp_struct *info; - unsigned err_status; - unsigned int scratch; - -#ifdef SERIAL_DEBUG_INTR - printk("rs_interrupt_single(%d)...", irq); -#endif - info = (struct esp_struct *)dev_id; - err_status = 0; - scratch = serial_in(info, UART_ESI_SID); - - spin_lock(&info->lock); - - if (!info->port.tty) { - spin_unlock(&info->lock); - return IRQ_NONE; - } - - if (scratch & 0x04) { /* error */ - serial_out(info, UART_ESI_CMD1, ESI_GET_ERR_STAT); - err_status = serial_in(info, UART_ESI_STAT1); - serial_in(info, UART_ESI_STAT2); - - if (err_status & 0x01) - info->stat_flags |= ESP_STAT_RX_TIMEOUT; - - if (err_status & 0x20) /* UART status */ - check_modem_status(info); - - if (err_status & 0x80) /* Start break */ - wake_up_interruptible(&info->break_wait); - } - - if ((scratch & 0x88) || /* DMA completed or timed out */ - (err_status & 0x1c) /* receive error */) { - if (info->stat_flags & ESP_STAT_DMA_RX) - receive_chars_dma_done(info, err_status); - else if (info->stat_flags & ESP_STAT_DMA_TX) - transmit_chars_dma_done(info); - } - - if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) && - ((scratch & 0x01) || (info->stat_flags & ESP_STAT_RX_TIMEOUT)) && - (info->IER & UART_IER_RDI)) { - int num_bytes; - - serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); - serial_out(info, UART_ESI_CMD1, ESI_GET_RX_AVAIL); - num_bytes = serial_in(info, UART_ESI_STAT1) << 8; - num_bytes |= serial_in(info, UART_ESI_STAT2); - - num_bytes = tty_buffer_request_room(info->port.tty, num_bytes); - - if (num_bytes) { - if (dma_bytes || - (info->stat_flags & ESP_STAT_USE_PIO) || - (num_bytes <= info->config.pio_threshold)) - receive_chars_pio(info, num_bytes); - else - receive_chars_dma(info, num_bytes); - } - } - - if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) && - (scratch & 0x02) && (info->IER & UART_IER_THRI)) { - if ((info->xmit_cnt <= 0) || info->port.tty->stopped) { - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); - serial_out(info, UART_ESI_CMD2, info->IER); - } else { - int num_bytes; - - serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); - serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL); - num_bytes = serial_in(info, UART_ESI_STAT1) << 8; - num_bytes |= serial_in(info, UART_ESI_STAT2); - - if (num_bytes > info->xmit_cnt) - num_bytes = info->xmit_cnt; - - if (num_bytes) { - if (dma_bytes || - (info->stat_flags & ESP_STAT_USE_PIO) || - (num_bytes <= info->config.pio_threshold)) - transmit_chars_pio(info, num_bytes); - else - transmit_chars_dma(info, num_bytes); - } - } - } - - info->last_active = jiffies; - -#ifdef SERIAL_DEBUG_INTR - printk("end.\n"); -#endif - spin_unlock(&info->lock); - return IRQ_HANDLED; -} - -/* - * ------------------------------------------------------------------- - * Here ends the serial interrupt routines. - * ------------------------------------------------------------------- - */ - -/* - * --------------------------------------------------------------- - * Low level utility subroutines for the serial driver: routines to - * figure out the appropriate timeout for an interrupt chain, routines - * to initialize and startup a serial port, and routines to shutdown a - * serial port. Useful stuff like that. - * - * Caller should hold lock - * --------------------------------------------------------------- - */ - -static void esp_basic_init(struct esp_struct *info) -{ - /* put ESPC in enhanced mode */ - serial_out(info, UART_ESI_CMD1, ESI_SET_MODE); - - if (info->stat_flags & ESP_STAT_NEVER_DMA) - serial_out(info, UART_ESI_CMD2, 0x01); - else - serial_out(info, UART_ESI_CMD2, 0x31); - - /* disable interrupts for now */ - serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); - serial_out(info, UART_ESI_CMD2, 0x00); - - /* set interrupt and DMA channel */ - serial_out(info, UART_ESI_CMD1, ESI_SET_IRQ); - - if (info->stat_flags & ESP_STAT_NEVER_DMA) - serial_out(info, UART_ESI_CMD2, 0x01); - else - serial_out(info, UART_ESI_CMD2, (dma << 4) | 0x01); - - serial_out(info, UART_ESI_CMD1, ESI_SET_ENH_IRQ); - - if (info->line % 8) /* secondary port */ - serial_out(info, UART_ESI_CMD2, 0x0d); /* shared */ - else if (info->irq == 9) - serial_out(info, UART_ESI_CMD2, 0x02); - else - serial_out(info, UART_ESI_CMD2, info->irq); - - /* set error status mask (check this) */ - serial_out(info, UART_ESI_CMD1, ESI_SET_ERR_MASK); - - if (info->stat_flags & ESP_STAT_NEVER_DMA) - serial_out(info, UART_ESI_CMD2, 0xa1); - else - serial_out(info, UART_ESI_CMD2, 0xbd); - - serial_out(info, UART_ESI_CMD2, 0x00); - - /* set DMA timeout */ - serial_out(info, UART_ESI_CMD1, ESI_SET_DMA_TMOUT); - serial_out(info, UART_ESI_CMD2, 0xff); - - /* set FIFO trigger levels */ - serial_out(info, UART_ESI_CMD1, ESI_SET_TRIGGER); - serial_out(info, UART_ESI_CMD2, info->config.rx_trigger >> 8); - serial_out(info, UART_ESI_CMD2, info->config.rx_trigger); - serial_out(info, UART_ESI_CMD2, info->config.tx_trigger >> 8); - serial_out(info, UART_ESI_CMD2, info->config.tx_trigger); - - /* Set clock scaling and wait states */ - serial_out(info, UART_ESI_CMD1, ESI_SET_PRESCALAR); - serial_out(info, UART_ESI_CMD2, 0x04 | ESPC_SCALE); - - /* set reinterrupt pacing */ - serial_out(info, UART_ESI_CMD1, ESI_SET_REINTR); - serial_out(info, UART_ESI_CMD2, 0xff); -} - -static int startup(struct esp_struct *info) -{ - unsigned long flags; - int retval = 0; - unsigned int num_chars; - - spin_lock_irqsave(&info->lock, flags); - - if (info->port.flags & ASYNC_INITIALIZED) - goto out; - - if (!info->xmit_buf) { - info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_ATOMIC); - retval = -ENOMEM; - if (!info->xmit_buf) - goto out; - } - -#ifdef SERIAL_DEBUG_OPEN - printk(KERN_DEBUG "starting up ttys%d (irq %d)...", - info->line, info->irq); -#endif - - /* Flush the RX buffer. Using the ESI flush command may cause */ - /* wild interrupts, so read all the data instead. */ - - serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); - serial_out(info, UART_ESI_CMD1, ESI_GET_RX_AVAIL); - num_chars = serial_in(info, UART_ESI_STAT1) << 8; - num_chars |= serial_in(info, UART_ESI_STAT2); - - while (num_chars > 1) { - inw(info->io_port + UART_ESI_RX); - num_chars -= 2; - } - - if (num_chars) - serial_in(info, UART_ESI_RX); - - /* set receive character timeout */ - serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT); - serial_out(info, UART_ESI_CMD2, info->config.rx_timeout); - - /* clear all flags except the "never DMA" flag */ - info->stat_flags &= ESP_STAT_NEVER_DMA; - - if (info->stat_flags & ESP_STAT_NEVER_DMA) - info->stat_flags |= ESP_STAT_USE_PIO; - - spin_unlock_irqrestore(&info->lock, flags); - - /* - * Allocate the IRQ - */ - - retval = request_irq(info->irq, rs_interrupt_single, IRQF_SHARED, - "esp serial", info); - - if (retval) { - if (capable(CAP_SYS_ADMIN)) { - if (info->port.tty) - set_bit(TTY_IO_ERROR, - &info->port.tty->flags); - retval = 0; - } - goto out_unlocked; - } - - if (!(info->stat_flags & ESP_STAT_USE_PIO) && !dma_buffer) { - dma_buffer = (char *)__get_dma_pages( - GFP_KERNEL, get_order(DMA_BUFFER_SZ)); - - /* use PIO mode if DMA buf/chan cannot be allocated */ - if (!dma_buffer) - info->stat_flags |= ESP_STAT_USE_PIO; - else if (request_dma(dma, "esp serial")) { - free_pages((unsigned long)dma_buffer, - get_order(DMA_BUFFER_SZ)); - dma_buffer = NULL; - info->stat_flags |= ESP_STAT_USE_PIO; - } - - } - - info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; - - spin_lock_irqsave(&info->lock, flags); - serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); - serial_out(info, UART_ESI_CMD2, UART_MCR); - serial_out(info, UART_ESI_CMD2, info->MCR); - - /* - * Finally, enable interrupts - */ - /* info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; */ - info->IER = UART_IER_RLSI | UART_IER_RDI | UART_IER_DMA_TMOUT | - UART_IER_DMA_TC; - serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); - serial_out(info, UART_ESI_CMD2, info->IER); - - if (info->port.tty) - clear_bit(TTY_IO_ERROR, &info->port.tty->flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - spin_unlock_irqrestore(&info->lock, flags); - - /* - * Set up the tty->alt_speed kludge - */ - if (info->port.tty) { - if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->port.tty->alt_speed = 57600; - if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->port.tty->alt_speed = 115200; - if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->port.tty->alt_speed = 230400; - if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->port.tty->alt_speed = 460800; - } - - /* - * set the speed of the serial port - */ - change_speed(info); - info->port.flags |= ASYNC_INITIALIZED; - return 0; - -out: - spin_unlock_irqrestore(&info->lock, flags); -out_unlocked: - return retval; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(struct esp_struct *info) -{ - unsigned long flags, f; - - if (!(info->port.flags & ASYNC_INITIALIZED)) - return; - -#ifdef SERIAL_DEBUG_OPEN - printk("Shutting down serial port %d (irq %d)....", info->line, - info->irq); -#endif - - spin_lock_irqsave(&info->lock, flags); - /* - * clear delta_msr_wait queue to avoid mem leaks: we may free the irq - * here so the queue might never be waken up - */ - wake_up_interruptible(&info->port.delta_msr_wait); - wake_up_interruptible(&info->break_wait); - - /* stop a DMA transfer on the port being closed */ - /* DMA lock is higher priority always */ - if (info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) { - f = claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - release_dma_lock(f); - - dma_bytes = 0; - } - - /* - * Free the IRQ - */ - free_irq(info->irq, info); - - if (dma_buffer) { - struct esp_struct *current_port = ports; - - while (current_port) { - if ((current_port != info) && - (current_port->port.flags & ASYNC_INITIALIZED)) - break; - - current_port = current_port->next_port; - } - - if (!current_port) { - free_dma(dma); - free_pages((unsigned long)dma_buffer, - get_order(DMA_BUFFER_SZ)); - dma_buffer = NULL; - } - } - - if (info->xmit_buf) { - free_page((unsigned long) info->xmit_buf); - info->xmit_buf = NULL; - } - - info->IER = 0; - serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); - serial_out(info, UART_ESI_CMD2, 0x00); - - if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) - info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); - - info->MCR &= ~UART_MCR_OUT2; - serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); - serial_out(info, UART_ESI_CMD2, UART_MCR); - serial_out(info, UART_ESI_CMD2, info->MCR); - - if (info->port.tty) - set_bit(TTY_IO_ERROR, &info->port.tty->flags); - - info->port.flags &= ~ASYNC_INITIALIZED; - spin_unlock_irqrestore(&info->lock, flags); -} - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static void change_speed(struct esp_struct *info) -{ - unsigned short port; - int quot = 0; - unsigned cflag, cval; - int baud, bits; - unsigned char flow1 = 0, flow2 = 0; - unsigned long flags; - - if (!info->port.tty || !info->port.tty->termios) - return; - cflag = info->port.tty->termios->c_cflag; - port = info->io_port; - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: cval = 0x00; bits = 7; break; - case CS6: cval = 0x01; bits = 8; break; - case CS7: cval = 0x02; bits = 9; break; - case CS8: cval = 0x03; bits = 10; break; - default: cval = 0x00; bits = 7; break; - } - if (cflag & CSTOPB) { - cval |= 0x04; - bits++; - } - if (cflag & PARENB) { - cval |= UART_LCR_PARITY; - bits++; - } - if (!(cflag & PARODD)) - cval |= UART_LCR_EPAR; -#ifdef CMSPAR - if (cflag & CMSPAR) - cval |= UART_LCR_SPAR; -#endif - baud = tty_get_baud_rate(info->port.tty); - if (baud == 38400 && - ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) - quot = info->custom_divisor; - else { - if (baud == 134) /* Special case since 134 is really 134.5 */ - quot = (2*BASE_BAUD / 269); - else if (baud) - quot = BASE_BAUD / baud; - } - /* If the quotient is ever zero, default to 9600 bps */ - if (!quot) - quot = BASE_BAUD / 9600; - - if (baud) { - /* Actual rate */ - baud = BASE_BAUD/quot; - tty_encode_baud_rate(info->port.tty, baud, baud); - } - info->timeout = ((1024 * HZ * bits * quot) / BASE_BAUD) + (HZ / 50); - - /* CTS flow control flag and modem status interrupts */ - /* info->IER &= ~UART_IER_MSI; */ - if (cflag & CRTSCTS) { - info->port.flags |= ASYNC_CTS_FLOW; - /* info->IER |= UART_IER_MSI; */ - flow1 = 0x04; - flow2 = 0x10; - } else - info->port.flags &= ~ASYNC_CTS_FLOW; - if (cflag & CLOCAL) - info->port.flags &= ~ASYNC_CHECK_CD; - else - info->port.flags |= ASYNC_CHECK_CD; - - /* - * Set up parity check flag - */ - info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; - if (I_INPCK(info->port.tty)) - info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; - if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) - info->read_status_mask |= UART_LSR_BI; - - info->ignore_status_mask = 0; -#if 0 - /* This should be safe, but for some broken bits of hardware... */ - if (I_IGNPAR(info->port.tty)) { - info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; - info->read_status_mask |= UART_LSR_PE | UART_LSR_FE; - } -#endif - if (I_IGNBRK(info->port.tty)) { - info->ignore_status_mask |= UART_LSR_BI; - info->read_status_mask |= UART_LSR_BI; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->port.tty)) { - info->ignore_status_mask |= UART_LSR_OE | \ - UART_LSR_PE | UART_LSR_FE; - info->read_status_mask |= UART_LSR_OE | \ - UART_LSR_PE | UART_LSR_FE; - } - } - - if (I_IXOFF(info->port.tty)) - flow1 |= 0x81; - - spin_lock_irqsave(&info->lock, flags); - /* set baud */ - serial_out(info, UART_ESI_CMD1, ESI_SET_BAUD); - serial_out(info, UART_ESI_CMD2, quot >> 8); - serial_out(info, UART_ESI_CMD2, quot & 0xff); - - /* set data bits, parity, etc. */ - serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); - serial_out(info, UART_ESI_CMD2, UART_LCR); - serial_out(info, UART_ESI_CMD2, cval); - - /* Enable flow control */ - serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_CNTL); - serial_out(info, UART_ESI_CMD2, flow1); - serial_out(info, UART_ESI_CMD2, flow2); - - /* set flow control characters (XON/XOFF only) */ - if (I_IXOFF(info->port.tty)) { - serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_CHARS); - serial_out(info, UART_ESI_CMD2, START_CHAR(info->port.tty)); - serial_out(info, UART_ESI_CMD2, STOP_CHAR(info->port.tty)); - serial_out(info, UART_ESI_CMD2, 0x10); - serial_out(info, UART_ESI_CMD2, 0x21); - switch (cflag & CSIZE) { - case CS5: - serial_out(info, UART_ESI_CMD2, 0x1f); - break; - case CS6: - serial_out(info, UART_ESI_CMD2, 0x3f); - break; - case CS7: - case CS8: - serial_out(info, UART_ESI_CMD2, 0x7f); - break; - default: - serial_out(info, UART_ESI_CMD2, 0xff); - break; - } - } - - /* Set high/low water */ - serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_LVL); - serial_out(info, UART_ESI_CMD2, info->config.flow_off >> 8); - serial_out(info, UART_ESI_CMD2, info->config.flow_off); - serial_out(info, UART_ESI_CMD2, info->config.flow_on >> 8); - serial_out(info, UART_ESI_CMD2, info->config.flow_on); - - spin_unlock_irqrestore(&info->lock, flags); -} - -static int rs_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct esp_struct *info = tty->driver_data; - unsigned long flags; - int ret = 0; - - if (serial_paranoia_check(info, tty->name, "rs_put_char")) - return 0; - - if (!info->xmit_buf) - return 0; - - spin_lock_irqsave(&info->lock, flags); - if (info->xmit_cnt < ESP_XMIT_SIZE - 1) { - info->xmit_buf[info->xmit_head++] = ch; - info->xmit_head &= ESP_XMIT_SIZE-1; - info->xmit_cnt++; - ret = 1; - } - spin_unlock_irqrestore(&info->lock, flags); - return ret; -} - -static void rs_flush_chars(struct tty_struct *tty) -{ - struct esp_struct *info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_flush_chars")) - return; - - spin_lock_irqsave(&info->lock, flags); - - if (info->xmit_cnt <= 0 || tty->stopped || !info->xmit_buf) - goto out; - - if (!(info->IER & UART_IER_THRI)) { - info->IER |= UART_IER_THRI; - serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); - serial_out(info, UART_ESI_CMD2, info->IER); - } -out: - spin_unlock_irqrestore(&info->lock, flags); -} - -static int rs_write(struct tty_struct *tty, - const unsigned char *buf, int count) -{ - int c, t, ret = 0; - struct esp_struct *info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_write")) - return 0; - - if (!info->xmit_buf) - return 0; - - while (1) { - /* Thanks to R. Wolff for suggesting how to do this with */ - /* interrupts enabled */ - - c = count; - t = ESP_XMIT_SIZE - info->xmit_cnt - 1; - - if (t < c) - c = t; - - t = ESP_XMIT_SIZE - info->xmit_head; - - if (t < c) - c = t; - - if (c <= 0) - break; - - memcpy(info->xmit_buf + info->xmit_head, buf, c); - - info->xmit_head = (info->xmit_head + c) & (ESP_XMIT_SIZE-1); - info->xmit_cnt += c; - buf += c; - count -= c; - ret += c; - } - - spin_lock_irqsave(&info->lock, flags); - - if (info->xmit_cnt && !tty->stopped && !(info->IER & UART_IER_THRI)) { - info->IER |= UART_IER_THRI; - serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); - serial_out(info, UART_ESI_CMD2, info->IER); - } - - spin_unlock_irqrestore(&info->lock, flags); - return ret; -} - -static int rs_write_room(struct tty_struct *tty) -{ - struct esp_struct *info = tty->driver_data; - int ret; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_write_room")) - return 0; - - spin_lock_irqsave(&info->lock, flags); - - ret = ESP_XMIT_SIZE - info->xmit_cnt - 1; - if (ret < 0) - ret = 0; - spin_unlock_irqrestore(&info->lock, flags); - return ret; -} - -static int rs_chars_in_buffer(struct tty_struct *tty) -{ - struct esp_struct *info = tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) - return 0; - return info->xmit_cnt; -} - -static void rs_flush_buffer(struct tty_struct *tty) -{ - struct esp_struct *info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) - return; - spin_lock_irqsave(&info->lock, flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - spin_unlock_irqrestore(&info->lock, flags); - tty_wakeup(tty); -} - -/* - * ------------------------------------------------------------ - * rs_throttle() - * - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - * ------------------------------------------------------------ - */ -static void rs_throttle(struct tty_struct *tty) -{ - struct esp_struct *info = tty->driver_data; - unsigned long flags; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", tty_name(tty, buf), - tty_chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_throttle")) - return; - - spin_lock_irqsave(&info->lock, flags); - info->IER &= ~UART_IER_RDI; - serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); - serial_out(info, UART_ESI_CMD2, info->IER); - serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT); - serial_out(info, UART_ESI_CMD2, 0x00); - spin_unlock_irqrestore(&info->lock, flags); -} - -static void rs_unthrottle(struct tty_struct *tty) -{ - struct esp_struct *info = tty->driver_data; - unsigned long flags; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk(KERN_DEBUG "unthrottle %s: %d....\n", tty_name(tty, buf), - tty_chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) - return; - - spin_lock_irqsave(&info->lock, flags); - info->IER |= UART_IER_RDI; - serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); - serial_out(info, UART_ESI_CMD2, info->IER); - serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT); - serial_out(info, UART_ESI_CMD2, info->config.rx_timeout); - spin_unlock_irqrestore(&info->lock, flags); -} - -/* - * ------------------------------------------------------------ - * rs_ioctl() and friends - * ------------------------------------------------------------ - */ - -static int get_serial_info(struct esp_struct *info, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - - lock_kernel(); - memset(&tmp, 0, sizeof(tmp)); - tmp.type = PORT_16550A; - tmp.line = info->line; - tmp.port = info->io_port; - tmp.irq = info->irq; - tmp.flags = info->port.flags; - tmp.xmit_fifo_size = 1024; - tmp.baud_base = BASE_BAUD; - tmp.close_delay = info->close_delay; - tmp.closing_wait = info->closing_wait; - tmp.custom_divisor = info->custom_divisor; - tmp.hub6 = 0; - unlock_kernel(); - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int get_esp_config(struct esp_struct *info, - struct hayes_esp_config __user *retinfo) -{ - struct hayes_esp_config tmp; - - if (!retinfo) - return -EFAULT; - - memset(&tmp, 0, sizeof(tmp)); - lock_kernel(); - tmp.rx_timeout = info->config.rx_timeout; - tmp.rx_trigger = info->config.rx_trigger; - tmp.tx_trigger = info->config.tx_trigger; - tmp.flow_off = info->config.flow_off; - tmp.flow_on = info->config.flow_on; - tmp.pio_threshold = info->config.pio_threshold; - tmp.dma_channel = (info->stat_flags & ESP_STAT_NEVER_DMA ? 0 : dma); - unlock_kernel(); - - return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; -} - -static int set_serial_info(struct esp_struct *info, - struct serial_struct __user *new_info) -{ - struct serial_struct new_serial; - struct esp_struct old_info; - unsigned int change_irq; - int retval = 0; - struct esp_struct *current_async; - - if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) - return -EFAULT; - old_info = *info; - - if ((new_serial.type != PORT_16550A) || - (new_serial.hub6) || - (info->io_port != new_serial.port) || - (new_serial.baud_base != BASE_BAUD) || - (new_serial.irq > 15) || - (new_serial.irq < 2) || - (new_serial.irq == 6) || - (new_serial.irq == 8) || - (new_serial.irq == 13)) - return -EINVAL; - - change_irq = new_serial.irq != info->irq; - - if (change_irq && (info->line % 8)) - return -EINVAL; - - if (!capable(CAP_SYS_ADMIN)) { - if (change_irq || - (new_serial.close_delay != info->close_delay) || - ((new_serial.flags & ~ASYNC_USR_MASK) != - (info->port.flags & ~ASYNC_USR_MASK))) - return -EPERM; - info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - info->custom_divisor = new_serial.custom_divisor; - } else { - if (new_serial.irq == 2) - new_serial.irq = 9; - - if (change_irq) { - current_async = ports; - - while (current_async) { - if ((current_async->line >= info->line) && - (current_async->line < (info->line + 8))) { - if (current_async == info) { - if (current_async->port.count > 1) - return -EBUSY; - } else if (current_async->port.count) - return -EBUSY; - } - - current_async = current_async->next_port; - } - } - - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - - info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - info->custom_divisor = new_serial.custom_divisor; - info->close_delay = new_serial.close_delay * HZ/100; - info->closing_wait = new_serial.closing_wait * HZ/100; - - if (change_irq) { - /* - * We need to shutdown the serial port at the old - * port/irq combination. - */ - shutdown(info); - - current_async = ports; - - while (current_async) { - if ((current_async->line >= info->line) && - (current_async->line < (info->line + 8))) - current_async->irq = new_serial.irq; - - current_async = current_async->next_port; - } - - serial_out(info, UART_ESI_CMD1, ESI_SET_ENH_IRQ); - if (info->irq == 9) - serial_out(info, UART_ESI_CMD2, 0x02); - else - serial_out(info, UART_ESI_CMD2, info->irq); - } - } - - if (info->port.flags & ASYNC_INITIALIZED) { - if (((old_info.port.flags & ASYNC_SPD_MASK) != - (info->port.flags & ASYNC_SPD_MASK)) || - (old_info.custom_divisor != info->custom_divisor)) { - if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->port.tty->alt_speed = 57600; - if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->port.tty->alt_speed = 115200; - if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->port.tty->alt_speed = 230400; - if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->port.tty->alt_speed = 460800; - change_speed(info); - } - } else - retval = startup(info); - - return retval; -} - -static int set_esp_config(struct esp_struct *info, - struct hayes_esp_config __user *new_info) -{ - struct hayes_esp_config new_config; - unsigned int change_dma; - int retval = 0; - struct esp_struct *current_async; - unsigned long flags; - - /* Perhaps a non-sysadmin user should be able to do some of these */ - /* operations. I haven't decided yet. */ - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (copy_from_user(&new_config, new_info, sizeof(new_config))) - return -EFAULT; - - if ((new_config.flow_on >= new_config.flow_off) || - (new_config.rx_trigger < 1) || - (new_config.tx_trigger < 1) || - (new_config.flow_off < 1) || - (new_config.flow_on < 1) || - (new_config.rx_trigger > 1023) || - (new_config.tx_trigger > 1023) || - (new_config.flow_off > 1023) || - (new_config.flow_on > 1023) || - (new_config.pio_threshold < 0) || - (new_config.pio_threshold > 1024)) - return -EINVAL; - - if ((new_config.dma_channel != 1) && (new_config.dma_channel != 3)) - new_config.dma_channel = 0; - - if (info->stat_flags & ESP_STAT_NEVER_DMA) - change_dma = new_config.dma_channel; - else - change_dma = (new_config.dma_channel != dma); - - if (change_dma) { - if (new_config.dma_channel) { - /* PIO mode to DMA mode transition OR */ - /* change current DMA channel */ - current_async = ports; - - while (current_async) { - if (current_async == info) { - if (current_async->port.count > 1) - return -EBUSY; - } else if (current_async->port.count) - return -EBUSY; - - current_async = current_async->next_port; - } - - shutdown(info); - dma = new_config.dma_channel; - info->stat_flags &= ~ESP_STAT_NEVER_DMA; - - /* all ports must use the same DMA channel */ - - spin_lock_irqsave(&info->lock, flags); - current_async = ports; - - while (current_async) { - esp_basic_init(current_async); - current_async = current_async->next_port; - } - spin_unlock_irqrestore(&info->lock, flags); - } else { - /* DMA mode to PIO mode only */ - if (info->port.count > 1) - return -EBUSY; - - shutdown(info); - spin_lock_irqsave(&info->lock, flags); - info->stat_flags |= ESP_STAT_NEVER_DMA; - esp_basic_init(info); - spin_unlock_irqrestore(&info->lock, flags); - } - } - - info->config.pio_threshold = new_config.pio_threshold; - - if ((new_config.flow_off != info->config.flow_off) || - (new_config.flow_on != info->config.flow_on)) { - info->config.flow_off = new_config.flow_off; - info->config.flow_on = new_config.flow_on; - - spin_lock_irqsave(&info->lock, flags); - serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_LVL); - serial_out(info, UART_ESI_CMD2, new_config.flow_off >> 8); - serial_out(info, UART_ESI_CMD2, new_config.flow_off); - serial_out(info, UART_ESI_CMD2, new_config.flow_on >> 8); - serial_out(info, UART_ESI_CMD2, new_config.flow_on); - spin_unlock_irqrestore(&info->lock, flags); - } - - if ((new_config.rx_trigger != info->config.rx_trigger) || - (new_config.tx_trigger != info->config.tx_trigger)) { - info->config.rx_trigger = new_config.rx_trigger; - info->config.tx_trigger = new_config.tx_trigger; - spin_lock_irqsave(&info->lock, flags); - serial_out(info, UART_ESI_CMD1, ESI_SET_TRIGGER); - serial_out(info, UART_ESI_CMD2, - new_config.rx_trigger >> 8); - serial_out(info, UART_ESI_CMD2, new_config.rx_trigger); - serial_out(info, UART_ESI_CMD2, - new_config.tx_trigger >> 8); - serial_out(info, UART_ESI_CMD2, new_config.tx_trigger); - spin_unlock_irqrestore(&info->lock, flags); - } - - if (new_config.rx_timeout != info->config.rx_timeout) { - info->config.rx_timeout = new_config.rx_timeout; - spin_lock_irqsave(&info->lock, flags); - - if (info->IER & UART_IER_RDI) { - serial_out(info, UART_ESI_CMD1, - ESI_SET_RX_TIMEOUT); - serial_out(info, UART_ESI_CMD2, - new_config.rx_timeout); - } - - spin_unlock_irqrestore(&info->lock, flags); - } - - if (!(info->port.flags & ASYNC_INITIALIZED)) - retval = startup(info); - - return retval; -} - -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct esp_struct *info, unsigned int __user *value) -{ - unsigned char status; - unsigned int result; - unsigned long flags; - - spin_lock_irqsave(&info->lock, flags); - serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT); - status = serial_in(info, UART_ESI_STAT1); - spin_unlock_irqrestore(&info->lock, flags); - result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); - return put_user(result, value); -} - - -static int esp_tiocmget(struct tty_struct *tty, struct file *file) -{ - struct esp_struct *info = tty->driver_data; - unsigned char control, status; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, __func__)) - return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - control = info->MCR; - - spin_lock_irqsave(&info->lock, flags); - serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT); - status = serial_in(info, UART_ESI_STAT2); - spin_unlock_irqrestore(&info->lock, flags); - - return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) - | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) - | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) - | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) - | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) - | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); -} - -static int esp_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) -{ - struct esp_struct *info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, __func__)) - return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - spin_lock_irqsave(&info->lock, flags); - - if (set & TIOCM_RTS) - info->MCR |= UART_MCR_RTS; - if (set & TIOCM_DTR) - info->MCR |= UART_MCR_DTR; - - if (clear & TIOCM_RTS) - info->MCR &= ~UART_MCR_RTS; - if (clear & TIOCM_DTR) - info->MCR &= ~UART_MCR_DTR; - - serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); - serial_out(info, UART_ESI_CMD2, UART_MCR); - serial_out(info, UART_ESI_CMD2, info->MCR); - - spin_unlock_irqrestore(&info->lock, flags); - return 0; -} - -/* - * rs_break() --- routine which turns the break handling on or off - */ -static int esp_break(struct tty_struct *tty, int break_state) -{ - struct esp_struct *info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "esp_break")) - return -EINVAL; - - if (break_state == -1) { - spin_lock_irqsave(&info->lock, flags); - serial_out(info, UART_ESI_CMD1, ESI_ISSUE_BREAK); - serial_out(info, UART_ESI_CMD2, 0x01); - spin_unlock_irqrestore(&info->lock, flags); - - /* FIXME - new style wait needed here */ - interruptible_sleep_on(&info->break_wait); - } else { - spin_lock_irqsave(&info->lock, flags); - serial_out(info, UART_ESI_CMD1, ESI_ISSUE_BREAK); - serial_out(info, UART_ESI_CMD2, 0x00); - spin_unlock_irqrestore(&info->lock, flags); - } - return 0; -} - -static int rs_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct esp_struct *info = tty->driver_data; - struct async_icount cprev, cnow; /* kernel counter temps */ - struct serial_icounter_struct __user *p_cuser; /* user space */ - void __user *argp = (void __user *)arg; - unsigned long flags; - int ret; - - if (serial_paranoia_check(info, tty->name, "rs_ioctl")) - return -ENODEV; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && - (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT) && - (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT) && - (cmd != TIOCGHAYESESP) && (cmd != TIOCSHAYESESP)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(info, argp); - case TIOCSSERIAL: - lock_kernel(); - ret = set_serial_info(info, argp); - unlock_kernel(); - return ret; - case TIOCSERGWILD: - return put_user(0L, (unsigned long __user *)argp); - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, argp); - case TIOCSERSWILD: - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - return 0; - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - spin_lock_irqsave(&info->lock, flags); - cprev = info->icount; /* note the counters on entry */ - spin_unlock_irqrestore(&info->lock, flags); - while (1) { - /* FIXME: convert to new style wakeup */ - interruptible_sleep_on(&info->port.delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - spin_lock_irqsave(&info->lock, flags); - cnow = info->icount; /* atomic copy */ - spin_unlock_irqrestore(&info->lock, flags); - if (cnow.rng == cprev.rng && - cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && - cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if (((arg & TIOCM_RNG) && - (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && - (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && - (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && - (cnow.cts != cprev.cts))) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ - case TIOCGICOUNT: - spin_lock_irqsave(&info->lock, flags); - cnow = info->icount; - spin_unlock_irqrestore(&info->lock, flags); - p_cuser = argp; - if (put_user(cnow.cts, &p_cuser->cts) || - put_user(cnow.dsr, &p_cuser->dsr) || - put_user(cnow.rng, &p_cuser->rng) || - put_user(cnow.dcd, &p_cuser->dcd)) - return -EFAULT; - return 0; - case TIOCGHAYESESP: - return get_esp_config(info, argp); - case TIOCSHAYESESP: - lock_kernel(); - ret = set_esp_config(info, argp); - unlock_kernel(); - return ret; - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - struct esp_struct *info = tty->driver_data; - unsigned long flags; - - change_speed(info); - - spin_lock_irqsave(&info->lock, flags); - - /* Handle transition to B0 status */ - if ((old_termios->c_cflag & CBAUD) && - !(tty->termios->c_cflag & CBAUD)) { - info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); - serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); - serial_out(info, UART_ESI_CMD2, UART_MCR); - serial_out(info, UART_ESI_CMD2, info->MCR); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && - (tty->termios->c_cflag & CBAUD)) { - info->MCR |= (UART_MCR_DTR | UART_MCR_RTS); - serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); - serial_out(info, UART_ESI_CMD2, UART_MCR); - serial_out(info, UART_ESI_CMD2, info->MCR); - } - - spin_unlock_irqrestore(&info->lock, flags); - - /* Handle turning of CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - rs_start(tty); - } -} - -/* - * ------------------------------------------------------------ - * rs_close() - * - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * async structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - * ------------------------------------------------------------ - */ -static void rs_close(struct tty_struct *tty, struct file *filp) -{ - struct esp_struct *info = tty->driver_data; - unsigned long flags; - - if (!info || serial_paranoia_check(info, tty->name, "rs_close")) - return; - - spin_lock_irqsave(&info->lock, flags); - - if (tty_hung_up_p(filp)) { - DBG_CNT("before DEC-hung"); - goto out; - } - -#ifdef SERIAL_DEBUG_OPEN - printk(KERN_DEBUG "rs_close ttys%d, count = %d\n", - info->line, info->port.count); -#endif - if (tty->count == 1 && info->port.count != 1) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. Info->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk(KERN_DEBUG "rs_close: bad serial port count; tty->count is 1, info->port.count is %d\n", info->port.count); - info->port.count = 1; - } - if (--info->port.count < 0) { - printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n", - info->line, info->port.count); - info->port.count = 0; - } - if (info->port.count) { - DBG_CNT("before DEC-2"); - goto out; - } - info->port.flags |= ASYNC_CLOSING; - - spin_unlock_irqrestore(&info->lock, flags); - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - /* info->IER &= ~UART_IER_RLSI; */ - info->IER &= ~UART_IER_RDI; - info->read_status_mask &= ~UART_LSR_DR; - if (info->port.flags & ASYNC_INITIALIZED) { - - spin_lock_irqsave(&info->lock, flags); - serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); - serial_out(info, UART_ESI_CMD2, info->IER); - - /* disable receive timeout */ - serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT); - serial_out(info, UART_ESI_CMD2, 0x00); - - spin_unlock_irqrestore(&info->lock, flags); - - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - rs_wait_until_sent(tty, info->timeout); - } - shutdown(info); - rs_flush_buffer(tty); - tty_ldisc_flush(tty); - tty->closing = 0; - info->port.tty = NULL; - - if (info->port.blocked_open) { - if (info->close_delay) - msleep_interruptible(jiffies_to_msecs(info->close_delay)); - wake_up_interruptible(&info->port.open_wait); - } - info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&info->port.close_wait); - return; - -out: - spin_unlock_irqrestore(&info->lock, flags); -} - -static void rs_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct esp_struct *info = tty->driver_data; - unsigned long orig_jiffies, char_time; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) - return; - - orig_jiffies = jiffies; - char_time = ((info->timeout - HZ / 50) / 1024) / 5; - - if (!char_time) - char_time = 1; - - spin_lock_irqsave(&info->lock, flags); - serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); - serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL); - - while ((serial_in(info, UART_ESI_STAT1) != 0x03) || - (serial_in(info, UART_ESI_STAT2) != 0xff)) { - - spin_unlock_irqrestore(&info->lock, flags); - msleep_interruptible(jiffies_to_msecs(char_time)); - - if (signal_pending(current)) - return; - - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - return; - - spin_lock_irqsave(&info->lock, flags); - serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); - serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL); - } - spin_unlock_irqrestore(&info->lock, flags); - set_current_state(TASK_RUNNING); -} - -/* - * esp_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -static void esp_hangup(struct tty_struct *tty) -{ - struct esp_struct *info = tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "esp_hangup")) - return; - - rs_flush_buffer(tty); - shutdown(info); - info->port.count = 0; - info->port.flags &= ~ASYNC_NORMAL_ACTIVE; - info->port.tty = NULL; - wake_up_interruptible(&info->port.open_wait); -} - -static int esp_carrier_raised(struct tty_port *port) -{ - struct esp_struct *info = container_of(port, struct esp_struct, port); - serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT); - if (serial_in(info, UART_ESI_STAT2) & UART_MSR_DCD) - return 1; - return 0; -} - -/* - * ------------------------------------------------------------ - * esp_open() and friends - * ------------------------------------------------------------ - */ -static int block_til_ready(struct tty_struct *tty, struct file *filp, - struct esp_struct *info) -{ - DECLARE_WAITQUEUE(wait, current); - int retval; - int do_clocal = 0; - unsigned long flags; - int cd; - struct tty_port *port = &info->port; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || - (port->flags & ASYNC_CLOSING)) { - if (port->flags & ASYNC_CLOSING) - interruptible_sleep_on(&port->close_wait); -#ifdef SERIAL_DO_RESTART - if (port->flags & ASYNC_HUP_NOTIFY) - return -EAGAIN; - else - return -ERESTARTSYS; -#else - return -EAGAIN; -#endif - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - port->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, port->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&port->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - printk(KERN_DEBUG "block_til_ready before block: ttys%d, count = %d\n", - info->line, port->count); -#endif - spin_lock_irqsave(&info->lock, flags); - if (!tty_hung_up_p(filp)) - port->count--; - port->blocked_open++; - while (1) { - if ((tty->termios->c_cflag & CBAUD)) { - unsigned int scratch; - - serial_out(info, UART_ESI_CMD1, ESI_READ_UART); - serial_out(info, UART_ESI_CMD2, UART_MCR); - scratch = serial_in(info, UART_ESI_STAT1); - serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); - serial_out(info, UART_ESI_CMD2, UART_MCR); - serial_out(info, UART_ESI_CMD2, - scratch | UART_MCR_DTR | UART_MCR_RTS); - } - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(port->flags & ASYNC_INITIALIZED)) { -#ifdef SERIAL_DO_RESTART - if (port->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; -#else - retval = -EAGAIN; -#endif - break; - } - - cd = tty_port_carrier_raised(port); - - if (!(port->flags & ASYNC_CLOSING) && - (do_clocal)) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - printk(KERN_DEBUG "block_til_ready blocking: ttys%d, count = %d\n", - info->line, port->count); -#endif - spin_unlock_irqrestore(&info->lock, flags); - schedule(); - spin_lock_irqsave(&info->lock, flags); - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&port->open_wait, &wait); - if (!tty_hung_up_p(filp)) - port->count++; - port->blocked_open--; - spin_unlock_irqrestore(&info->lock, flags); -#ifdef SERIAL_DEBUG_OPEN - printk(KERN_DEBUG "block_til_ready after blocking: ttys%d, count = %d\n", - info->line, port->count); -#endif - if (retval) - return retval; - port->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} - -/* - * This routine is called whenever a serial port is opened. It - * enables interrupts for a serial port, linking in its async structure into - * the IRQ chain. It also performs the serial-specific - * initialization for the tty structure. - */ -static int esp_open(struct tty_struct *tty, struct file *filp) -{ - struct esp_struct *info; - int retval, line; - unsigned long flags; - - line = tty->index; - if ((line < 0) || (line >= NR_PORTS)) - return -ENODEV; - - /* find the port in the chain */ - - info = ports; - - while (info && (info->line != line)) - info = info->next_port; - - if (!info) { - serial_paranoia_check(info, tty->name, "esp_open"); - return -ENODEV; - } - -#ifdef SERIAL_DEBUG_OPEN - printk(KERN_DEBUG "esp_open %s, count = %d\n", tty->name, info->port.count); -#endif - spin_lock_irqsave(&info->lock, flags); - info->port.count++; - tty->driver_data = info; - info->port.tty = tty; - - spin_unlock_irqrestore(&info->lock, flags); - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) - return retval; - - retval = block_til_ready(tty, filp, info); - if (retval) { -#ifdef SERIAL_DEBUG_OPEN - printk(KERN_DEBUG "esp_open returning after block_til_ready with %d\n", - retval); -#endif - return retval; - } -#ifdef SERIAL_DEBUG_OPEN - printk(KERN_DEBUG "esp_open %s successful...", tty->name); -#endif - return 0; -} - -/* - * --------------------------------------------------------------------- - * espserial_init() and friends - * - * espserial_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ - -static void __init show_serial_version(void) -{ - printk(KERN_INFO "%s version %s (DMA %u)\n", - serial_name, serial_version, dma); -} - -/* - * This routine is called by espserial_init() to initialize a specific serial - * port. - */ -static int autoconfig(struct esp_struct *info) -{ - int port_detected = 0; - unsigned long flags; - - if (!request_region(info->io_port, REGION_SIZE, "esp serial")) - return -EIO; - - spin_lock_irqsave(&info->lock, flags); - /* - * Check for ESP card - */ - - if (serial_in(info, UART_ESI_BASE) == 0xf3) { - serial_out(info, UART_ESI_CMD1, 0x00); - serial_out(info, UART_ESI_CMD1, 0x01); - - if ((serial_in(info, UART_ESI_STAT2) & 0x70) == 0x20) { - port_detected = 1; - - if (!(info->irq)) { - serial_out(info, UART_ESI_CMD1, 0x02); - - if (serial_in(info, UART_ESI_STAT1) & 0x01) - info->irq = 3; - else - info->irq = 4; - } - - - /* put card in enhanced mode */ - /* this prevents access through */ - /* the "old" IO ports */ - esp_basic_init(info); - - /* clear out MCR */ - serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); - serial_out(info, UART_ESI_CMD2, UART_MCR); - serial_out(info, UART_ESI_CMD2, 0x00); - } - } - if (!port_detected) - release_region(info->io_port, REGION_SIZE); - - spin_unlock_irqrestore(&info->lock, flags); - return (port_detected); -} - -static const struct tty_operations esp_ops = { - .open = esp_open, - .close = rs_close, - .write = rs_write, - .put_char = rs_put_char, - .flush_chars = rs_flush_chars, - .write_room = rs_write_room, - .chars_in_buffer = rs_chars_in_buffer, - .flush_buffer = rs_flush_buffer, - .ioctl = rs_ioctl, - .throttle = rs_throttle, - .unthrottle = rs_unthrottle, - .set_termios = rs_set_termios, - .stop = rs_stop, - .start = rs_start, - .hangup = esp_hangup, - .break_ctl = esp_break, - .wait_until_sent = rs_wait_until_sent, - .tiocmget = esp_tiocmget, - .tiocmset = esp_tiocmset, -}; - -static const struct tty_port_operations esp_port_ops = { - .esp_carrier_raised, -}; - -/* - * The serial driver boot-time initialization code! - */ -static int __init espserial_init(void) -{ - int i, offset; - struct esp_struct *info; - struct esp_struct *last_primary = NULL; - int esp[] = { 0x100, 0x140, 0x180, 0x200, 0x240, 0x280, 0x300, 0x380 }; - - esp_driver = alloc_tty_driver(NR_PORTS); - if (!esp_driver) - return -ENOMEM; - - for (i = 0; i < NR_PRIMARY; i++) { - if (irq[i] != 0) { - if ((irq[i] < 2) || (irq[i] > 15) || (irq[i] == 6) || - (irq[i] == 8) || (irq[i] == 13)) - irq[i] = 0; - else if (irq[i] == 2) - irq[i] = 9; - } - } - - if ((dma != 1) && (dma != 3)) - dma = 0; - - if ((rx_trigger < 1) || (rx_trigger > 1023)) - rx_trigger = 768; - - if ((tx_trigger < 1) || (tx_trigger > 1023)) - tx_trigger = 768; - - if ((flow_off < 1) || (flow_off > 1023)) - flow_off = 1016; - - if ((flow_on < 1) || (flow_on > 1023)) - flow_on = 944; - - if ((rx_timeout < 0) || (rx_timeout > 255)) - rx_timeout = 128; - - if (flow_on >= flow_off) - flow_on = flow_off - 1; - - show_serial_version(); - - /* Initialize the tty_driver structure */ - - esp_driver->owner = THIS_MODULE; - esp_driver->name = "ttyP"; - esp_driver->major = ESP_IN_MAJOR; - esp_driver->minor_start = 0; - esp_driver->type = TTY_DRIVER_TYPE_SERIAL; - esp_driver->subtype = SERIAL_TYPE_NORMAL; - esp_driver->init_termios = tty_std_termios; - esp_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - esp_driver->init_termios.c_ispeed = 9600; - esp_driver->init_termios.c_ospeed = 9600; - esp_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(esp_driver, &esp_ops); - if (tty_register_driver(esp_driver)) { - printk(KERN_ERR "Couldn't register esp serial driver"); - put_tty_driver(esp_driver); - return 1; - } - - info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL); - - if (!info) { - printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n"); - tty_unregister_driver(esp_driver); - put_tty_driver(esp_driver); - return 1; - } - - spin_lock_init(&info->lock); - /* rx_trigger, tx_trigger are needed by autoconfig */ - info->config.rx_trigger = rx_trigger; - info->config.tx_trigger = tx_trigger; - - i = 0; - offset = 0; - - do { - tty_port_init(&info->port); - info->port.ops = &esp_port_ops; - info->io_port = esp[i] + offset; - info->irq = irq[i]; - info->line = (i * 8) + (offset / 8); - - if (!autoconfig(info)) { - i++; - offset = 0; - continue; - } - - info->custom_divisor = (divisor[i] >> (offset / 2)) & 0xf; - info->port.flags = STD_COM_FLAGS; - if (info->custom_divisor) - info->port.flags |= ASYNC_SPD_CUST; - info->magic = ESP_MAGIC; - info->close_delay = 5*HZ/10; - info->closing_wait = 30*HZ; - info->config.rx_timeout = rx_timeout; - info->config.flow_on = flow_on; - info->config.flow_off = flow_off; - info->config.pio_threshold = pio_threshold; - info->next_port = ports; - init_waitqueue_head(&info->break_wait); - ports = info; - printk(KERN_INFO "ttyP%d at 0x%04x (irq = %d) is an ESP ", - info->line, info->io_port, info->irq); - - if (info->line % 8) { - printk("secondary port\n"); - /* 8 port cards can't do DMA */ - info->stat_flags |= ESP_STAT_NEVER_DMA; - - if (last_primary) - last_primary->stat_flags |= ESP_STAT_NEVER_DMA; - } else { - printk("primary port\n"); - last_primary = info; - irq[i] = info->irq; - } - - if (!dma) - info->stat_flags |= ESP_STAT_NEVER_DMA; - - info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL); - if (!info) { - printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n"); - /* allow use of the already detected ports */ - return 0; - } - - spin_lock_init(&info->lock); - /* rx_trigger, tx_trigger are needed by autoconfig */ - info->config.rx_trigger = rx_trigger; - info->config.tx_trigger = tx_trigger; - - if (offset == 56) { - i++; - offset = 0; - } else { - offset += 8; - } - } while (i < NR_PRIMARY); - - /* free the last port memory allocation */ - kfree(info); - - return 0; -} - -static void __exit espserial_exit(void) -{ - int e1; - struct esp_struct *temp_async; - struct esp_pio_buffer *pio_buf; - - e1 = tty_unregister_driver(esp_driver); - if (e1) - printk(KERN_ERR "esp: failed to unregister driver (%d)\n", e1); - put_tty_driver(esp_driver); - - while (ports) { - if (ports->io_port) - release_region(ports->io_port, REGION_SIZE); - temp_async = ports->next_port; - kfree(ports); - ports = temp_async; - } - - if (dma_buffer) - free_pages((unsigned long)dma_buffer, - get_order(DMA_BUFFER_SZ)); - - while (free_pio_buf) { - pio_buf = free_pio_buf->next; - kfree(free_pio_buf); - free_pio_buf = pio_buf; - } -} - -module_init(espserial_init); -module_exit(espserial_exit); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/char/istallion.c linux-2.6.32-rc6-staging/drivers/char/istallion.c --- linux-2.6.32-rc6/drivers/char/istallion.c 2009-11-04 15:20:15.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/char/istallion.c 2009-11-06 20:57:19.000000000 -0800 @@ -621,7 +621,7 @@ static int stli_startbrd(struct stlibrd *brdp); static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp); static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp); -static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); +static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg); static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); static void stli_poll(unsigned long arg); static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); @@ -704,7 +704,7 @@ .owner = THIS_MODULE, .read = stli_memread, .write = stli_memwrite, - .ioctl = stli_memioctl, + .unlocked_ioctl = stli_memioctl, }; /*****************************************************************************/ @@ -4311,7 +4311,7 @@ * reset it, and start/stop it. */ -static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) +static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) { struct stlibrd *brdp; int brdnr, rc, done; @@ -4356,7 +4356,7 @@ * Now handle the board specific ioctls. These all depend on the * minor number of the device they were called from. */ - brdnr = iminor(ip); + brdnr = iminor(fp->f_dentry->d_inode); if (brdnr >= STL_MAXBRDS) return -ENODEV; brdp = stli_brds[brdnr]; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/char/Kconfig linux-2.6.32-rc6-staging/drivers/char/Kconfig --- linux-2.6.32-rc6/drivers/char/Kconfig 2009-11-04 15:20:15.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/char/Kconfig 2009-11-06 20:57:19.000000000 -0800 @@ -201,19 +201,6 @@ To compile this driver as a module, choose M here: the module will be called epca. -config ESPSERIAL - tristate "Hayes ESP serial port support" - depends on SERIAL_NONSTANDARD && ISA && ISA_DMA_API && BROKEN - help - This is a driver which supports Hayes ESP serial ports. Both single - port cards and multiport cards are supported. Make sure to read - . - - To compile this driver as a module, choose M here: the - module will be called esp. - - If unsure, say N. - config MOXA_INTELLIO tristate "Moxa Intellio support" depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/char/Makefile linux-2.6.32-rc6-staging/drivers/char/Makefile --- linux-2.6.32-rc6/drivers/char/Makefile 2009-11-04 15:20:15.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/char/Makefile 2009-11-06 20:57:19.000000000 -0800 @@ -18,7 +18,6 @@ obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o obj-$(CONFIG_AUDIT) += tty_audit.o obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o -obj-$(CONFIG_ESPSERIAL) += esp.o obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/char/pcmcia/ipwireless/tty.c linux-2.6.32-rc6-staging/drivers/char/pcmcia/ipwireless/tty.c --- linux-2.6.32-rc6/drivers/char/pcmcia/ipwireless/tty.c 2009-10-05 16:45:08.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/char/pcmcia/ipwireless/tty.c 2009-11-06 20:57:19.000000000 -0800 @@ -603,7 +603,7 @@ } } -static struct tty_operations tty_ops = { +static const struct tty_operations tty_ops = { .open = ipw_open, .close = ipw_close, .hangup = ipw_hangup, diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/char/stallion.c linux-2.6.32-rc6-staging/drivers/char/stallion.c --- linux-2.6.32-rc6/drivers/char/stallion.c 2009-11-04 15:20:16.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/char/stallion.c 2009-11-06 20:57:19.000000000 -0800 @@ -407,7 +407,7 @@ * Declare all those functions in this driver! */ -static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); +static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg); static int stl_brdinit(struct stlbrd *brdp); static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); @@ -607,7 +607,7 @@ */ static const struct file_operations stl_fsiomem = { .owner = THIS_MODULE, - .ioctl = stl_memioctl, + .unlocked_ioctl = stl_memioctl, }; static struct class *stallion_class; @@ -2486,18 +2486,19 @@ * collection. */ -static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) +static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) { int brdnr, rc; void __user *argp = (void __user *)arg; - pr_debug("stl_memioctl(ip=%p,fp=%p,cmd=%x,arg=%lx)\n", ip, fp, cmd,arg); + pr_debug("stl_memioctl(fp=%p,cmd=%x,arg=%lx)\n", fp, cmd,arg); - brdnr = iminor(ip); + brdnr = iminor(fp->f_dentry->d_inode); if (brdnr >= STL_MAXBRDS) return -ENODEV; rc = 0; + lock_kernel(); switch (cmd) { case COM_GETPORTSTATS: rc = stl_getportstats(NULL, NULL, argp); @@ -2518,7 +2519,7 @@ rc = -ENOIOCTLCMD; break; } - + unlock_kernel(); return rc; } diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/char/tty_port.c linux-2.6.32-rc6-staging/drivers/char/tty_port.c --- linux-2.6.32-rc6/drivers/char/tty_port.c 2009-11-04 15:20:16.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/char/tty_port.c 2009-11-06 20:57:19.000000000 -0800 @@ -99,10 +99,11 @@ static void tty_port_shutdown(struct tty_port *port) { + mutex_lock(&port->mutex); if (port->ops->shutdown && test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) port->ops->shutdown(port); - + mutex_unlock(&port->mutex); } /** @@ -198,7 +199,7 @@ * management of these lines. Note that the dtr/rts raise is done each * iteration as a hangup may have previously dropped them while we wait. */ - + int tty_port_block_til_ready(struct tty_port *port, struct tty_struct *tty, struct file *filp) { @@ -221,6 +222,9 @@ the port has just hung up or is in another error state */ if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) { + /* Indicate we are open */ + if (tty->termios->c_cflag & CBAUD) + tty_port_raise_dtr_rts(port); port->flags |= ASYNC_NORMAL_ACTIVE; return 0; } @@ -247,7 +251,8 @@ tty_port_raise_dtr_rts(port); prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); - /* Check for a hangup or uninitialised port. Return accordingly */ + /* Check for a hangup or uninitialised port. + Return accordingly */ if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { if (port->flags & ASYNC_HUP_NOTIFY) retval = -EAGAIN; @@ -279,11 +284,11 @@ port->flags |= ASYNC_NORMAL_ACTIVE; spin_unlock_irqrestore(&port->lock, flags); return retval; - } EXPORT_SYMBOL(tty_port_block_til_ready); -int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp) +int tty_port_close_start(struct tty_port *port, + struct tty_struct *tty, struct file *filp) { unsigned long flags; @@ -293,7 +298,7 @@ return 0; } - if( tty->count == 1 && port->count != 1) { + if (tty->count == 1 && port->count != 1) { printk(KERN_WARNING "tty_port_close_start: tty->count = 1 port count = %d.\n", port->count); @@ -325,8 +330,8 @@ long timeout; if (bps > 1200) - timeout = max_t(long, (HZ * 10 * port->drain_delay) / bps, - HZ / 10); + timeout = max_t(long, + (HZ * 10 * port->drain_delay) / bps, HZ / 10); else timeout = 2 * HZ; schedule_timeout_interruptible(timeout); @@ -375,3 +380,36 @@ tty_port_tty_set(port, NULL); } EXPORT_SYMBOL(tty_port_close); + +int tty_port_open(struct tty_port *port, struct tty_struct *tty, + struct file *filp) +{ + spin_lock_irq(&port->lock); + if (!tty_hung_up_p(filp)) + ++port->count; + spin_unlock_irq(&port->lock); + tty_port_tty_set(port, tty); + + /* + * Do the device-specific open only if the hardware isn't + * already initialized. Serialize open and shutdown using the + * port mutex. + */ + + mutex_lock(&port->mutex); + + if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) { + if (port->ops->activate) { + int retval = port->ops->activate(port, tty); + if (retval) { + mutex_unlock(&port->mutex); + return retval; + } + } + set_bit(ASYNCB_INITIALIZED, &port->flags); + } + mutex_unlock(&port->mutex); + return tty_port_block_til_ready(port, tty, filp); +} + +EXPORT_SYMBOL(tty_port_open); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/firmware/dell_rbu.c linux-2.6.32-rc6-staging/drivers/firmware/dell_rbu.c --- linux-2.6.32-rc6/drivers/firmware/dell_rbu.c 2009-03-23 16:12:14.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/firmware/dell_rbu.c 2009-11-06 20:57:04.000000000 -0800 @@ -544,9 +544,12 @@ { rbu_data.entry_created = 0; - if (!fw || !fw->size) + if (!fw) return; + if (!fw->size) + goto out; + spin_lock(&rbu_data.lock); if (!strcmp(image_type, "mono")) { if (!img_update_realloc(fw->size)) @@ -568,6 +571,8 @@ } else pr_debug("invalid image type specified.\n"); spin_unlock(&rbu_data.lock); + out: + release_firmware(fw); } static ssize_t read_rbu_image_type(struct kobject *kobj, @@ -615,7 +620,7 @@ spin_unlock(&rbu_data.lock); req_firm_rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, "dell_rbu", - &rbu_device->dev, &context, + &rbu_device->dev, GFP_KERNEL, &context, callbackfn_rbu); if (req_firm_rc) { printk(KERN_ERR diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/misc/hpilo.h linux-2.6.32-rc6-staging/drivers/misc/hpilo.h --- linux-2.6.32-rc6/drivers/misc/hpilo.h 2009-11-04 15:20:22.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/misc/hpilo.h 2009-11-06 20:57:04.000000000 -0800 @@ -44,9 +44,20 @@ struct pci_dev *ilo_dev; + /* + * open_lock serializes ccb_cnt during open and close + * [ irq disabled ] + * -> alloc_lock used when adding/removing/searching ccb_alloc, + * which represents all ccbs open on the device + * --> fifo_lock controls access to fifo queues shared with hw + * + * Locks must be taken in this order, but open_lock and alloc_lock + * are optional, they do not need to be held in order to take a + * lower level lock. + */ + spinlock_t open_lock; spinlock_t alloc_lock; spinlock_t fifo_lock; - spinlock_t open_lock; struct cdev cdev; }; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/serial/8250.c linux-2.6.32-rc6-staging/drivers/serial/8250.c --- linux-2.6.32-rc6/drivers/serial/8250.c 2009-11-04 15:20:31.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/serial/8250.c 2009-11-06 20:57:19.000000000 -0800 @@ -2646,7 +2646,7 @@ { struct uart_8250_port *up; static int first = 1; - int i; + int i, irqflag = 0; if (!first) return; @@ -2670,6 +2670,9 @@ up->port.ops = &serial8250_pops; } + if (share_irqs) + irqflag = IRQF_SHARED; + for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; i++, up++) { @@ -2683,8 +2686,7 @@ up->port.iotype = old_serial_port[i].io_type; up->port.regshift = old_serial_port[i].iomem_reg_shift; set_io_from_upio(&up->port); - if (share_irqs) - up->port.irqflags |= IRQF_SHARED; + up->port.irqflags |= irqflag; } } @@ -2940,10 +2942,13 @@ { struct plat_serial8250_port *p = dev->dev.platform_data; struct uart_port port; - int ret, i; + int ret, i, irqflag = 0; memset(&port, 0, sizeof(struct uart_port)); + if (share_irqs) + irqflag = IRQF_SHARED; + for (i = 0; p && p->flags != 0; p++, i++) { port.iobase = p->iobase; port.membase = p->membase; @@ -2960,8 +2965,7 @@ port.serial_in = p->serial_in; port.serial_out = p->serial_out; port.dev = &dev->dev; - if (share_irqs) - port.irqflags |= IRQF_SHARED; + port.irqflags |= irqflag; ret = serial8250_register_port(&port); if (ret < 0) { dev_err(&dev->dev, "unable to register port at index %d " diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/serial/jsm/jsm_driver.c linux-2.6.32-rc6-staging/drivers/serial/jsm/jsm_driver.c --- linux-2.6.32-rc6/drivers/serial/jsm/jsm_driver.c 2009-10-05 16:43:55.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/serial/jsm/jsm_driver.c 2009-11-06 20:57:19.000000000 -0800 @@ -48,6 +48,17 @@ .nr = NR_PORTS, }; +static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state); +static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev); +static void jsm_io_resume(struct pci_dev *pdev); + +static struct pci_error_handlers jsm_err_handler = { + .error_detected = jsm_io_error_detected, + .slot_reset = jsm_io_slot_reset, + .resume = jsm_io_resume, +}; + int jsm_debug; module_param(jsm_debug, int, 0); MODULE_PARM_DESC(jsm_debug, "Driver debugging level"); @@ -123,7 +134,7 @@ } rc = request_irq(brd->irq, brd->bd_ops->intr, - IRQF_DISABLED|IRQF_SHARED, "JSM", brd); + IRQF_SHARED, "JSM", brd); if (rc) { printk(KERN_WARNING "Failed to hook IRQ %d\n",brd->irq); goto out_iounmap; @@ -164,6 +175,7 @@ } pci_set_drvdata(pdev, brd); + pci_save_state(pdev); return 0; out_free_irq: @@ -222,8 +234,42 @@ .id_table = jsm_pci_tbl, .probe = jsm_probe_one, .remove = __devexit_p(jsm_remove_one), + .err_handler = &jsm_err_handler, }; +static pci_ers_result_t jsm_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct jsm_board *brd = pci_get_drvdata(pdev); + + jsm_remove_uart_port(brd); + + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t jsm_io_slot_reset(struct pci_dev *pdev) +{ + int rc; + + rc = pci_enable_device(pdev); + + if (rc) + return PCI_ERS_RESULT_DISCONNECT; + + pci_set_master(pdev); + + return PCI_ERS_RESULT_RECOVERED; +} + +static void jsm_io_resume(struct pci_dev *pdev) +{ + struct jsm_board *brd = pci_get_drvdata(pdev); + + pci_restore_state(pdev); + + jsm_uart_port_init(brd); +} + static int __init jsm_init_module(void) { int rc; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/serial/jsm/jsm.h linux-2.6.32-rc6-staging/drivers/serial/jsm/jsm.h --- linux-2.6.32-rc6/drivers/serial/jsm/jsm.h 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/serial/jsm/jsm.h 2009-11-06 20:57:19.000000000 -0800 @@ -138,7 +138,6 @@ u32 nasync; /* Number of ports on card */ u32 irq; /* Interrupt request number */ - u64 intr_count; /* Count of interrupts */ u64 membase; /* Start of base memory of the card */ u64 membase_end; /* End of base memory of the card */ @@ -206,8 +205,6 @@ u64 ch_close_delay; /* How long we should drop RTS/DTR for */ - u64 ch_cpstime; /* Time for CPS calculations */ - tcflag_t ch_c_iflag; /* channel iflags */ tcflag_t ch_c_cflag; /* channel cflags */ tcflag_t ch_c_oflag; /* channel oflags */ @@ -215,11 +212,6 @@ u8 ch_stopc; /* Stop character */ u8 ch_startc; /* Start character */ - u32 ch_old_baud; /* Cache of the current baud */ - u32 ch_custom_speed;/* Custom baud, if set */ - - u32 ch_wopen; /* Waiting for open process cnt */ - u8 ch_mostat; /* FEP output modem status */ u8 ch_mistat; /* FEP input modem status */ diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/serial/jsm/jsm_neo.c linux-2.6.32-rc6-staging/drivers/serial/jsm/jsm_neo.c --- linux-2.6.32-rc6/drivers/serial/jsm/jsm_neo.c 2009-11-04 15:20:32.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/serial/jsm/jsm_neo.c 2009-11-06 20:57:19.000000000 -0800 @@ -954,13 +954,8 @@ ch->ch_flags |= (CH_BAUD0); ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR); neo_assert_modem_signals(ch); - ch->ch_old_baud = 0; return; - } else if (ch->ch_custom_speed) { - baud = ch->ch_custom_speed; - if (ch->ch_flags & CH_BAUD0) - ch->ch_flags &= ~(CH_BAUD0); } else { int i; unsigned int cflag; @@ -1045,7 +1040,6 @@ quot = ch->ch_bd->bd_dividend / baud; if (quot != 0) { - ch->ch_old_baud = baud; writeb(UART_LCR_DLAB, &ch->ch_neo_uart->lcr); writeb((quot & 0xff), &ch->ch_neo_uart->txrx); writeb((quot >> 8), &ch->ch_neo_uart->ier); @@ -1123,8 +1117,6 @@ unsigned long lock_flags2; int outofloop_count = 0; - brd->intr_count++; - /* Lock out the slow poller from running on this board. */ spin_lock_irqsave(&brd->bd_intr_lock, lock_flags); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/serial/jsm/jsm_tty.c linux-2.6.32-rc6-staging/drivers/serial/jsm/jsm_tty.c --- linux-2.6.32-rc6/drivers/serial/jsm/jsm_tty.c 2009-11-04 15:20:32.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/serial/jsm/jsm_tty.c 2009-11-06 20:57:19.000000000 -0800 @@ -296,8 +296,6 @@ bd->bd_ops->assert_modem_signals(channel); } - channel->ch_old_baud = 0; - /* Turn off UART interrupts for this port */ channel->ch_bd->bd_ops->uart_off(channel); @@ -432,7 +430,7 @@ return 0; } -int __devinit jsm_uart_port_init(struct jsm_board *brd) +int jsm_uart_port_init(struct jsm_board *brd) { int i; unsigned int line; @@ -472,7 +470,7 @@ if (uart_add_one_port (&jsm_uart_driver, &brd->channels[i]->uart_port)) printk(KERN_INFO "jsm: add device failed\n"); else - printk(KERN_INFO "Added device \n"); + printk(KERN_INFO "jsm: Port %d added\n", i); } jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n"); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/serial/pxa.c linux-2.6.32-rc6-staging/drivers/serial/pxa.c --- linux-2.6.32-rc6/drivers/serial/pxa.c 2009-11-04 15:20:32.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/serial/pxa.c 2009-11-06 20:57:19.000000000 -0800 @@ -438,6 +438,7 @@ unsigned char cval, fcr = 0; unsigned long flags; unsigned int baud, quot; + unsigned int dll; switch (termios->c_cflag & CSIZE) { case CS5: @@ -534,10 +535,18 @@ else up->mcr &= ~UART_MCR_AFE; - serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ + serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */ serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ + + /* + * work around Errata #75 according to Intel(R) PXA27x Processor Family + * Specification Update (Nov 2005) + */ + dll = serial_in(up, UART_DLL); + WARN_ON(dll != (quot & 0xff)); + serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ - serial_out(up, UART_LCR, cval); /* reset DLAB */ + serial_out(up, UART_LCR, cval); /* reset DLAB */ up->lcr = cval; /* Save LCR */ serial_pxa_set_mctrl(&up->port, up->port.mctrl); serial_out(up, UART_FCR, fcr); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/serial/serial_core.c linux-2.6.32-rc6-staging/drivers/serial/serial_core.c --- linux-2.6.32-rc6/drivers/serial/serial_core.c 2009-11-04 15:20:32.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/serial/serial_core.c 2009-11-06 20:57:19.000000000 -0800 @@ -342,11 +342,11 @@ if (flags == UPF_SPD_HI) altbaud = 57600; - if (flags == UPF_SPD_VHI) + else if (flags == UPF_SPD_VHI) altbaud = 115200; - if (flags == UPF_SPD_SHI) + else if (flags == UPF_SPD_SHI) altbaud = 230400; - if (flags == UPF_SPD_WARP) + else if (flags == UPF_SPD_WARP) altbaud = 460800; for (try = 0; try < 2; try++) { @@ -1217,9 +1217,8 @@ /* Handle transition to B0 status */ if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) uart_clear_mctrl(state->uart_port, TIOCM_RTS | TIOCM_DTR); - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { + else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { unsigned int mask = TIOCM_DTR; if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags)) @@ -1234,9 +1233,8 @@ __uart_start(tty); spin_unlock_irqrestore(&state->uart_port->lock, flags); } - /* Handle turning on CRTSCTS */ - if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { + else if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { spin_lock_irqsave(&state->uart_port->lock, flags); if (!(state->uart_port->ops->get_mctrl(state->uart_port) & TIOCM_CTS)) { tty->hw_stopped = 1; @@ -2344,7 +2342,7 @@ */ int uart_register_driver(struct uart_driver *drv) { - struct tty_driver *normal = NULL; + struct tty_driver *normal; int i, retval; BUG_ON(drv->state); @@ -2354,13 +2352,12 @@ * we have a large number of ports to handle. */ drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL); - retval = -ENOMEM; if (!drv->state) goto out; - normal = alloc_tty_driver(drv->nr); + normal = alloc_tty_driver(drv->nr); if (!normal) - goto out; + goto out_kfree; drv->tty_driver = normal; @@ -2393,12 +2390,14 @@ } retval = tty_register_driver(normal); - out: - if (retval < 0) { - put_tty_driver(normal); - kfree(drv->state); - } - return retval; + if (retval >= 0) + return retval; + + put_tty_driver(normal); +out_kfree: + kfree(drv->state); +out: + return -ENOMEM; } /** diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/serial/ucc_uart.c linux-2.6.32-rc6-staging/drivers/serial/ucc_uart.c --- linux-2.6.32-rc6/drivers/serial/ucc_uart.c 2009-11-04 15:20:32.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/serial/ucc_uart.c 2009-11-06 20:57:04.000000000 -0800 @@ -1179,16 +1179,18 @@ if (firmware->header.length != fw->size) { dev_err(dev, "invalid firmware\n"); - return; + goto out; } ret = qe_upload_firmware(firmware); if (ret) { dev_err(dev, "could not load firmware\n"); - return; + goto out; } firmware_loaded = 1; + out: + release_firmware(fw); } static int ucc_uart_probe(struct of_device *ofdev, @@ -1247,7 +1249,7 @@ */ ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, filename, &ofdev->dev, - &ofdev->dev, uart_firmware_cont); + GFP_KERNEL, &ofdev->dev, uart_firmware_cont); if (ret) { dev_err(&ofdev->dev, "could not load firmware %s\n", diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/android/binder.c linux-2.6.32-rc6-staging/drivers/staging/android/binder.c --- linux-2.6.32-rc6/drivers/staging/android/binder.c 2009-11-04 15:20:32.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/android/binder.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,3767 +0,0 @@ -/* binder.c - * - * Android IPC Subsystem - * - * Copyright (C) 2007-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "binder.h" - -static DEFINE_MUTEX(binder_lock); -static DEFINE_MUTEX(binder_deferred_lock); - -static HLIST_HEAD(binder_procs); -static HLIST_HEAD(binder_deferred_list); -static HLIST_HEAD(binder_dead_nodes); - -static struct proc_dir_entry *binder_proc_dir_entry_root; -static struct proc_dir_entry *binder_proc_dir_entry_proc; -static struct binder_node *binder_context_mgr_node; -static uid_t binder_context_mgr_uid = -1; -static int binder_last_id; - -static int binder_read_proc_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); - -/* This is only defined in include/asm-arm/sizes.h */ -#ifndef SZ_1K -#define SZ_1K 0x400 -#endif - -#ifndef SZ_4M -#define SZ_4M 0x400000 -#endif - -#define FORBIDDEN_MMAP_FLAGS (VM_WRITE) - -#define BINDER_SMALL_BUF_SIZE (PAGE_SIZE * 64) - -enum { - BINDER_DEBUG_USER_ERROR = 1U << 0, - BINDER_DEBUG_FAILED_TRANSACTION = 1U << 1, - BINDER_DEBUG_DEAD_TRANSACTION = 1U << 2, - BINDER_DEBUG_OPEN_CLOSE = 1U << 3, - BINDER_DEBUG_DEAD_BINDER = 1U << 4, - BINDER_DEBUG_DEATH_NOTIFICATION = 1U << 5, - BINDER_DEBUG_READ_WRITE = 1U << 6, - BINDER_DEBUG_USER_REFS = 1U << 7, - BINDER_DEBUG_THREADS = 1U << 8, - BINDER_DEBUG_TRANSACTION = 1U << 9, - BINDER_DEBUG_TRANSACTION_COMPLETE = 1U << 10, - BINDER_DEBUG_FREE_BUFFER = 1U << 11, - BINDER_DEBUG_INTERNAL_REFS = 1U << 12, - BINDER_DEBUG_BUFFER_ALLOC = 1U << 13, - BINDER_DEBUG_PRIORITY_CAP = 1U << 14, - BINDER_DEBUG_BUFFER_ALLOC_ASYNC = 1U << 15, -}; -static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR | - BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION; -module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO); - -static int binder_debug_no_lock; -module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO); - -static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait); -static int binder_stop_on_user_error; - -static int binder_set_stop_on_user_error(const char *val, - struct kernel_param *kp) -{ - int ret; - ret = param_set_int(val, kp); - if (binder_stop_on_user_error < 2) - wake_up(&binder_user_error_wait); - return ret; -} -module_param_call(stop_on_user_error, binder_set_stop_on_user_error, - param_get_int, &binder_stop_on_user_error, S_IWUSR | S_IRUGO); - -#define binder_debug(mask, x...) \ - do { \ - if (binder_debug_mask & mask) \ - printk(KERN_INFO x); \ - } while (0) - -#define binder_user_error(x...) \ - do { \ - if (binder_debug_mask & BINDER_DEBUG_USER_ERROR) \ - printk(KERN_INFO x); \ - if (binder_stop_on_user_error) \ - binder_stop_on_user_error = 2; \ - } while (0) - -enum binder_stat_types { - BINDER_STAT_PROC, - BINDER_STAT_THREAD, - BINDER_STAT_NODE, - BINDER_STAT_REF, - BINDER_STAT_DEATH, - BINDER_STAT_TRANSACTION, - BINDER_STAT_TRANSACTION_COMPLETE, - BINDER_STAT_COUNT -}; - -struct binder_stats { - int br[_IOC_NR(BR_FAILED_REPLY) + 1]; - int bc[_IOC_NR(BC_DEAD_BINDER_DONE) + 1]; - int obj_created[BINDER_STAT_COUNT]; - int obj_deleted[BINDER_STAT_COUNT]; -}; - -static struct binder_stats binder_stats; - -static inline void binder_stats_deleted(enum binder_stat_types type) -{ - binder_stats.obj_deleted[type]++; -} - -static inline void binder_stats_created(enum binder_stat_types type) -{ - binder_stats.obj_created[type]++; -} - -struct binder_transaction_log_entry { - int debug_id; - int call_type; - int from_proc; - int from_thread; - int target_handle; - int to_proc; - int to_thread; - int to_node; - int data_size; - int offsets_size; -}; -struct binder_transaction_log { - int next; - int full; - struct binder_transaction_log_entry entry[32]; -}; -static struct binder_transaction_log binder_transaction_log; -static struct binder_transaction_log binder_transaction_log_failed; - -static struct binder_transaction_log_entry *binder_transaction_log_add( - struct binder_transaction_log *log) -{ - struct binder_transaction_log_entry *e; - e = &log->entry[log->next]; - memset(e, 0, sizeof(*e)); - log->next++; - if (log->next == ARRAY_SIZE(log->entry)) { - log->next = 0; - log->full = 1; - } - return e; -} - -struct binder_work { - struct list_head entry; - enum { - BINDER_WORK_TRANSACTION = 1, - BINDER_WORK_TRANSACTION_COMPLETE, - BINDER_WORK_NODE, - BINDER_WORK_DEAD_BINDER, - BINDER_WORK_DEAD_BINDER_AND_CLEAR, - BINDER_WORK_CLEAR_DEATH_NOTIFICATION, - } type; -}; - -struct binder_node { - int debug_id; - struct binder_work work; - union { - struct rb_node rb_node; - struct hlist_node dead_node; - }; - struct binder_proc *proc; - struct hlist_head refs; - int internal_strong_refs; - int local_weak_refs; - int local_strong_refs; - void __user *ptr; - void __user *cookie; - unsigned has_strong_ref:1; - unsigned pending_strong_ref:1; - unsigned has_weak_ref:1; - unsigned pending_weak_ref:1; - unsigned has_async_transaction:1; - unsigned accept_fds:1; - unsigned min_priority:8; - struct list_head async_todo; -}; - -struct binder_ref_death { - struct binder_work work; - void __user *cookie; -}; - -struct binder_ref { - /* Lookups needed: */ - /* node + proc => ref (transaction) */ - /* desc + proc => ref (transaction, inc/dec ref) */ - /* node => refs + procs (proc exit) */ - int debug_id; - struct rb_node rb_node_desc; - struct rb_node rb_node_node; - struct hlist_node node_entry; - struct binder_proc *proc; - struct binder_node *node; - uint32_t desc; - int strong; - int weak; - struct binder_ref_death *death; -}; - -struct binder_buffer { - struct list_head entry; /* free and allocated entries by addesss */ - struct rb_node rb_node; /* free entry by size or allocated entry */ - /* by address */ - unsigned free:1; - unsigned allow_user_free:1; - unsigned async_transaction:1; - unsigned debug_id:29; - - struct binder_transaction *transaction; - - struct binder_node *target_node; - size_t data_size; - size_t offsets_size; - uint8_t data[0]; -}; - -enum binder_deferred_state { - BINDER_DEFERRED_PUT_FILES = 0x01, - BINDER_DEFERRED_FLUSH = 0x02, - BINDER_DEFERRED_RELEASE = 0x04, -}; - -struct binder_proc { - struct hlist_node proc_node; - struct rb_root threads; - struct rb_root nodes; - struct rb_root refs_by_desc; - struct rb_root refs_by_node; - int pid; - struct vm_area_struct *vma; - struct task_struct *tsk; - struct files_struct *files; - struct hlist_node deferred_work_node; - int deferred_work; - void *buffer; - ptrdiff_t user_buffer_offset; - - struct list_head buffers; - struct rb_root free_buffers; - struct rb_root allocated_buffers; - size_t free_async_space; - - struct page **pages; - size_t buffer_size; - uint32_t buffer_free; - struct list_head todo; - wait_queue_head_t wait; - struct binder_stats stats; - struct list_head delivered_death; - int max_threads; - int requested_threads; - int requested_threads_started; - int ready_threads; - long default_priority; -}; - -enum { - BINDER_LOOPER_STATE_REGISTERED = 0x01, - BINDER_LOOPER_STATE_ENTERED = 0x02, - BINDER_LOOPER_STATE_EXITED = 0x04, - BINDER_LOOPER_STATE_INVALID = 0x08, - BINDER_LOOPER_STATE_WAITING = 0x10, - BINDER_LOOPER_STATE_NEED_RETURN = 0x20 -}; - -struct binder_thread { - struct binder_proc *proc; - struct rb_node rb_node; - int pid; - int looper; - struct binder_transaction *transaction_stack; - struct list_head todo; - uint32_t return_error; /* Write failed, return error code in read buf */ - uint32_t return_error2; /* Write failed, return error code in read */ - /* buffer. Used when sending a reply to a dead process that */ - /* we are also waiting on */ - wait_queue_head_t wait; - struct binder_stats stats; -}; - -struct binder_transaction { - int debug_id; - struct binder_work work; - struct binder_thread *from; - struct binder_transaction *from_parent; - struct binder_proc *to_proc; - struct binder_thread *to_thread; - struct binder_transaction *to_parent; - unsigned need_reply:1; - /* unsigned is_dead:1; */ /* not used at the moment */ - - struct binder_buffer *buffer; - unsigned int code; - unsigned int flags; - long priority; - long saved_priority; - uid_t sender_euid; -}; - -static void -binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer); - -/* - * copied from get_unused_fd_flags - */ -int task_get_unused_fd_flags(struct binder_proc *proc, int flags) -{ - struct files_struct *files = proc->files; - int fd, error; - struct fdtable *fdt; - unsigned long rlim_cur; - unsigned long irqs; - - if (files == NULL) - return -ESRCH; - - error = -EMFILE; - spin_lock(&files->file_lock); - -repeat: - fdt = files_fdtable(files); - fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds, - files->next_fd); - - /* - * N.B. For clone tasks sharing a files structure, this test - * will limit the total number of files that can be opened. - */ - rlim_cur = 0; - if (lock_task_sighand(proc->tsk, &irqs)) { - rlim_cur = proc->tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur; - unlock_task_sighand(proc->tsk, &irqs); - } - if (fd >= rlim_cur) - goto out; - - /* Do we need to expand the fd array or fd set? */ - error = expand_files(files, fd); - if (error < 0) - goto out; - - if (error) { - /* - * If we needed to expand the fs array we - * might have blocked - try again. - */ - error = -EMFILE; - goto repeat; - } - - FD_SET(fd, fdt->open_fds); - if (flags & O_CLOEXEC) - FD_SET(fd, fdt->close_on_exec); - else - FD_CLR(fd, fdt->close_on_exec); - files->next_fd = fd + 1; -#if 1 - /* Sanity check */ - if (fdt->fd[fd] != NULL) { - printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); - fdt->fd[fd] = NULL; - } -#endif - error = fd; - -out: - spin_unlock(&files->file_lock); - return error; -} - -/* - * copied from fd_install - */ -static void task_fd_install( - struct binder_proc *proc, unsigned int fd, struct file *file) -{ - struct files_struct *files = proc->files; - struct fdtable *fdt; - - if (files == NULL) - return; - - spin_lock(&files->file_lock); - fdt = files_fdtable(files); - BUG_ON(fdt->fd[fd] != NULL); - rcu_assign_pointer(fdt->fd[fd], file); - spin_unlock(&files->file_lock); -} - -/* - * copied from __put_unused_fd in open.c - */ -static void __put_unused_fd(struct files_struct *files, unsigned int fd) -{ - struct fdtable *fdt = files_fdtable(files); - __FD_CLR(fd, fdt->open_fds); - if (fd < files->next_fd) - files->next_fd = fd; -} - -/* - * copied from sys_close - */ -static long task_close_fd(struct binder_proc *proc, unsigned int fd) -{ - struct file *filp; - struct files_struct *files = proc->files; - struct fdtable *fdt; - int retval; - - if (files == NULL) - return -ESRCH; - - spin_lock(&files->file_lock); - fdt = files_fdtable(files); - if (fd >= fdt->max_fds) - goto out_unlock; - filp = fdt->fd[fd]; - if (!filp) - goto out_unlock; - rcu_assign_pointer(fdt->fd[fd], NULL); - FD_CLR(fd, fdt->close_on_exec); - __put_unused_fd(files, fd); - spin_unlock(&files->file_lock); - retval = filp_close(filp, files); - - /* can't restart close syscall because file table entry was cleared */ - if (unlikely(retval == -ERESTARTSYS || - retval == -ERESTARTNOINTR || - retval == -ERESTARTNOHAND || - retval == -ERESTART_RESTARTBLOCK)) - retval = -EINTR; - - return retval; - -out_unlock: - spin_unlock(&files->file_lock); - return -EBADF; -} - -static void binder_set_nice(long nice) -{ - long min_nice; - if (can_nice(current, nice)) { - set_user_nice(current, nice); - return; - } - min_nice = 20 - current->signal->rlim[RLIMIT_NICE].rlim_cur; - binder_debug(BINDER_DEBUG_PRIORITY_CAP, - "binder: %d: nice value %ld not allowed use " - "%ld instead\n", current->pid, nice, min_nice); - set_user_nice(current, min_nice); - if (min_nice < 20) - return; - binder_user_error("binder: %d RLIMIT_NICE not set\n", current->pid); -} - -static size_t binder_buffer_size(struct binder_proc *proc, - struct binder_buffer *buffer) -{ - if (list_is_last(&buffer->entry, &proc->buffers)) - return proc->buffer + proc->buffer_size - (void *)buffer->data; - else - return (size_t)list_entry(buffer->entry.next, - struct binder_buffer, entry) - (size_t)buffer->data; -} - -static void binder_insert_free_buffer(struct binder_proc *proc, - struct binder_buffer *new_buffer) -{ - struct rb_node **p = &proc->free_buffers.rb_node; - struct rb_node *parent = NULL; - struct binder_buffer *buffer; - size_t buffer_size; - size_t new_buffer_size; - - BUG_ON(!new_buffer->free); - - new_buffer_size = binder_buffer_size(proc, new_buffer); - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: add free buffer, size %zd, " - "at %p\n", proc->pid, new_buffer_size, new_buffer); - - while (*p) { - parent = *p; - buffer = rb_entry(parent, struct binder_buffer, rb_node); - BUG_ON(!buffer->free); - - buffer_size = binder_buffer_size(proc, buffer); - - if (new_buffer_size < buffer_size) - p = &parent->rb_left; - else - p = &parent->rb_right; - } - rb_link_node(&new_buffer->rb_node, parent, p); - rb_insert_color(&new_buffer->rb_node, &proc->free_buffers); -} - -static void binder_insert_allocated_buffer(struct binder_proc *proc, - struct binder_buffer *new_buffer) -{ - struct rb_node **p = &proc->allocated_buffers.rb_node; - struct rb_node *parent = NULL; - struct binder_buffer *buffer; - - BUG_ON(new_buffer->free); - - while (*p) { - parent = *p; - buffer = rb_entry(parent, struct binder_buffer, rb_node); - BUG_ON(buffer->free); - - if (new_buffer < buffer) - p = &parent->rb_left; - else if (new_buffer > buffer) - p = &parent->rb_right; - else - BUG(); - } - rb_link_node(&new_buffer->rb_node, parent, p); - rb_insert_color(&new_buffer->rb_node, &proc->allocated_buffers); -} - -static struct binder_buffer *binder_buffer_lookup(struct binder_proc *proc, - void __user *user_ptr) -{ - struct rb_node *n = proc->allocated_buffers.rb_node; - struct binder_buffer *buffer; - struct binder_buffer *kern_ptr; - - kern_ptr = user_ptr - proc->user_buffer_offset - - offsetof(struct binder_buffer, data); - - while (n) { - buffer = rb_entry(n, struct binder_buffer, rb_node); - BUG_ON(buffer->free); - - if (kern_ptr < buffer) - n = n->rb_left; - else if (kern_ptr > buffer) - n = n->rb_right; - else - return buffer; - } - return NULL; -} - -static int binder_update_page_range(struct binder_proc *proc, int allocate, - void *start, void *end, - struct vm_area_struct *vma) -{ - void *page_addr; - unsigned long user_page_addr; - struct vm_struct tmp_area; - struct page **page; - struct mm_struct *mm; - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: %s pages %p-%p\n", proc->pid, - allocate ? "allocate" : "free", start, end); - - if (end <= start) - return 0; - - if (vma) - mm = NULL; - else - mm = get_task_mm(proc->tsk); - - if (mm) { - down_write(&mm->mmap_sem); - vma = proc->vma; - } - - if (allocate == 0) - goto free_range; - - if (vma == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed to " - "map pages in userspace, no vma\n", proc->pid); - goto err_no_vma; - } - - for (page_addr = start; page_addr < end; page_addr += PAGE_SIZE) { - int ret; - struct page **page_array_ptr; - page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; - - BUG_ON(*page); - *page = alloc_page(GFP_KERNEL | __GFP_ZERO); - if (*page == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed " - "for page at %p\n", proc->pid, page_addr); - goto err_alloc_page_failed; - } - tmp_area.addr = page_addr; - tmp_area.size = PAGE_SIZE + PAGE_SIZE /* guard page? */; - page_array_ptr = page; - ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr); - if (ret) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed " - "to map page at %p in kernel\n", - proc->pid, page_addr); - goto err_map_kernel_failed; - } - user_page_addr = - (uintptr_t)page_addr + proc->user_buffer_offset; - ret = vm_insert_page(vma, user_page_addr, page[0]); - if (ret) { - printk(KERN_ERR "binder: %d: binder_alloc_buf failed " - "to map page at %lx in userspace\n", - proc->pid, user_page_addr); - goto err_vm_insert_page_failed; - } - /* vm_insert_page does not seem to increment the refcount */ - } - if (mm) { - up_write(&mm->mmap_sem); - mmput(mm); - } - return 0; - -free_range: - for (page_addr = end - PAGE_SIZE; page_addr >= start; - page_addr -= PAGE_SIZE) { - page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; - if (vma) - zap_page_range(vma, (uintptr_t)page_addr + - proc->user_buffer_offset, PAGE_SIZE, NULL); -err_vm_insert_page_failed: - unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE); -err_map_kernel_failed: - __free_page(*page); - *page = NULL; -err_alloc_page_failed: - ; - } -err_no_vma: - if (mm) { - up_write(&mm->mmap_sem); - mmput(mm); - } - return -ENOMEM; -} - -static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, - size_t data_size, - size_t offsets_size, int is_async) -{ - struct rb_node *n = proc->free_buffers.rb_node; - struct binder_buffer *buffer; - size_t buffer_size; - struct rb_node *best_fit = NULL; - void *has_page_addr; - void *end_page_addr; - size_t size; - - if (proc->vma == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf, no vma\n", - proc->pid); - return NULL; - } - - size = ALIGN(data_size, sizeof(void *)) + - ALIGN(offsets_size, sizeof(void *)); - - if (size < data_size || size < offsets_size) { - binder_user_error("binder: %d: got transaction with invalid " - "size %zd-%zd\n", proc->pid, data_size, offsets_size); - return NULL; - } - - if (is_async && - proc->free_async_space < size + sizeof(struct binder_buffer)) { - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_alloc_buf size %zd" - "failed, no async space left\n", proc->pid, size); - return NULL; - } - - while (n) { - buffer = rb_entry(n, struct binder_buffer, rb_node); - BUG_ON(!buffer->free); - buffer_size = binder_buffer_size(proc, buffer); - - if (size < buffer_size) { - best_fit = n; - n = n->rb_left; - } else if (size > buffer_size) - n = n->rb_right; - else { - best_fit = n; - break; - } - } - if (best_fit == NULL) { - printk(KERN_ERR "binder: %d: binder_alloc_buf size %zd failed, " - "no address space\n", proc->pid, size); - return NULL; - } - if (n == NULL) { - buffer = rb_entry(best_fit, struct binder_buffer, rb_node); - buffer_size = binder_buffer_size(proc, buffer); - } - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_alloc_buf size %zd got buff" - "er %p size %zd\n", proc->pid, size, buffer, buffer_size); - - has_page_addr = - (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK); - if (n == NULL) { - if (size + sizeof(struct binder_buffer) + 4 >= buffer_size) - buffer_size = size; /* no room for other buffers */ - else - buffer_size = size + sizeof(struct binder_buffer); - } - end_page_addr = - (void *)PAGE_ALIGN((uintptr_t)buffer->data + buffer_size); - if (end_page_addr > has_page_addr) - end_page_addr = has_page_addr; - if (binder_update_page_range(proc, 1, - (void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL)) - return NULL; - - rb_erase(best_fit, &proc->free_buffers); - buffer->free = 0; - binder_insert_allocated_buffer(proc, buffer); - if (buffer_size != size) { - struct binder_buffer *new_buffer = (void *)buffer->data + size; - list_add(&new_buffer->entry, &buffer->entry); - new_buffer->free = 1; - binder_insert_free_buffer(proc, new_buffer); - } - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_alloc_buf size %zd got " - "%p\n", proc->pid, size, buffer); - buffer->data_size = data_size; - buffer->offsets_size = offsets_size; - buffer->async_transaction = is_async; - if (is_async) { - proc->free_async_space -= size + sizeof(struct binder_buffer); - binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, - "binder: %d: binder_alloc_buf size %zd " - "async free %zd\n", proc->pid, size, - proc->free_async_space); - } - - return buffer; -} - -static void *buffer_start_page(struct binder_buffer *buffer) -{ - return (void *)((uintptr_t)buffer & PAGE_MASK); -} - -static void *buffer_end_page(struct binder_buffer *buffer) -{ - return (void *)(((uintptr_t)(buffer + 1) - 1) & PAGE_MASK); -} - -static void binder_delete_free_buffer(struct binder_proc *proc, - struct binder_buffer *buffer) -{ - struct binder_buffer *prev, *next = NULL; - int free_page_end = 1; - int free_page_start = 1; - - BUG_ON(proc->buffers.next == &buffer->entry); - prev = list_entry(buffer->entry.prev, struct binder_buffer, entry); - BUG_ON(!prev->free); - if (buffer_end_page(prev) == buffer_start_page(buffer)) { - free_page_start = 0; - if (buffer_end_page(prev) == buffer_end_page(buffer)) - free_page_end = 0; - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: merge free, buffer %p " - "share page with %p\n", proc->pid, buffer, prev); - } - - if (!list_is_last(&buffer->entry, &proc->buffers)) { - next = list_entry(buffer->entry.next, - struct binder_buffer, entry); - if (buffer_start_page(next) == buffer_end_page(buffer)) { - free_page_end = 0; - if (buffer_start_page(next) == - buffer_start_page(buffer)) - free_page_start = 0; - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: merge free, buffer" - " %p share page with %p\n", proc->pid, - buffer, prev); - } - } - list_del(&buffer->entry); - if (free_page_start || free_page_end) { - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: merge free, buffer %p do " - "not share page%s%s with with %p or %p\n", - proc->pid, buffer, free_page_start ? "" : " end", - free_page_end ? "" : " start", prev, next); - binder_update_page_range(proc, 0, free_page_start ? - buffer_start_page(buffer) : buffer_end_page(buffer), - (free_page_end ? buffer_end_page(buffer) : - buffer_start_page(buffer)) + PAGE_SIZE, NULL); - } -} - -static void binder_free_buf(struct binder_proc *proc, - struct binder_buffer *buffer) -{ - size_t size, buffer_size; - - buffer_size = binder_buffer_size(proc, buffer); - - size = ALIGN(buffer->data_size, sizeof(void *)) + - ALIGN(buffer->offsets_size, sizeof(void *)); - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_free_buf %p size %zd buffer" - "_size %zd\n", proc->pid, buffer, size, buffer_size); - - BUG_ON(buffer->free); - BUG_ON(size > buffer_size); - BUG_ON(buffer->transaction != NULL); - BUG_ON((void *)buffer < proc->buffer); - BUG_ON((void *)buffer > proc->buffer + proc->buffer_size); - - if (buffer->async_transaction) { - proc->free_async_space += size + sizeof(struct binder_buffer); - - binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, - "binder: %d: binder_free_buf size %zd " - "async free %zd\n", proc->pid, size, - proc->free_async_space); - } - - binder_update_page_range(proc, 0, - (void *)PAGE_ALIGN((uintptr_t)buffer->data), - (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK), - NULL); - rb_erase(&buffer->rb_node, &proc->allocated_buffers); - buffer->free = 1; - if (!list_is_last(&buffer->entry, &proc->buffers)) { - struct binder_buffer *next = list_entry(buffer->entry.next, - struct binder_buffer, entry); - if (next->free) { - rb_erase(&next->rb_node, &proc->free_buffers); - binder_delete_free_buffer(proc, next); - } - } - if (proc->buffers.next != &buffer->entry) { - struct binder_buffer *prev = list_entry(buffer->entry.prev, - struct binder_buffer, entry); - if (prev->free) { - binder_delete_free_buffer(proc, buffer); - rb_erase(&prev->rb_node, &proc->free_buffers); - buffer = prev; - } - } - binder_insert_free_buffer(proc, buffer); -} - -static struct binder_node *binder_get_node(struct binder_proc *proc, - void __user *ptr) -{ - struct rb_node *n = proc->nodes.rb_node; - struct binder_node *node; - - while (n) { - node = rb_entry(n, struct binder_node, rb_node); - - if (ptr < node->ptr) - n = n->rb_left; - else if (ptr > node->ptr) - n = n->rb_right; - else - return node; - } - return NULL; -} - -static struct binder_node *binder_new_node(struct binder_proc *proc, - void __user *ptr, - void __user *cookie) -{ - struct rb_node **p = &proc->nodes.rb_node; - struct rb_node *parent = NULL; - struct binder_node *node; - - while (*p) { - parent = *p; - node = rb_entry(parent, struct binder_node, rb_node); - - if (ptr < node->ptr) - p = &(*p)->rb_left; - else if (ptr > node->ptr) - p = &(*p)->rb_right; - else - return NULL; - } - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (node == NULL) - return NULL; - binder_stats_created(BINDER_STAT_NODE); - rb_link_node(&node->rb_node, parent, p); - rb_insert_color(&node->rb_node, &proc->nodes); - node->debug_id = ++binder_last_id; - node->proc = proc; - node->ptr = ptr; - node->cookie = cookie; - node->work.type = BINDER_WORK_NODE; - INIT_LIST_HEAD(&node->work.entry); - INIT_LIST_HEAD(&node->async_todo); - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d:%d node %d u%p c%p created\n", - proc->pid, current->pid, node->debug_id, - node->ptr, node->cookie); - return node; -} - -static int binder_inc_node(struct binder_node *node, int strong, int internal, - struct list_head *target_list) -{ - if (strong) { - if (internal) { - if (target_list == NULL && - node->internal_strong_refs == 0 && - !(node == binder_context_mgr_node && - node->has_strong_ref)) { - printk(KERN_ERR "binder: invalid inc strong " - "node for %d\n", node->debug_id); - return -EINVAL; - } - node->internal_strong_refs++; - } else - node->local_strong_refs++; - if (!node->has_strong_ref && target_list) { - list_del_init(&node->work.entry); - list_add_tail(&node->work.entry, target_list); - } - } else { - if (!internal) - node->local_weak_refs++; - if (!node->has_weak_ref && list_empty(&node->work.entry)) { - if (target_list == NULL) { - printk(KERN_ERR "binder: invalid inc weak node " - "for %d\n", node->debug_id); - return -EINVAL; - } - list_add_tail(&node->work.entry, target_list); - } - } - return 0; -} - -static int binder_dec_node(struct binder_node *node, int strong, int internal) -{ - if (strong) { - if (internal) - node->internal_strong_refs--; - else - node->local_strong_refs--; - if (node->local_strong_refs || node->internal_strong_refs) - return 0; - } else { - if (!internal) - node->local_weak_refs--; - if (node->local_weak_refs || !hlist_empty(&node->refs)) - return 0; - } - if (node->proc && (node->has_strong_ref || node->has_weak_ref)) { - if (list_empty(&node->work.entry)) { - list_add_tail(&node->work.entry, &node->proc->todo); - wake_up_interruptible(&node->proc->wait); - } - } else { - if (hlist_empty(&node->refs) && !node->local_strong_refs && - !node->local_weak_refs) { - list_del_init(&node->work.entry); - if (node->proc) { - rb_erase(&node->rb_node, &node->proc->nodes); - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: refless node %d deleted\n", - node->debug_id); - } else { - hlist_del(&node->dead_node); - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: dead node %d deleted\n", - node->debug_id); - } - kfree(node); - binder_stats_deleted(BINDER_STAT_NODE); - } - } - - return 0; -} - - -static struct binder_ref *binder_get_ref(struct binder_proc *proc, - uint32_t desc) -{ - struct rb_node *n = proc->refs_by_desc.rb_node; - struct binder_ref *ref; - - while (n) { - ref = rb_entry(n, struct binder_ref, rb_node_desc); - - if (desc < ref->desc) - n = n->rb_left; - else if (desc > ref->desc) - n = n->rb_right; - else - return ref; - } - return NULL; -} - -static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, - struct binder_node *node) -{ - struct rb_node *n; - struct rb_node **p = &proc->refs_by_node.rb_node; - struct rb_node *parent = NULL; - struct binder_ref *ref, *new_ref; - - while (*p) { - parent = *p; - ref = rb_entry(parent, struct binder_ref, rb_node_node); - - if (node < ref->node) - p = &(*p)->rb_left; - else if (node > ref->node) - p = &(*p)->rb_right; - else - return ref; - } - new_ref = kzalloc(sizeof(*ref), GFP_KERNEL); - if (new_ref == NULL) - return NULL; - binder_stats_created(BINDER_STAT_REF); - new_ref->debug_id = ++binder_last_id; - new_ref->proc = proc; - new_ref->node = node; - rb_link_node(&new_ref->rb_node_node, parent, p); - rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node); - - new_ref->desc = (node == binder_context_mgr_node) ? 0 : 1; - for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { - ref = rb_entry(n, struct binder_ref, rb_node_desc); - if (ref->desc > new_ref->desc) - break; - new_ref->desc = ref->desc + 1; - } - - p = &proc->refs_by_desc.rb_node; - while (*p) { - parent = *p; - ref = rb_entry(parent, struct binder_ref, rb_node_desc); - - if (new_ref->desc < ref->desc) - p = &(*p)->rb_left; - else if (new_ref->desc > ref->desc) - p = &(*p)->rb_right; - else - BUG(); - } - rb_link_node(&new_ref->rb_node_desc, parent, p); - rb_insert_color(&new_ref->rb_node_desc, &proc->refs_by_desc); - if (node) { - hlist_add_head(&new_ref->node_entry, &node->refs); - - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d new ref %d desc %d for " - "node %d\n", proc->pid, new_ref->debug_id, - new_ref->desc, node->debug_id); - } else { - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d new ref %d desc %d for " - "dead node\n", proc->pid, new_ref->debug_id, - new_ref->desc); - } - return new_ref; -} - -static void binder_delete_ref(struct binder_ref *ref) -{ - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d delete ref %d desc %d for " - "node %d\n", ref->proc->pid, ref->debug_id, - ref->desc, ref->node->debug_id); - - rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc); - rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node); - if (ref->strong) - binder_dec_node(ref->node, 1, 1); - hlist_del(&ref->node_entry); - binder_dec_node(ref->node, 0, 1); - if (ref->death) { - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: %d delete ref %d desc %d " - "has death notification\n", ref->proc->pid, - ref->debug_id, ref->desc); - list_del(&ref->death->work.entry); - kfree(ref->death); - binder_stats_deleted(BINDER_STAT_DEATH); - } - kfree(ref); - binder_stats_deleted(BINDER_STAT_REF); -} - -static int binder_inc_ref(struct binder_ref *ref, int strong, - struct list_head *target_list) -{ - int ret; - if (strong) { - if (ref->strong == 0) { - ret = binder_inc_node(ref->node, 1, 1, target_list); - if (ret) - return ret; - } - ref->strong++; - } else { - if (ref->weak == 0) { - ret = binder_inc_node(ref->node, 0, 1, target_list); - if (ret) - return ret; - } - ref->weak++; - } - return 0; -} - - -static int binder_dec_ref(struct binder_ref *ref, int strong) -{ - if (strong) { - if (ref->strong == 0) { - binder_user_error("binder: %d invalid dec strong, " - "ref %d desc %d s %d w %d\n", - ref->proc->pid, ref->debug_id, - ref->desc, ref->strong, ref->weak); - return -EINVAL; - } - ref->strong--; - if (ref->strong == 0) { - int ret; - ret = binder_dec_node(ref->node, strong, 1); - if (ret) - return ret; - } - } else { - if (ref->weak == 0) { - binder_user_error("binder: %d invalid dec weak, " - "ref %d desc %d s %d w %d\n", - ref->proc->pid, ref->debug_id, - ref->desc, ref->strong, ref->weak); - return -EINVAL; - } - ref->weak--; - } - if (ref->strong == 0 && ref->weak == 0) - binder_delete_ref(ref); - return 0; -} - -static void binder_pop_transaction(struct binder_thread *target_thread, - struct binder_transaction *t) -{ - if (target_thread) { - BUG_ON(target_thread->transaction_stack != t); - BUG_ON(target_thread->transaction_stack->from != target_thread); - target_thread->transaction_stack = - target_thread->transaction_stack->from_parent; - t->from = NULL; - } - t->need_reply = 0; - if (t->buffer) - t->buffer->transaction = NULL; - kfree(t); - binder_stats_deleted(BINDER_STAT_TRANSACTION); -} - -static void binder_send_failed_reply(struct binder_transaction *t, - uint32_t error_code) -{ - struct binder_thread *target_thread; - BUG_ON(t->flags & TF_ONE_WAY); - while (1) { - target_thread = t->from; - if (target_thread) { - if (target_thread->return_error != BR_OK && - target_thread->return_error2 == BR_OK) { - target_thread->return_error2 = - target_thread->return_error; - target_thread->return_error = BR_OK; - } - if (target_thread->return_error == BR_OK) { - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: send failed reply for " - "transaction %d to %d:%d\n", - t->debug_id, target_thread->proc->pid, - target_thread->pid); - - binder_pop_transaction(target_thread, t); - target_thread->return_error = error_code; - wake_up_interruptible(&target_thread->wait); - } else { - printk(KERN_ERR "binder: reply failed, target " - "thread, %d:%d, has error code %d " - "already\n", target_thread->proc->pid, - target_thread->pid, - target_thread->return_error); - } - return; - } else { - struct binder_transaction *next = t->from_parent; - - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: send failed reply " - "for transaction %d, target dead\n", - t->debug_id); - - binder_pop_transaction(target_thread, t); - if (next == NULL) { - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: reply failed," - " no target thread at root\n"); - return; - } - t = next; - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: reply failed, no target " - "thread -- retry %d\n", t->debug_id); - } - } -} - -static void binder_transaction_buffer_release(struct binder_proc *proc, - struct binder_buffer *buffer, - size_t *failed_at) -{ - size_t *offp, *off_end; - int debug_id = buffer->debug_id; - - binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d buffer release %d, size %zd-%zd, failed at %p\n", - proc->pid, buffer->debug_id, - buffer->data_size, buffer->offsets_size, failed_at); - - if (buffer->target_node) - binder_dec_node(buffer->target_node, 1, 0); - - offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *))); - if (failed_at) - off_end = failed_at; - else - off_end = (void *)offp + buffer->offsets_size; - for (; offp < off_end; offp++) { - struct flat_binder_object *fp; - if (*offp > buffer->data_size - sizeof(*fp) || - buffer->data_size < sizeof(*fp) || - !IS_ALIGNED(*offp, sizeof(void *))) { - printk(KERN_ERR "binder: transaction release %d bad" - "offset %zd, size %zd\n", debug_id, - *offp, buffer->data_size); - continue; - } - fp = (struct flat_binder_object *)(buffer->data + *offp); - switch (fp->type) { - case BINDER_TYPE_BINDER: - case BINDER_TYPE_WEAK_BINDER: { - struct binder_node *node = binder_get_node(proc, fp->binder); - if (node == NULL) { - printk(KERN_ERR "binder: transaction release %d" - " bad node %p\n", debug_id, fp->binder); - break; - } - binder_debug(BINDER_DEBUG_TRANSACTION, - " node %d u%p\n", - node->debug_id, node->ptr); - binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0); - } break; - case BINDER_TYPE_HANDLE: - case BINDER_TYPE_WEAK_HANDLE: { - struct binder_ref *ref = binder_get_ref(proc, fp->handle); - if (ref == NULL) { - printk(KERN_ERR "binder: transaction release %d" - " bad handle %ld\n", debug_id, - fp->handle); - break; - } - binder_debug(BINDER_DEBUG_TRANSACTION, - " ref %d desc %d (node %d)\n", - ref->debug_id, ref->desc, ref->node->debug_id); - binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE); - } break; - - case BINDER_TYPE_FD: - binder_debug(BINDER_DEBUG_TRANSACTION, - " fd %ld\n", fp->handle); - if (failed_at) - task_close_fd(proc, fp->handle); - break; - - default: - printk(KERN_ERR "binder: transaction release %d bad " - "object type %lx\n", debug_id, fp->type); - break; - } - } -} - -static void binder_transaction(struct binder_proc *proc, - struct binder_thread *thread, - struct binder_transaction_data *tr, int reply) -{ - struct binder_transaction *t; - struct binder_work *tcomplete; - size_t *offp, *off_end; - struct binder_proc *target_proc; - struct binder_thread *target_thread = NULL; - struct binder_node *target_node = NULL; - struct list_head *target_list; - wait_queue_head_t *target_wait; - struct binder_transaction *in_reply_to = NULL; - struct binder_transaction_log_entry *e; - uint32_t return_error; - - e = binder_transaction_log_add(&binder_transaction_log); - e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY); - e->from_proc = proc->pid; - e->from_thread = thread->pid; - e->target_handle = tr->target.handle; - e->data_size = tr->data_size; - e->offsets_size = tr->offsets_size; - - if (reply) { - in_reply_to = thread->transaction_stack; - if (in_reply_to == NULL) { - binder_user_error("binder: %d:%d got reply transaction " - "with no transaction stack\n", - proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - goto err_empty_call_stack; - } - binder_set_nice(in_reply_to->saved_priority); - if (in_reply_to->to_thread != thread) { - binder_user_error("binder: %d:%d got reply transaction " - "with bad transaction stack," - " transaction %d has target %d:%d\n", - proc->pid, thread->pid, in_reply_to->debug_id, - in_reply_to->to_proc ? - in_reply_to->to_proc->pid : 0, - in_reply_to->to_thread ? - in_reply_to->to_thread->pid : 0); - return_error = BR_FAILED_REPLY; - in_reply_to = NULL; - goto err_bad_call_stack; - } - thread->transaction_stack = in_reply_to->to_parent; - target_thread = in_reply_to->from; - if (target_thread == NULL) { - return_error = BR_DEAD_REPLY; - goto err_dead_binder; - } - if (target_thread->transaction_stack != in_reply_to) { - binder_user_error("binder: %d:%d got reply transaction " - "with bad target transaction stack %d, " - "expected %d\n", - proc->pid, thread->pid, - target_thread->transaction_stack ? - target_thread->transaction_stack->debug_id : 0, - in_reply_to->debug_id); - return_error = BR_FAILED_REPLY; - in_reply_to = NULL; - target_thread = NULL; - goto err_dead_binder; - } - target_proc = target_thread->proc; - } else { - if (tr->target.handle) { - struct binder_ref *ref; - ref = binder_get_ref(proc, tr->target.handle); - if (ref == NULL) { - binder_user_error("binder: %d:%d got " - "transaction to invalid handle\n", - proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - goto err_invalid_target_handle; - } - target_node = ref->node; - } else { - target_node = binder_context_mgr_node; - if (target_node == NULL) { - return_error = BR_DEAD_REPLY; - goto err_no_context_mgr_node; - } - } - e->to_node = target_node->debug_id; - target_proc = target_node->proc; - if (target_proc == NULL) { - return_error = BR_DEAD_REPLY; - goto err_dead_binder; - } - if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) { - struct binder_transaction *tmp; - tmp = thread->transaction_stack; - if (tmp->to_thread != thread) { - binder_user_error("binder: %d:%d got new " - "transaction with bad transaction stack" - ", transaction %d has target %d:%d\n", - proc->pid, thread->pid, tmp->debug_id, - tmp->to_proc ? tmp->to_proc->pid : 0, - tmp->to_thread ? - tmp->to_thread->pid : 0); - return_error = BR_FAILED_REPLY; - goto err_bad_call_stack; - } - while (tmp) { - if (tmp->from && tmp->from->proc == target_proc) - target_thread = tmp->from; - tmp = tmp->from_parent; - } - } - } - if (target_thread) { - e->to_thread = target_thread->pid; - target_list = &target_thread->todo; - target_wait = &target_thread->wait; - } else { - target_list = &target_proc->todo; - target_wait = &target_proc->wait; - } - e->to_proc = target_proc->pid; - - /* TODO: reuse incoming transaction for reply */ - t = kzalloc(sizeof(*t), GFP_KERNEL); - if (t == NULL) { - return_error = BR_FAILED_REPLY; - goto err_alloc_t_failed; - } - binder_stats_created(BINDER_STAT_TRANSACTION); - - tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL); - if (tcomplete == NULL) { - return_error = BR_FAILED_REPLY; - goto err_alloc_tcomplete_failed; - } - binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE); - - t->debug_id = ++binder_last_id; - e->debug_id = t->debug_id; - - if (reply) - binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d:%d BC_REPLY %d -> %d:%d, " - "data %p-%p size %zd-%zd\n", - proc->pid, thread->pid, t->debug_id, - target_proc->pid, target_thread->pid, - tr->data.ptr.buffer, tr->data.ptr.offsets, - tr->data_size, tr->offsets_size); - else - binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d:%d BC_TRANSACTION %d -> " - "%d - node %d, data %p-%p size %zd-%zd\n", - proc->pid, thread->pid, t->debug_id, - target_proc->pid, target_node->debug_id, - tr->data.ptr.buffer, tr->data.ptr.offsets, - tr->data_size, tr->offsets_size); - - if (!reply && !(tr->flags & TF_ONE_WAY)) - t->from = thread; - else - t->from = NULL; - t->sender_euid = proc->tsk->cred->euid; - t->to_proc = target_proc; - t->to_thread = target_thread; - t->code = tr->code; - t->flags = tr->flags; - t->priority = task_nice(current); - t->buffer = binder_alloc_buf(target_proc, tr->data_size, - tr->offsets_size, !reply && (t->flags & TF_ONE_WAY)); - if (t->buffer == NULL) { - return_error = BR_FAILED_REPLY; - goto err_binder_alloc_buf_failed; - } - t->buffer->allow_user_free = 0; - t->buffer->debug_id = t->debug_id; - t->buffer->transaction = t; - t->buffer->target_node = target_node; - if (target_node) - binder_inc_node(target_node, 1, 0, NULL); - - offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *))); - - if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) { - binder_user_error("binder: %d:%d got transaction with invalid " - "data ptr\n", proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - goto err_copy_data_failed; - } - if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) { - binder_user_error("binder: %d:%d got transaction with invalid " - "offsets ptr\n", proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - goto err_copy_data_failed; - } - if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) { - binder_user_error("binder: %d:%d got transaction with " - "invalid offsets size, %zd\n", - proc->pid, thread->pid, tr->offsets_size); - return_error = BR_FAILED_REPLY; - goto err_bad_offset; - } - off_end = (void *)offp + tr->offsets_size; - for (; offp < off_end; offp++) { - struct flat_binder_object *fp; - if (*offp > t->buffer->data_size - sizeof(*fp) || - t->buffer->data_size < sizeof(*fp) || - !IS_ALIGNED(*offp, sizeof(void *))) { - binder_user_error("binder: %d:%d got transaction with " - "invalid offset, %zd\n", - proc->pid, thread->pid, *offp); - return_error = BR_FAILED_REPLY; - goto err_bad_offset; - } - fp = (struct flat_binder_object *)(t->buffer->data + *offp); - switch (fp->type) { - case BINDER_TYPE_BINDER: - case BINDER_TYPE_WEAK_BINDER: { - struct binder_ref *ref; - struct binder_node *node = binder_get_node(proc, fp->binder); - if (node == NULL) { - node = binder_new_node(proc, fp->binder, fp->cookie); - if (node == NULL) { - return_error = BR_FAILED_REPLY; - goto err_binder_new_node_failed; - } - node->min_priority = fp->flags & FLAT_BINDER_FLAG_PRIORITY_MASK; - node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS); - } - if (fp->cookie != node->cookie) { - binder_user_error("binder: %d:%d sending u%p " - "node %d, cookie mismatch %p != %p\n", - proc->pid, thread->pid, - fp->binder, node->debug_id, - fp->cookie, node->cookie); - goto err_binder_get_ref_for_node_failed; - } - ref = binder_get_ref_for_node(target_proc, node); - if (ref == NULL) { - return_error = BR_FAILED_REPLY; - goto err_binder_get_ref_for_node_failed; - } - if (fp->type == BINDER_TYPE_BINDER) - fp->type = BINDER_TYPE_HANDLE; - else - fp->type = BINDER_TYPE_WEAK_HANDLE; - fp->handle = ref->desc; - binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, - &thread->todo); - - binder_debug(BINDER_DEBUG_TRANSACTION, - " node %d u%p -> ref %d desc %d\n", - node->debug_id, node->ptr, ref->debug_id, - ref->desc); - } break; - case BINDER_TYPE_HANDLE: - case BINDER_TYPE_WEAK_HANDLE: { - struct binder_ref *ref = binder_get_ref(proc, fp->handle); - if (ref == NULL) { - binder_user_error("binder: %d:%d got " - "transaction with invalid " - "handle, %ld\n", proc->pid, - thread->pid, fp->handle); - return_error = BR_FAILED_REPLY; - goto err_binder_get_ref_failed; - } - if (ref->node->proc == target_proc) { - if (fp->type == BINDER_TYPE_HANDLE) - fp->type = BINDER_TYPE_BINDER; - else - fp->type = BINDER_TYPE_WEAK_BINDER; - fp->binder = ref->node->ptr; - fp->cookie = ref->node->cookie; - binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL); - binder_debug(BINDER_DEBUG_TRANSACTION, - " ref %d desc %d -> node %d u%p\n", - ref->debug_id, ref->desc, ref->node->debug_id, - ref->node->ptr); - } else { - struct binder_ref *new_ref; - new_ref = binder_get_ref_for_node(target_proc, ref->node); - if (new_ref == NULL) { - return_error = BR_FAILED_REPLY; - goto err_binder_get_ref_for_node_failed; - } - fp->handle = new_ref->desc; - binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); - binder_debug(BINDER_DEBUG_TRANSACTION, - " ref %d desc %d -> ref %d desc %d (node %d)\n", - ref->debug_id, ref->desc, new_ref->debug_id, - new_ref->desc, ref->node->debug_id); - } - } break; - - case BINDER_TYPE_FD: { - int target_fd; - struct file *file; - - if (reply) { - if (!(in_reply_to->flags & TF_ACCEPT_FDS)) { - binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n", - proc->pid, thread->pid, fp->handle); - return_error = BR_FAILED_REPLY; - goto err_fd_not_allowed; - } - } else if (!target_node->accept_fds) { - binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n", - proc->pid, thread->pid, fp->handle); - return_error = BR_FAILED_REPLY; - goto err_fd_not_allowed; - } - - file = fget(fp->handle); - if (file == NULL) { - binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n", - proc->pid, thread->pid, fp->handle); - return_error = BR_FAILED_REPLY; - goto err_fget_failed; - } - target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC); - if (target_fd < 0) { - fput(file); - return_error = BR_FAILED_REPLY; - goto err_get_unused_fd_failed; - } - task_fd_install(target_proc, target_fd, file); - binder_debug(BINDER_DEBUG_TRANSACTION, - " fd %ld -> %d\n", fp->handle, target_fd); - /* TODO: fput? */ - fp->handle = target_fd; - } break; - - default: - binder_user_error("binder: %d:%d got transactio" - "n with invalid object type, %lx\n", - proc->pid, thread->pid, fp->type); - return_error = BR_FAILED_REPLY; - goto err_bad_object_type; - } - } - if (reply) { - BUG_ON(t->buffer->async_transaction != 0); - binder_pop_transaction(target_thread, in_reply_to); - } else if (!(t->flags & TF_ONE_WAY)) { - BUG_ON(t->buffer->async_transaction != 0); - t->need_reply = 1; - t->from_parent = thread->transaction_stack; - thread->transaction_stack = t; - } else { - BUG_ON(target_node == NULL); - BUG_ON(t->buffer->async_transaction != 1); - if (target_node->has_async_transaction) { - target_list = &target_node->async_todo; - target_wait = NULL; - } else - target_node->has_async_transaction = 1; - } - t->work.type = BINDER_WORK_TRANSACTION; - list_add_tail(&t->work.entry, target_list); - tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; - list_add_tail(&tcomplete->entry, &thread->todo); - if (target_wait) - wake_up_interruptible(target_wait); - return; - -err_get_unused_fd_failed: -err_fget_failed: -err_fd_not_allowed: -err_binder_get_ref_for_node_failed: -err_binder_get_ref_failed: -err_binder_new_node_failed: -err_bad_object_type: -err_bad_offset: -err_copy_data_failed: - binder_transaction_buffer_release(target_proc, t->buffer, offp); - t->buffer->transaction = NULL; - binder_free_buf(target_proc, t->buffer); -err_binder_alloc_buf_failed: - kfree(tcomplete); - binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); -err_alloc_tcomplete_failed: - kfree(t); - binder_stats_deleted(BINDER_STAT_TRANSACTION); -err_alloc_t_failed: -err_bad_call_stack: -err_empty_call_stack: -err_dead_binder: -err_invalid_target_handle: -err_no_context_mgr_node: - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: %d:%d transaction failed %d, size %zd-%zd\n", - proc->pid, thread->pid, return_error, - tr->data_size, tr->offsets_size); - - { - struct binder_transaction_log_entry *fe; - fe = binder_transaction_log_add(&binder_transaction_log_failed); - *fe = *e; - } - - BUG_ON(thread->return_error != BR_OK); - if (in_reply_to) { - thread->return_error = BR_TRANSACTION_COMPLETE; - binder_send_failed_reply(in_reply_to, return_error); - } else - thread->return_error = return_error; -} - -int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, - void __user *buffer, int size, signed long *consumed) -{ - uint32_t cmd; - void __user *ptr = buffer + *consumed; - void __user *end = buffer + size; - - while (ptr < end && thread->return_error == BR_OK) { - if (get_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) { - binder_stats.bc[_IOC_NR(cmd)]++; - proc->stats.bc[_IOC_NR(cmd)]++; - thread->stats.bc[_IOC_NR(cmd)]++; - } - switch (cmd) { - case BC_INCREFS: - case BC_ACQUIRE: - case BC_RELEASE: - case BC_DECREFS: { - uint32_t target; - struct binder_ref *ref; - const char *debug_string; - - if (get_user(target, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (target == 0 && binder_context_mgr_node && - (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) { - ref = binder_get_ref_for_node(proc, - binder_context_mgr_node); - if (ref->desc != target) { - binder_user_error("binder: %d:" - "%d tried to acquire " - "reference to desc 0, " - "got %d instead\n", - proc->pid, thread->pid, - ref->desc); - } - } else - ref = binder_get_ref(proc, target); - if (ref == NULL) { - binder_user_error("binder: %d:%d refcou" - "nt change on invalid ref %d\n", - proc->pid, thread->pid, target); - break; - } - switch (cmd) { - case BC_INCREFS: - debug_string = "IncRefs"; - binder_inc_ref(ref, 0, NULL); - break; - case BC_ACQUIRE: - debug_string = "Acquire"; - binder_inc_ref(ref, 1, NULL); - break; - case BC_RELEASE: - debug_string = "Release"; - binder_dec_ref(ref, 1); - break; - case BC_DECREFS: - default: - debug_string = "DecRefs"; - binder_dec_ref(ref, 0); - break; - } - binder_debug(BINDER_DEBUG_USER_REFS, - "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n", - proc->pid, thread->pid, debug_string, ref->debug_id, - ref->desc, ref->strong, ref->weak, ref->node->debug_id); - break; - } - case BC_INCREFS_DONE: - case BC_ACQUIRE_DONE: { - void __user *node_ptr; - void *cookie; - struct binder_node *node; - - if (get_user(node_ptr, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - if (get_user(cookie, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - node = binder_get_node(proc, node_ptr); - if (node == NULL) { - binder_user_error("binder: %d:%d " - "%s u%p no match\n", - proc->pid, thread->pid, - cmd == BC_INCREFS_DONE ? - "BC_INCREFS_DONE" : - "BC_ACQUIRE_DONE", - node_ptr); - break; - } - if (cookie != node->cookie) { - binder_user_error("binder: %d:%d %s u%p node %d" - " cookie mismatch %p != %p\n", - proc->pid, thread->pid, - cmd == BC_INCREFS_DONE ? - "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", - node_ptr, node->debug_id, - cookie, node->cookie); - break; - } - if (cmd == BC_ACQUIRE_DONE) { - if (node->pending_strong_ref == 0) { - binder_user_error("binder: %d:%d " - "BC_ACQUIRE_DONE node %d has " - "no pending acquire request\n", - proc->pid, thread->pid, - node->debug_id); - break; - } - node->pending_strong_ref = 0; - } else { - if (node->pending_weak_ref == 0) { - binder_user_error("binder: %d:%d " - "BC_INCREFS_DONE node %d has " - "no pending increfs request\n", - proc->pid, thread->pid, - node->debug_id); - break; - } - node->pending_weak_ref = 0; - } - binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0); - binder_debug(BINDER_DEBUG_USER_REFS, - "binder: %d:%d %s node %d ls %d lw %d\n", - proc->pid, thread->pid, - cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", - node->debug_id, node->local_strong_refs, node->local_weak_refs); - break; - } - case BC_ATTEMPT_ACQUIRE: - printk(KERN_ERR "binder: BC_ATTEMPT_ACQUIRE not supported\n"); - return -EINVAL; - case BC_ACQUIRE_RESULT: - printk(KERN_ERR "binder: BC_ACQUIRE_RESULT not supported\n"); - return -EINVAL; - - case BC_FREE_BUFFER: { - void __user *data_ptr; - struct binder_buffer *buffer; - - if (get_user(data_ptr, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - - buffer = binder_buffer_lookup(proc, data_ptr); - if (buffer == NULL) { - binder_user_error("binder: %d:%d " - "BC_FREE_BUFFER u%p no match\n", - proc->pid, thread->pid, data_ptr); - break; - } - if (!buffer->allow_user_free) { - binder_user_error("binder: %d:%d " - "BC_FREE_BUFFER u%p matched " - "unreturned buffer\n", - proc->pid, thread->pid, data_ptr); - break; - } - binder_debug(BINDER_DEBUG_FREE_BUFFER, - "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n", - proc->pid, thread->pid, data_ptr, buffer->debug_id, - buffer->transaction ? "active" : "finished"); - - if (buffer->transaction) { - buffer->transaction->buffer = NULL; - buffer->transaction = NULL; - } - if (buffer->async_transaction && buffer->target_node) { - BUG_ON(!buffer->target_node->has_async_transaction); - if (list_empty(&buffer->target_node->async_todo)) - buffer->target_node->has_async_transaction = 0; - else - list_move_tail(buffer->target_node->async_todo.next, &thread->todo); - } - binder_transaction_buffer_release(proc, buffer, NULL); - binder_free_buf(proc, buffer); - break; - } - - case BC_TRANSACTION: - case BC_REPLY: { - struct binder_transaction_data tr; - - if (copy_from_user(&tr, ptr, sizeof(tr))) - return -EFAULT; - ptr += sizeof(tr); - binder_transaction(proc, thread, &tr, cmd == BC_REPLY); - break; - } - - case BC_REGISTER_LOOPER: - binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BC_REGISTER_LOOPER\n", - proc->pid, thread->pid); - if (thread->looper & BINDER_LOOPER_STATE_ENTERED) { - thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("binder: %d:%d ERROR:" - " BC_REGISTER_LOOPER called " - "after BC_ENTER_LOOPER\n", - proc->pid, thread->pid); - } else if (proc->requested_threads == 0) { - thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("binder: %d:%d ERROR:" - " BC_REGISTER_LOOPER called " - "without request\n", - proc->pid, thread->pid); - } else { - proc->requested_threads--; - proc->requested_threads_started++; - } - thread->looper |= BINDER_LOOPER_STATE_REGISTERED; - break; - case BC_ENTER_LOOPER: - binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BC_ENTER_LOOPER\n", - proc->pid, thread->pid); - if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) { - thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("binder: %d:%d ERROR:" - " BC_ENTER_LOOPER called after " - "BC_REGISTER_LOOPER\n", - proc->pid, thread->pid); - } - thread->looper |= BINDER_LOOPER_STATE_ENTERED; - break; - case BC_EXIT_LOOPER: - binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BC_EXIT_LOOPER\n", - proc->pid, thread->pid); - thread->looper |= BINDER_LOOPER_STATE_EXITED; - break; - - case BC_REQUEST_DEATH_NOTIFICATION: - case BC_CLEAR_DEATH_NOTIFICATION: { - uint32_t target; - void __user *cookie; - struct binder_ref *ref; - struct binder_ref_death *death; - - if (get_user(target, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (get_user(cookie, (void __user * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - ref = binder_get_ref(proc, target); - if (ref == NULL) { - binder_user_error("binder: %d:%d %s " - "invalid ref %d\n", - proc->pid, thread->pid, - cmd == BC_REQUEST_DEATH_NOTIFICATION ? - "BC_REQUEST_DEATH_NOTIFICATION" : - "BC_CLEAR_DEATH_NOTIFICATION", - target); - break; - } - - binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, - "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n", - proc->pid, thread->pid, - cmd == BC_REQUEST_DEATH_NOTIFICATION ? - "BC_REQUEST_DEATH_NOTIFICATION" : - "BC_CLEAR_DEATH_NOTIFICATION", - cookie, ref->debug_id, ref->desc, - ref->strong, ref->weak, ref->node->debug_id); - - if (cmd == BC_REQUEST_DEATH_NOTIFICATION) { - if (ref->death) { - binder_user_error("binder: %d:%" - "d BC_REQUEST_DEATH_NOTI" - "FICATION death notific" - "ation already set\n", - proc->pid, thread->pid); - break; - } - death = kzalloc(sizeof(*death), GFP_KERNEL); - if (death == NULL) { - thread->return_error = BR_ERROR; - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: %d:%d " - "BC_REQUEST_DEATH_NOTIFICATION failed\n", - proc->pid, thread->pid); - break; - } - binder_stats_created(BINDER_STAT_DEATH); - INIT_LIST_HEAD(&death->work.entry); - death->cookie = cookie; - ref->death = death; - if (ref->node->proc == NULL) { - ref->death->work.type = BINDER_WORK_DEAD_BINDER; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&ref->death->work.entry, &thread->todo); - } else { - list_add_tail(&ref->death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } - } else { - if (ref->death == NULL) { - binder_user_error("binder: %d:%" - "d BC_CLEAR_DEATH_NOTIFI" - "CATION death notificat" - "ion not active\n", - proc->pid, thread->pid); - break; - } - death = ref->death; - if (death->cookie != cookie) { - binder_user_error("binder: %d:%" - "d BC_CLEAR_DEATH_NOTIFI" - "CATION death notificat" - "ion cookie mismatch " - "%p != %p\n", - proc->pid, thread->pid, - death->cookie, cookie); - break; - } - ref->death = NULL; - if (list_empty(&death->work.entry)) { - death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&death->work.entry, &thread->todo); - } else { - list_add_tail(&death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } else { - BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER); - death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR; - } - } - } break; - case BC_DEAD_BINDER_DONE: { - struct binder_work *w; - void __user *cookie; - struct binder_ref_death *death = NULL; - if (get_user(cookie, (void __user * __user *)ptr)) - return -EFAULT; - - ptr += sizeof(void *); - list_for_each_entry(w, &proc->delivered_death, entry) { - struct binder_ref_death *tmp_death = container_of(w, struct binder_ref_death, work); - if (tmp_death->cookie == cookie) { - death = tmp_death; - break; - } - } - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: %d:%d BC_DEAD_BINDER_DONE %p found %p\n", - proc->pid, thread->pid, cookie, death); - if (death == NULL) { - binder_user_error("binder: %d:%d BC_DEAD" - "_BINDER_DONE %p not found\n", - proc->pid, thread->pid, cookie); - break; - } - - list_del_init(&death->work.entry); - if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) { - death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&death->work.entry, &thread->todo); - } else { - list_add_tail(&death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } - } break; - - default: - printk(KERN_ERR "binder: %d:%d unknown command %d\n", - proc->pid, thread->pid, cmd); - return -EINVAL; - } - *consumed = ptr - buffer; - } - return 0; -} - -void binder_stat_br(struct binder_proc *proc, struct binder_thread *thread, - uint32_t cmd) -{ - if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.br)) { - binder_stats.br[_IOC_NR(cmd)]++; - proc->stats.br[_IOC_NR(cmd)]++; - thread->stats.br[_IOC_NR(cmd)]++; - } -} - -static int binder_has_proc_work(struct binder_proc *proc, - struct binder_thread *thread) -{ - return !list_empty(&proc->todo) || - (thread->looper & BINDER_LOOPER_STATE_NEED_RETURN); -} - -static int binder_has_thread_work(struct binder_thread *thread) -{ - return !list_empty(&thread->todo) || thread->return_error != BR_OK || - (thread->looper & BINDER_LOOPER_STATE_NEED_RETURN); -} - -static int binder_thread_read(struct binder_proc *proc, - struct binder_thread *thread, - void __user *buffer, int size, - signed long *consumed, int non_block) -{ - void __user *ptr = buffer + *consumed; - void __user *end = buffer + size; - - int ret = 0; - int wait_for_proc_work; - - if (*consumed == 0) { - if (put_user(BR_NOOP, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - } - -retry: - wait_for_proc_work = thread->transaction_stack == NULL && - list_empty(&thread->todo); - - if (thread->return_error != BR_OK && ptr < end) { - if (thread->return_error2 != BR_OK) { - if (put_user(thread->return_error2, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (ptr == end) - goto done; - thread->return_error2 = BR_OK; - } - if (put_user(thread->return_error, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - thread->return_error = BR_OK; - goto done; - } - - - thread->looper |= BINDER_LOOPER_STATE_WAITING; - if (wait_for_proc_work) - proc->ready_threads++; - mutex_unlock(&binder_lock); - if (wait_for_proc_work) { - if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | - BINDER_LOOPER_STATE_ENTERED))) { - binder_user_error("binder: %d:%d ERROR: Thread waiting " - "for process work before calling BC_REGISTER_" - "LOOPER or BC_ENTER_LOOPER (state %x)\n", - proc->pid, thread->pid, thread->looper); - wait_event_interruptible(binder_user_error_wait, - binder_stop_on_user_error < 2); - } - binder_set_nice(proc->default_priority); - if (non_block) { - if (!binder_has_proc_work(proc, thread)) - ret = -EAGAIN; - } else - ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread)); - } else { - if (non_block) { - if (!binder_has_thread_work(thread)) - ret = -EAGAIN; - } else - ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread)); - } - mutex_lock(&binder_lock); - if (wait_for_proc_work) - proc->ready_threads--; - thread->looper &= ~BINDER_LOOPER_STATE_WAITING; - - if (ret) - return ret; - - while (1) { - uint32_t cmd; - struct binder_transaction_data tr; - struct binder_work *w; - struct binder_transaction *t = NULL; - - if (!list_empty(&thread->todo)) - w = list_first_entry(&thread->todo, struct binder_work, entry); - else if (!list_empty(&proc->todo) && wait_for_proc_work) - w = list_first_entry(&proc->todo, struct binder_work, entry); - else { - if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN)) /* no data added */ - goto retry; - break; - } - - if (end - ptr < sizeof(tr) + 4) - break; - - switch (w->type) { - case BINDER_WORK_TRANSACTION: { - t = container_of(w, struct binder_transaction, work); - } break; - case BINDER_WORK_TRANSACTION_COMPLETE: { - cmd = BR_TRANSACTION_COMPLETE; - if (put_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - - binder_stat_br(proc, thread, cmd); - binder_debug(BINDER_DEBUG_TRANSACTION_COMPLETE, - "binder: %d:%d BR_TRANSACTION_COMPLETE\n", - proc->pid, thread->pid); - - list_del(&w->entry); - kfree(w); - binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); - } break; - case BINDER_WORK_NODE: { - struct binder_node *node = container_of(w, struct binder_node, work); - uint32_t cmd = BR_NOOP; - const char *cmd_name; - int strong = node->internal_strong_refs || node->local_strong_refs; - int weak = !hlist_empty(&node->refs) || node->local_weak_refs || strong; - if (weak && !node->has_weak_ref) { - cmd = BR_INCREFS; - cmd_name = "BR_INCREFS"; - node->has_weak_ref = 1; - node->pending_weak_ref = 1; - node->local_weak_refs++; - } else if (strong && !node->has_strong_ref) { - cmd = BR_ACQUIRE; - cmd_name = "BR_ACQUIRE"; - node->has_strong_ref = 1; - node->pending_strong_ref = 1; - node->local_strong_refs++; - } else if (!strong && node->has_strong_ref) { - cmd = BR_RELEASE; - cmd_name = "BR_RELEASE"; - node->has_strong_ref = 0; - } else if (!weak && node->has_weak_ref) { - cmd = BR_DECREFS; - cmd_name = "BR_DECREFS"; - node->has_weak_ref = 0; - } - if (cmd != BR_NOOP) { - if (put_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (put_user(node->ptr, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - if (put_user(node->cookie, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - - binder_stat_br(proc, thread, cmd); - binder_debug(BINDER_DEBUG_USER_REFS, - "binder: %d:%d %s %d u%p c%p\n", - proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie); - } else { - list_del_init(&w->entry); - if (!weak && !strong) { - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d:%d node %d u%p c%p deleted\n", - proc->pid, thread->pid, node->debug_id, - node->ptr, node->cookie); - rb_erase(&node->rb_node, &proc->nodes); - kfree(node); - binder_stats_deleted(BINDER_STAT_NODE); - } else { - binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d:%d node %d u%p c%p state unchanged\n", - proc->pid, thread->pid, node->debug_id, node->ptr, - node->cookie); - } - } - } break; - case BINDER_WORK_DEAD_BINDER: - case BINDER_WORK_DEAD_BINDER_AND_CLEAR: - case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: { - struct binder_ref_death *death; - uint32_t cmd; - - death = container_of(w, struct binder_ref_death, work); - if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) - cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE; - else - cmd = BR_DEAD_BINDER; - if (put_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (put_user(death->cookie, (void * __user *)ptr)) - return -EFAULT; - ptr += sizeof(void *); - binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, - "binder: %d:%d %s %p\n", - proc->pid, thread->pid, - cmd == BR_DEAD_BINDER ? - "BR_DEAD_BINDER" : - "BR_CLEAR_DEATH_NOTIFICATION_DONE", - death->cookie); - - if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) { - list_del(&w->entry); - kfree(death); - binder_stats_deleted(BINDER_STAT_DEATH); - } else - list_move(&w->entry, &proc->delivered_death); - if (cmd == BR_DEAD_BINDER) - goto done; /* DEAD_BINDER notifications can cause transactions */ - } break; - } - - if (!t) - continue; - - BUG_ON(t->buffer == NULL); - if (t->buffer->target_node) { - struct binder_node *target_node = t->buffer->target_node; - tr.target.ptr = target_node->ptr; - tr.cookie = target_node->cookie; - t->saved_priority = task_nice(current); - if (t->priority < target_node->min_priority && - !(t->flags & TF_ONE_WAY)) - binder_set_nice(t->priority); - else if (!(t->flags & TF_ONE_WAY) || - t->saved_priority > target_node->min_priority) - binder_set_nice(target_node->min_priority); - cmd = BR_TRANSACTION; - } else { - tr.target.ptr = NULL; - tr.cookie = NULL; - cmd = BR_REPLY; - } - tr.code = t->code; - tr.flags = t->flags; - tr.sender_euid = t->sender_euid; - - if (t->from) { - struct task_struct *sender = t->from->proc->tsk; - tr.sender_pid = task_tgid_nr_ns(sender, - current->nsproxy->pid_ns); - } else { - tr.sender_pid = 0; - } - - tr.data_size = t->buffer->data_size; - tr.offsets_size = t->buffer->offsets_size; - tr.data.ptr.buffer = (void *)t->buffer->data + - proc->user_buffer_offset; - tr.data.ptr.offsets = tr.data.ptr.buffer + - ALIGN(t->buffer->data_size, - sizeof(void *)); - - if (put_user(cmd, (uint32_t __user *)ptr)) - return -EFAULT; - ptr += sizeof(uint32_t); - if (copy_to_user(ptr, &tr, sizeof(tr))) - return -EFAULT; - ptr += sizeof(tr); - - binder_stat_br(proc, thread, cmd); - binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d:%d %s %d %d:%d, cmd %d" - "size %zd-%zd ptr %p-%p\n", - proc->pid, thread->pid, - (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" : - "BR_REPLY", - t->debug_id, t->from ? t->from->proc->pid : 0, - t->from ? t->from->pid : 0, cmd, - t->buffer->data_size, t->buffer->offsets_size, - tr.data.ptr.buffer, tr.data.ptr.offsets); - - list_del(&t->work.entry); - t->buffer->allow_user_free = 1; - if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY)) { - t->to_parent = thread->transaction_stack; - t->to_thread = thread; - thread->transaction_stack = t; - } else { - t->buffer->transaction = NULL; - kfree(t); - binder_stats_deleted(BINDER_STAT_TRANSACTION); - } - break; - } - -done: - - *consumed = ptr - buffer; - if (proc->requested_threads + proc->ready_threads == 0 && - proc->requested_threads_started < proc->max_threads && - (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | - BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */ - /*spawn a new thread if we leave this out */) { - proc->requested_threads++; - binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BR_SPAWN_LOOPER\n", - proc->pid, thread->pid); - if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer)) - return -EFAULT; - } - return 0; -} - -static void binder_release_work(struct list_head *list) -{ - struct binder_work *w; - while (!list_empty(list)) { - w = list_first_entry(list, struct binder_work, entry); - list_del_init(&w->entry); - switch (w->type) { - case BINDER_WORK_TRANSACTION: { - struct binder_transaction *t; - - t = container_of(w, struct binder_transaction, work); - if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) - binder_send_failed_reply(t, BR_DEAD_REPLY); - } break; - case BINDER_WORK_TRANSACTION_COMPLETE: { - kfree(w); - binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); - } break; - default: - break; - } - } - -} - -static struct binder_thread *binder_get_thread(struct binder_proc *proc) -{ - struct binder_thread *thread = NULL; - struct rb_node *parent = NULL; - struct rb_node **p = &proc->threads.rb_node; - - while (*p) { - parent = *p; - thread = rb_entry(parent, struct binder_thread, rb_node); - - if (current->pid < thread->pid) - p = &(*p)->rb_left; - else if (current->pid > thread->pid) - p = &(*p)->rb_right; - else - break; - } - if (*p == NULL) { - thread = kzalloc(sizeof(*thread), GFP_KERNEL); - if (thread == NULL) - return NULL; - binder_stats_created(BINDER_STAT_THREAD); - thread->proc = proc; - thread->pid = current->pid; - init_waitqueue_head(&thread->wait); - INIT_LIST_HEAD(&thread->todo); - rb_link_node(&thread->rb_node, parent, p); - rb_insert_color(&thread->rb_node, &proc->threads); - thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN; - thread->return_error = BR_OK; - thread->return_error2 = BR_OK; - } - return thread; -} - -static int binder_free_thread(struct binder_proc *proc, - struct binder_thread *thread) -{ - struct binder_transaction *t; - struct binder_transaction *send_reply = NULL; - int active_transactions = 0; - - rb_erase(&thread->rb_node, &proc->threads); - t = thread->transaction_stack; - if (t && t->to_thread == thread) - send_reply = t; - while (t) { - active_transactions++; - binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, - "binder: release %d:%d transaction %d " - "%s, still active\n", proc->pid, thread->pid, - t->debug_id, - (t->to_thread == thread) ? "in" : "out"); - - if (t->to_thread == thread) { - t->to_proc = NULL; - t->to_thread = NULL; - if (t->buffer) { - t->buffer->transaction = NULL; - t->buffer = NULL; - } - t = t->to_parent; - } else if (t->from == thread) { - t->from = NULL; - t = t->from_parent; - } else - BUG(); - } - if (send_reply) - binder_send_failed_reply(send_reply, BR_DEAD_REPLY); - binder_release_work(&thread->todo); - kfree(thread); - binder_stats_deleted(BINDER_STAT_THREAD); - return active_transactions; -} - -static unsigned int binder_poll(struct file *filp, - struct poll_table_struct *wait) -{ - struct binder_proc *proc = filp->private_data; - struct binder_thread *thread = NULL; - int wait_for_proc_work; - - mutex_lock(&binder_lock); - thread = binder_get_thread(proc); - - wait_for_proc_work = thread->transaction_stack == NULL && - list_empty(&thread->todo) && thread->return_error == BR_OK; - mutex_unlock(&binder_lock); - - if (wait_for_proc_work) { - if (binder_has_proc_work(proc, thread)) - return POLLIN; - poll_wait(filp, &proc->wait, wait); - if (binder_has_proc_work(proc, thread)) - return POLLIN; - } else { - if (binder_has_thread_work(thread)) - return POLLIN; - poll_wait(filp, &thread->wait, wait); - if (binder_has_thread_work(thread)) - return POLLIN; - } - return 0; -} - -static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - int ret; - struct binder_proc *proc = filp->private_data; - struct binder_thread *thread; - unsigned int size = _IOC_SIZE(cmd); - void __user *ubuf = (void __user *)arg; - - /*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/ - - ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); - if (ret) - return ret; - - mutex_lock(&binder_lock); - thread = binder_get_thread(proc); - if (thread == NULL) { - ret = -ENOMEM; - goto err; - } - - switch (cmd) { - case BINDER_WRITE_READ: { - struct binder_write_read bwr; - if (size != sizeof(struct binder_write_read)) { - ret = -EINVAL; - goto err; - } - if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { - ret = -EFAULT; - goto err; - } - binder_debug(BINDER_DEBUG_READ_WRITE, - "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n", - proc->pid, thread->pid, bwr.write_size, bwr.write_buffer, - bwr.read_size, bwr.read_buffer); - - if (bwr.write_size > 0) { - ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed); - if (ret < 0) { - bwr.read_consumed = 0; - if (copy_to_user(ubuf, &bwr, sizeof(bwr))) - ret = -EFAULT; - goto err; - } - } - if (bwr.read_size > 0) { - ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK); - if (!list_empty(&proc->todo)) - wake_up_interruptible(&proc->wait); - if (ret < 0) { - if (copy_to_user(ubuf, &bwr, sizeof(bwr))) - ret = -EFAULT; - goto err; - } - } - binder_debug(BINDER_DEBUG_READ_WRITE, - "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n", - proc->pid, thread->pid, bwr.write_consumed, bwr.write_size, - bwr.read_consumed, bwr.read_size); - if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { - ret = -EFAULT; - goto err; - } - break; - } - case BINDER_SET_MAX_THREADS: - if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) { - ret = -EINVAL; - goto err; - } - break; - case BINDER_SET_CONTEXT_MGR: - if (binder_context_mgr_node != NULL) { - printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n"); - ret = -EBUSY; - goto err; - } - if (binder_context_mgr_uid != -1) { - if (binder_context_mgr_uid != current->cred->euid) { - printk(KERN_ERR "binder: BINDER_SET_" - "CONTEXT_MGR bad uid %d != %d\n", - current->cred->euid, - binder_context_mgr_uid); - ret = -EPERM; - goto err; - } - } else - binder_context_mgr_uid = current->cred->euid; - binder_context_mgr_node = binder_new_node(proc, NULL, NULL); - if (binder_context_mgr_node == NULL) { - ret = -ENOMEM; - goto err; - } - binder_context_mgr_node->local_weak_refs++; - binder_context_mgr_node->local_strong_refs++; - binder_context_mgr_node->has_strong_ref = 1; - binder_context_mgr_node->has_weak_ref = 1; - break; - case BINDER_THREAD_EXIT: - binder_debug(BINDER_DEBUG_THREADS, "binder: %d:%d exit\n", - proc->pid, thread->pid); - binder_free_thread(proc, thread); - thread = NULL; - break; - case BINDER_VERSION: - if (size != sizeof(struct binder_version)) { - ret = -EINVAL; - goto err; - } - if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &((struct binder_version *)ubuf)->protocol_version)) { - ret = -EINVAL; - goto err; - } - break; - default: - ret = -EINVAL; - goto err; - } - ret = 0; -err: - if (thread) - thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN; - mutex_unlock(&binder_lock); - wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); - if (ret && ret != -ERESTARTSYS) - printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); - return ret; -} - -static void binder_vma_open(struct vm_area_struct *vma) -{ - struct binder_proc *proc = vma->vm_private_data; - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", - proc->pid, vma->vm_start, vma->vm_end, - (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, - (unsigned long)pgprot_val(vma->vm_page_prot)); - dump_stack(); -} - -static void binder_vma_close(struct vm_area_struct *vma) -{ - struct binder_proc *proc = vma->vm_private_data; - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", - proc->pid, vma->vm_start, vma->vm_end, - (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, - (unsigned long)pgprot_val(vma->vm_page_prot)); - proc->vma = NULL; - binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES); -} - -static struct vm_operations_struct binder_vm_ops = { - .open = binder_vma_open, - .close = binder_vma_close, -}; - -static int binder_mmap(struct file *filp, struct vm_area_struct *vma) -{ - int ret; - struct vm_struct *area; - struct binder_proc *proc = filp->private_data; - const char *failure_string; - struct binder_buffer *buffer; - - if ((vma->vm_end - vma->vm_start) > SZ_4M) - vma->vm_end = vma->vm_start + SZ_4M; - - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", - proc->pid, vma->vm_start, vma->vm_end, - (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, - (unsigned long)pgprot_val(vma->vm_page_prot)); - - if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) { - ret = -EPERM; - failure_string = "bad vm_flags"; - goto err_bad_arg; - } - vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE; - - if (proc->buffer) { - ret = -EBUSY; - failure_string = "already mapped"; - goto err_already_mapped; - } - - area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP); - if (area == NULL) { - ret = -ENOMEM; - failure_string = "get_vm_area"; - goto err_get_vm_area_failed; - } - proc->buffer = area->addr; - proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer; - -#ifdef CONFIG_CPU_CACHE_VIPT - if (cache_is_vipt_aliasing()) { - while (CACHE_COLOUR((vma->vm_start ^ (uint32_t)proc->buffer))) { - printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer); - vma->vm_start += PAGE_SIZE; - } - } -#endif - proc->pages = kzalloc(sizeof(proc->pages[0]) * ((vma->vm_end - vma->vm_start) / PAGE_SIZE), GFP_KERNEL); - if (proc->pages == NULL) { - ret = -ENOMEM; - failure_string = "alloc page array"; - goto err_alloc_pages_failed; - } - proc->buffer_size = vma->vm_end - vma->vm_start; - - vma->vm_ops = &binder_vm_ops; - vma->vm_private_data = proc; - - if (binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma)) { - ret = -ENOMEM; - failure_string = "alloc small buf"; - goto err_alloc_small_buf_failed; - } - buffer = proc->buffer; - INIT_LIST_HEAD(&proc->buffers); - list_add(&buffer->entry, &proc->buffers); - buffer->free = 1; - binder_insert_free_buffer(proc, buffer); - proc->free_async_space = proc->buffer_size / 2; - barrier(); - proc->files = get_files_struct(current); - proc->vma = vma; - - /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", - proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/ - return 0; - -err_alloc_small_buf_failed: - kfree(proc->pages); - proc->pages = NULL; -err_alloc_pages_failed: - vfree(proc->buffer); - proc->buffer = NULL; -err_get_vm_area_failed: -err_already_mapped: -err_bad_arg: - printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n", - proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); - return ret; -} - -static int binder_open(struct inode *nodp, struct file *filp) -{ - struct binder_proc *proc; - - binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n", - current->group_leader->pid, current->pid); - - proc = kzalloc(sizeof(*proc), GFP_KERNEL); - if (proc == NULL) - return -ENOMEM; - get_task_struct(current); - proc->tsk = current; - INIT_LIST_HEAD(&proc->todo); - init_waitqueue_head(&proc->wait); - proc->default_priority = task_nice(current); - mutex_lock(&binder_lock); - binder_stats_created(BINDER_STAT_PROC); - hlist_add_head(&proc->proc_node, &binder_procs); - proc->pid = current->group_leader->pid; - INIT_LIST_HEAD(&proc->delivered_death); - filp->private_data = proc; - mutex_unlock(&binder_lock); - - if (binder_proc_dir_entry_proc) { - char strbuf[11]; - snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); - remove_proc_entry(strbuf, binder_proc_dir_entry_proc); - create_proc_read_entry(strbuf, S_IRUGO, - binder_proc_dir_entry_proc, - binder_read_proc_proc, proc); - } - - return 0; -} - -static int binder_flush(struct file *filp, fl_owner_t id) -{ - struct binder_proc *proc = filp->private_data; - - binder_defer_work(proc, BINDER_DEFERRED_FLUSH); - - return 0; -} - -static void binder_deferred_flush(struct binder_proc *proc) -{ - struct rb_node *n; - int wake_count = 0; - for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { - struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node); - thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN; - if (thread->looper & BINDER_LOOPER_STATE_WAITING) { - wake_up_interruptible(&thread->wait); - wake_count++; - } - } - wake_up_interruptible_all(&proc->wait); - - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder_flush: %d woke %d threads\n", proc->pid, - wake_count); -} - -static int binder_release(struct inode *nodp, struct file *filp) -{ - struct binder_proc *proc = filp->private_data; - if (binder_proc_dir_entry_proc) { - char strbuf[11]; - snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); - remove_proc_entry(strbuf, binder_proc_dir_entry_proc); - } - - binder_defer_work(proc, BINDER_DEFERRED_RELEASE); - - return 0; -} - -static void binder_deferred_release(struct binder_proc *proc) -{ - struct hlist_node *pos; - struct binder_transaction *t; - struct rb_node *n; - int threads, nodes, incoming_refs, outgoing_refs, buffers, active_transactions, page_count; - - BUG_ON(proc->vma); - BUG_ON(proc->files); - - hlist_del(&proc->proc_node); - if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) { - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder_release: %d context_mgr_node gone\n", - proc->pid); - binder_context_mgr_node = NULL; - } - - threads = 0; - active_transactions = 0; - while ((n = rb_first(&proc->threads))) { - struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node); - threads++; - active_transactions += binder_free_thread(proc, thread); - } - nodes = 0; - incoming_refs = 0; - while ((n = rb_first(&proc->nodes))) { - struct binder_node *node = rb_entry(n, struct binder_node, rb_node); - - nodes++; - rb_erase(&node->rb_node, &proc->nodes); - list_del_init(&node->work.entry); - if (hlist_empty(&node->refs)) { - kfree(node); - binder_stats_deleted(BINDER_STAT_NODE); - } else { - struct binder_ref *ref; - int death = 0; - - node->proc = NULL; - node->local_strong_refs = 0; - node->local_weak_refs = 0; - hlist_add_head(&node->dead_node, &binder_dead_nodes); - - hlist_for_each_entry(ref, pos, &node->refs, node_entry) { - incoming_refs++; - if (ref->death) { - death++; - if (list_empty(&ref->death->work.entry)) { - ref->death->work.type = BINDER_WORK_DEAD_BINDER; - list_add_tail(&ref->death->work.entry, &ref->proc->todo); - wake_up_interruptible(&ref->proc->wait); - } else - BUG(); - } - } - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: node %d now dead, " - "refs %d, death %d\n", node->debug_id, - incoming_refs, death); - } - } - outgoing_refs = 0; - while ((n = rb_first(&proc->refs_by_desc))) { - struct binder_ref *ref = rb_entry(n, struct binder_ref, - rb_node_desc); - outgoing_refs++; - binder_delete_ref(ref); - } - binder_release_work(&proc->todo); - buffers = 0; - - while ((n = rb_first(&proc->allocated_buffers))) { - struct binder_buffer *buffer = rb_entry(n, struct binder_buffer, - rb_node); - t = buffer->transaction; - if (t) { - t->buffer = NULL; - buffer->transaction = NULL; - printk(KERN_ERR "binder: release proc %d, " - "transaction %d, not freed\n", - proc->pid, t->debug_id); - /*BUG();*/ - } - binder_free_buf(proc, buffer); - buffers++; - } - - binder_stats_deleted(BINDER_STAT_PROC); - - page_count = 0; - if (proc->pages) { - int i; - for (i = 0; i < proc->buffer_size / PAGE_SIZE; i++) { - if (proc->pages[i]) { - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder_release: %d: " - "page %d at %p not freed\n", - proc->pid, i, - proc->buffer + i * PAGE_SIZE); - __free_page(proc->pages[i]); - page_count++; - } - } - kfree(proc->pages); - vfree(proc->buffer); - } - - put_task_struct(proc->tsk); - - binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder_release: %d threads %d, nodes %d (ref %d), " - "refs %d, active transactions %d, buffers %d, " - "pages %d\n", - proc->pid, threads, nodes, incoming_refs, outgoing_refs, - active_transactions, buffers, page_count); - - kfree(proc); -} - -static void binder_deferred_func(struct work_struct *work) -{ - struct binder_proc *proc; - struct files_struct *files; - - int defer; - do { - mutex_lock(&binder_lock); - mutex_lock(&binder_deferred_lock); - if (!hlist_empty(&binder_deferred_list)) { - proc = hlist_entry(binder_deferred_list.first, - struct binder_proc, deferred_work_node); - hlist_del_init(&proc->deferred_work_node); - defer = proc->deferred_work; - proc->deferred_work = 0; - } else { - proc = NULL; - defer = 0; - } - mutex_unlock(&binder_deferred_lock); - - files = NULL; - if (defer & BINDER_DEFERRED_PUT_FILES) { - files = proc->files; - if (files) - proc->files = NULL; - } - - if (defer & BINDER_DEFERRED_FLUSH) - binder_deferred_flush(proc); - - if (defer & BINDER_DEFERRED_RELEASE) - binder_deferred_release(proc); /* frees proc */ - - mutex_unlock(&binder_lock); - if (files) - put_files_struct(files); - } while (proc); -} -static DECLARE_WORK(binder_deferred_work, binder_deferred_func); - -static void -binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer) -{ - mutex_lock(&binder_deferred_lock); - proc->deferred_work |= defer; - if (hlist_unhashed(&proc->deferred_work_node)) { - hlist_add_head(&proc->deferred_work_node, - &binder_deferred_list); - schedule_work(&binder_deferred_work); - } - mutex_unlock(&binder_deferred_lock); -} - -static char *print_binder_transaction(char *buf, char *end, const char *prefix, - struct binder_transaction *t) -{ - buf += snprintf(buf, end - buf, - "%s %d: %p from %d:%d to %d:%d code %x " - "flags %x pri %ld r%d", - prefix, t->debug_id, t, - t->from ? t->from->proc->pid : 0, - t->from ? t->from->pid : 0, - t->to_proc ? t->to_proc->pid : 0, - t->to_thread ? t->to_thread->pid : 0, - t->code, t->flags, t->priority, t->need_reply); - if (buf >= end) - return buf; - if (t->buffer == NULL) { - buf += snprintf(buf, end - buf, " buffer free\n"); - return buf; - } - if (t->buffer->target_node) { - buf += snprintf(buf, end - buf, " node %d", - t->buffer->target_node->debug_id); - if (buf >= end) - return buf; - } - buf += snprintf(buf, end - buf, " size %zd:%zd data %p\n", - t->buffer->data_size, t->buffer->offsets_size, - t->buffer->data); - return buf; -} - -static char *print_binder_buffer(char *buf, char *end, const char *prefix, - struct binder_buffer *buffer) -{ - buf += snprintf(buf, end - buf, "%s %d: %p size %zd:%zd %s\n", - prefix, buffer->debug_id, buffer->data, - buffer->data_size, buffer->offsets_size, - buffer->transaction ? "active" : "delivered"); - return buf; -} - -static char *print_binder_work(char *buf, char *end, const char *prefix, - const char *transaction_prefix, - struct binder_work *w) -{ - struct binder_node *node; - struct binder_transaction *t; - - switch (w->type) { - case BINDER_WORK_TRANSACTION: - t = container_of(w, struct binder_transaction, work); - buf = print_binder_transaction(buf, end, transaction_prefix, t); - break; - case BINDER_WORK_TRANSACTION_COMPLETE: - buf += snprintf(buf, end - buf, - "%stransaction complete\n", prefix); - break; - case BINDER_WORK_NODE: - node = container_of(w, struct binder_node, work); - buf += snprintf(buf, end - buf, "%snode work %d: u%p c%p\n", - prefix, node->debug_id, node->ptr, - node->cookie); - break; - case BINDER_WORK_DEAD_BINDER: - buf += snprintf(buf, end - buf, "%shas dead binder\n", prefix); - break; - case BINDER_WORK_DEAD_BINDER_AND_CLEAR: - buf += snprintf(buf, end - buf, - "%shas cleared dead binder\n", prefix); - break; - case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: - buf += snprintf(buf, end - buf, - "%shas cleared death notification\n", prefix); - break; - default: - buf += snprintf(buf, end - buf, "%sunknown work: type %d\n", - prefix, w->type); - break; - } - return buf; -} - -static char *print_binder_thread(char *buf, char *end, - struct binder_thread *thread, - int print_always) -{ - struct binder_transaction *t; - struct binder_work *w; - char *start_buf = buf; - char *header_buf; - - buf += snprintf(buf, end - buf, " thread %d: l %02x\n", - thread->pid, thread->looper); - header_buf = buf; - t = thread->transaction_stack; - while (t) { - if (buf >= end) - break; - if (t->from == thread) { - buf = print_binder_transaction(buf, end, - " outgoing transaction", t); - t = t->from_parent; - } else if (t->to_thread == thread) { - buf = print_binder_transaction(buf, end, - " incoming transaction", t); - t = t->to_parent; - } else { - buf = print_binder_transaction(buf, end, - " bad transaction", t); - t = NULL; - } - } - list_for_each_entry(w, &thread->todo, entry) { - if (buf >= end) - break; - buf = print_binder_work(buf, end, " ", - " pending transaction", w); - } - if (!print_always && buf == header_buf) - buf = start_buf; - return buf; -} - -static char *print_binder_node(char *buf, char *end, struct binder_node *node) -{ - struct binder_ref *ref; - struct hlist_node *pos; - struct binder_work *w; - int count; - - count = 0; - hlist_for_each_entry(ref, pos, &node->refs, node_entry) - count++; - - buf += snprintf(buf, end - buf, - " node %d: u%p c%p hs %d hw %d ls %d lw %d " - "is %d iw %d", - node->debug_id, node->ptr, node->cookie, - node->has_strong_ref, node->has_weak_ref, - node->local_strong_refs, node->local_weak_refs, - node->internal_strong_refs, count); - if (buf >= end) - return buf; - if (count) { - buf += snprintf(buf, end - buf, " proc"); - if (buf >= end) - return buf; - hlist_for_each_entry(ref, pos, &node->refs, node_entry) { - buf += snprintf(buf, end - buf, " %d", ref->proc->pid); - if (buf >= end) - return buf; - } - } - buf += snprintf(buf, end - buf, "\n"); - list_for_each_entry(w, &node->async_todo, entry) { - if (buf >= end) - break; - buf = print_binder_work(buf, end, " ", - " pending async transaction", w); - } - return buf; -} - -static char *print_binder_ref(char *buf, char *end, struct binder_ref *ref) -{ - buf += snprintf(buf, end - buf, - " ref %d: desc %d %snode %d s %d w %d d %p\n", - ref->debug_id, ref->desc, - ref->node->proc ? "" : "dead ", ref->node->debug_id, - ref->strong, ref->weak, ref->death); - return buf; -} - -static char *print_binder_proc(char *buf, char *end, - struct binder_proc *proc, int print_all) -{ - struct binder_work *w; - struct rb_node *n; - char *start_buf = buf; - char *header_buf; - - buf += snprintf(buf, end - buf, "proc %d\n", proc->pid); - header_buf = buf; - - for (n = rb_first(&proc->threads); - n != NULL && buf < end; - n = rb_next(n)) - buf = print_binder_thread(buf, end, - rb_entry(n, struct binder_thread, - rb_node), print_all); - for (n = rb_first(&proc->nodes); - n != NULL && buf < end; - n = rb_next(n)) { - struct binder_node *node = rb_entry(n, struct binder_node, - rb_node); - if (print_all || node->has_async_transaction) - buf = print_binder_node(buf, end, node); - } - if (print_all) { - for (n = rb_first(&proc->refs_by_desc); - n != NULL && buf < end; - n = rb_next(n)) - buf = print_binder_ref(buf, end, - rb_entry(n, struct binder_ref, - rb_node_desc)); - } - for (n = rb_first(&proc->allocated_buffers); - n != NULL && buf < end; - n = rb_next(n)) - buf = print_binder_buffer(buf, end, " buffer", - rb_entry(n, struct binder_buffer, - rb_node)); - list_for_each_entry(w, &proc->todo, entry) { - if (buf >= end) - break; - buf = print_binder_work(buf, end, " ", - " pending transaction", w); - } - list_for_each_entry(w, &proc->delivered_death, entry) { - if (buf >= end) - break; - buf += snprintf(buf, end - buf, - " has delivered dead binder\n"); - break; - } - if (!print_all && buf == header_buf) - buf = start_buf; - return buf; -} - -static const char *binder_return_strings[] = { - "BR_ERROR", - "BR_OK", - "BR_TRANSACTION", - "BR_REPLY", - "BR_ACQUIRE_RESULT", - "BR_DEAD_REPLY", - "BR_TRANSACTION_COMPLETE", - "BR_INCREFS", - "BR_ACQUIRE", - "BR_RELEASE", - "BR_DECREFS", - "BR_ATTEMPT_ACQUIRE", - "BR_NOOP", - "BR_SPAWN_LOOPER", - "BR_FINISHED", - "BR_DEAD_BINDER", - "BR_CLEAR_DEATH_NOTIFICATION_DONE", - "BR_FAILED_REPLY" -}; - -static const char *binder_command_strings[] = { - "BC_TRANSACTION", - "BC_REPLY", - "BC_ACQUIRE_RESULT", - "BC_FREE_BUFFER", - "BC_INCREFS", - "BC_ACQUIRE", - "BC_RELEASE", - "BC_DECREFS", - "BC_INCREFS_DONE", - "BC_ACQUIRE_DONE", - "BC_ATTEMPT_ACQUIRE", - "BC_REGISTER_LOOPER", - "BC_ENTER_LOOPER", - "BC_EXIT_LOOPER", - "BC_REQUEST_DEATH_NOTIFICATION", - "BC_CLEAR_DEATH_NOTIFICATION", - "BC_DEAD_BINDER_DONE" -}; - -static const char *binder_objstat_strings[] = { - "proc", - "thread", - "node", - "ref", - "death", - "transaction", - "transaction_complete" -}; - -static char *print_binder_stats(char *buf, char *end, const char *prefix, - struct binder_stats *stats) -{ - int i; - - BUILD_BUG_ON(ARRAY_SIZE(stats->bc) != - ARRAY_SIZE(binder_command_strings)); - for (i = 0; i < ARRAY_SIZE(stats->bc); i++) { - if (stats->bc[i]) - buf += snprintf(buf, end - buf, "%s%s: %d\n", prefix, - binder_command_strings[i], - stats->bc[i]); - if (buf >= end) - return buf; - } - - BUILD_BUG_ON(ARRAY_SIZE(stats->br) != - ARRAY_SIZE(binder_return_strings)); - for (i = 0; i < ARRAY_SIZE(stats->br); i++) { - if (stats->br[i]) - buf += snprintf(buf, end - buf, "%s%s: %d\n", prefix, - binder_return_strings[i], stats->br[i]); - if (buf >= end) - return buf; - } - - BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != - ARRAY_SIZE(binder_objstat_strings)); - BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != - ARRAY_SIZE(stats->obj_deleted)); - for (i = 0; i < ARRAY_SIZE(stats->obj_created); i++) { - if (stats->obj_created[i] || stats->obj_deleted[i]) - buf += snprintf(buf, end - buf, - "%s%s: active %d total %d\n", prefix, - binder_objstat_strings[i], - stats->obj_created[i] - - stats->obj_deleted[i], - stats->obj_created[i]); - if (buf >= end) - return buf; - } - return buf; -} - -static char *print_binder_proc_stats(char *buf, char *end, - struct binder_proc *proc) -{ - struct binder_work *w; - struct rb_node *n; - int count, strong, weak; - - buf += snprintf(buf, end - buf, "proc %d\n", proc->pid); - if (buf >= end) - return buf; - count = 0; - for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) - count++; - buf += snprintf(buf, end - buf, " threads: %d\n", count); - if (buf >= end) - return buf; - buf += snprintf(buf, end - buf, " requested threads: %d+%d/%d\n" - " ready threads %d\n" - " free async space %zd\n", proc->requested_threads, - proc->requested_threads_started, proc->max_threads, - proc->ready_threads, proc->free_async_space); - if (buf >= end) - return buf; - count = 0; - for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) - count++; - buf += snprintf(buf, end - buf, " nodes: %d\n", count); - if (buf >= end) - return buf; - count = 0; - strong = 0; - weak = 0; - for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { - struct binder_ref *ref = rb_entry(n, struct binder_ref, - rb_node_desc); - count++; - strong += ref->strong; - weak += ref->weak; - } - buf += snprintf(buf, end - buf, " refs: %d s %d w %d\n", - count, strong, weak); - if (buf >= end) - return buf; - - count = 0; - for (n = rb_first(&proc->allocated_buffers); n != NULL; n = rb_next(n)) - count++; - buf += snprintf(buf, end - buf, " buffers: %d\n", count); - if (buf >= end) - return buf; - - count = 0; - list_for_each_entry(w, &proc->todo, entry) { - switch (w->type) { - case BINDER_WORK_TRANSACTION: - count++; - break; - default: - break; - } - } - buf += snprintf(buf, end - buf, " pending transactions: %d\n", count); - if (buf >= end) - return buf; - - buf = print_binder_stats(buf, end, " ", &proc->stats); - - return buf; -} - - -static int binder_read_proc_state(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct binder_proc *proc; - struct hlist_node *pos; - struct binder_node *node; - int len = 0; - char *buf = page; - char *end = page + PAGE_SIZE; - int do_lock = !binder_debug_no_lock; - - if (off) - return 0; - - if (do_lock) - mutex_lock(&binder_lock); - - buf += snprintf(buf, end - buf, "binder state:\n"); - - if (!hlist_empty(&binder_dead_nodes)) - buf += snprintf(buf, end - buf, "dead nodes:\n"); - hlist_for_each_entry(node, pos, &binder_dead_nodes, dead_node) { - if (buf >= end) - break; - buf = print_binder_node(buf, end, node); - } - - hlist_for_each_entry(proc, pos, &binder_procs, proc_node) { - if (buf >= end) - break; - buf = print_binder_proc(buf, end, proc, 1); - } - if (do_lock) - mutex_unlock(&binder_lock); - if (buf > page + PAGE_SIZE) - buf = page + PAGE_SIZE; - - *start = page + off; - - len = buf - page; - if (len > off) - len -= off; - else - len = 0; - - return len < count ? len : count; -} - -static int binder_read_proc_stats(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct binder_proc *proc; - struct hlist_node *pos; - int len = 0; - char *p = page; - int do_lock = !binder_debug_no_lock; - - if (off) - return 0; - - if (do_lock) - mutex_lock(&binder_lock); - - p += snprintf(p, PAGE_SIZE, "binder stats:\n"); - - p = print_binder_stats(p, page + PAGE_SIZE, "", &binder_stats); - - hlist_for_each_entry(proc, pos, &binder_procs, proc_node) { - if (p >= page + PAGE_SIZE) - break; - p = print_binder_proc_stats(p, page + PAGE_SIZE, proc); - } - if (do_lock) - mutex_unlock(&binder_lock); - if (p > page + PAGE_SIZE) - p = page + PAGE_SIZE; - - *start = page + off; - - len = p - page; - if (len > off) - len -= off; - else - len = 0; - - return len < count ? len : count; -} - -static int binder_read_proc_transactions(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct binder_proc *proc; - struct hlist_node *pos; - int len = 0; - char *buf = page; - char *end = page + PAGE_SIZE; - int do_lock = !binder_debug_no_lock; - - if (off) - return 0; - - if (do_lock) - mutex_lock(&binder_lock); - - buf += snprintf(buf, end - buf, "binder transactions:\n"); - hlist_for_each_entry(proc, pos, &binder_procs, proc_node) { - if (buf >= end) - break; - buf = print_binder_proc(buf, end, proc, 0); - } - if (do_lock) - mutex_unlock(&binder_lock); - if (buf > page + PAGE_SIZE) - buf = page + PAGE_SIZE; - - *start = page + off; - - len = buf - page; - if (len > off) - len -= off; - else - len = 0; - - return len < count ? len : count; -} - -static int binder_read_proc_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct binder_proc *proc = data; - int len = 0; - char *p = page; - int do_lock = !binder_debug_no_lock; - - if (off) - return 0; - - if (do_lock) - mutex_lock(&binder_lock); - p += snprintf(p, PAGE_SIZE, "binder proc state:\n"); - p = print_binder_proc(p, page + PAGE_SIZE, proc, 1); - if (do_lock) - mutex_unlock(&binder_lock); - - if (p > page + PAGE_SIZE) - p = page + PAGE_SIZE; - *start = page + off; - - len = p - page; - if (len > off) - len -= off; - else - len = 0; - - return len < count ? len : count; -} - -static char *print_binder_transaction_log_entry(char *buf, char *end, - struct binder_transaction_log_entry *e) -{ - buf += snprintf(buf, end - buf, - "%d: %s from %d:%d to %d:%d node %d handle %d " - "size %d:%d\n", - e->debug_id, (e->call_type == 2) ? "reply" : - ((e->call_type == 1) ? "async" : "call "), e->from_proc, - e->from_thread, e->to_proc, e->to_thread, e->to_node, - e->target_handle, e->data_size, e->offsets_size); - return buf; -} - -static int binder_read_proc_transaction_log( - char *page, char **start, off_t off, int count, int *eof, void *data) -{ - struct binder_transaction_log *log = data; - int len = 0; - int i; - char *buf = page; - char *end = page + PAGE_SIZE; - - if (off) - return 0; - - if (log->full) { - for (i = log->next; i < ARRAY_SIZE(log->entry); i++) { - if (buf >= end) - break; - buf = print_binder_transaction_log_entry(buf, end, - &log->entry[i]); - } - } - for (i = 0; i < log->next; i++) { - if (buf >= end) - break; - buf = print_binder_transaction_log_entry(buf, end, - &log->entry[i]); - } - - *start = page + off; - - len = buf - page; - if (len > off) - len -= off; - else - len = 0; - - return len < count ? len : count; -} - -static const struct file_operations binder_fops = { - .owner = THIS_MODULE, - .poll = binder_poll, - .unlocked_ioctl = binder_ioctl, - .mmap = binder_mmap, - .open = binder_open, - .flush = binder_flush, - .release = binder_release, -}; - -static struct miscdevice binder_miscdev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "binder", - .fops = &binder_fops -}; - -static int __init binder_init(void) -{ - int ret; - - binder_proc_dir_entry_root = proc_mkdir("binder", NULL); - if (binder_proc_dir_entry_root) - binder_proc_dir_entry_proc = proc_mkdir("proc", - binder_proc_dir_entry_root); - ret = misc_register(&binder_miscdev); - if (binder_proc_dir_entry_root) { - create_proc_read_entry("state", - S_IRUGO, - binder_proc_dir_entry_root, - binder_read_proc_state, - NULL); - create_proc_read_entry("stats", - S_IRUGO, - binder_proc_dir_entry_root, - binder_read_proc_stats, - NULL); - create_proc_read_entry("transactions", - S_IRUGO, - binder_proc_dir_entry_root, - binder_read_proc_transactions, - NULL); - create_proc_read_entry("transaction_log", - S_IRUGO, - binder_proc_dir_entry_root, - binder_read_proc_transaction_log, - &binder_transaction_log); - create_proc_read_entry("failed_transaction_log", - S_IRUGO, - binder_proc_dir_entry_root, - binder_read_proc_transaction_log, - &binder_transaction_log_failed); - } - return ret; -} - -device_initcall(binder_init); - -MODULE_LICENSE("GPL v2"); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/android/binder.h linux-2.6.32-rc6-staging/drivers/staging/android/binder.h --- linux-2.6.32-rc6/drivers/staging/android/binder.h 2009-03-23 16:12:14.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/android/binder.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,330 +0,0 @@ -/* - * Copyright (C) 2008 Google, Inc. - * - * Based on, but no longer compatible with, the original - * OpenBinder.org binder driver interface, which is: - * - * Copyright (c) 2005 Palmsource, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _LINUX_BINDER_H -#define _LINUX_BINDER_H - -#include - -#define B_PACK_CHARS(c1, c2, c3, c4) \ - ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) -#define B_TYPE_LARGE 0x85 - -enum { - BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE), - BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE), - BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE), - BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE), - BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE), -}; - -enum { - FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff, - FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100, -}; - -/* - * This is the flattened representation of a Binder object for transfer - * between processes. The 'offsets' supplied as part of a binder transaction - * contains offsets into the data where these structures occur. The Binder - * driver takes care of re-writing the structure type and data as it moves - * between processes. - */ -struct flat_binder_object { - /* 8 bytes for large_flat_header. */ - unsigned long type; - unsigned long flags; - - /* 8 bytes of data. */ - union { - void *binder; /* local object */ - signed long handle; /* remote object */ - }; - - /* extra data associated with local object */ - void *cookie; -}; - -/* - * On 64-bit platforms where user code may run in 32-bits the driver must - * translate the buffer (and local binder) addresses apropriately. - */ - -struct binder_write_read { - signed long write_size; /* bytes to write */ - signed long write_consumed; /* bytes consumed by driver */ - unsigned long write_buffer; - signed long read_size; /* bytes to read */ - signed long read_consumed; /* bytes consumed by driver */ - unsigned long read_buffer; -}; - -/* Use with BINDER_VERSION, driver fills in fields. */ -struct binder_version { - /* driver protocol version -- increment with incompatible change */ - signed long protocol_version; -}; - -/* This is the current protocol version. */ -#define BINDER_CURRENT_PROTOCOL_VERSION 7 - -#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read) -#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, int64_t) -#define BINDER_SET_MAX_THREADS _IOW('b', 5, size_t) -#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, int) -#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, int) -#define BINDER_THREAD_EXIT _IOW('b', 8, int) -#define BINDER_VERSION _IOWR('b', 9, struct binder_version) - -/* - * NOTE: Two special error codes you should check for when calling - * in to the driver are: - * - * EINTR -- The operation has been interupted. This should be - * handled by retrying the ioctl() until a different error code - * is returned. - * - * ECONNREFUSED -- The driver is no longer accepting operations - * from your process. That is, the process is being destroyed. - * You should handle this by exiting from your process. Note - * that once this error code is returned, all further calls to - * the driver from any thread will return this same code. - */ - -enum transaction_flags { - TF_ONE_WAY = 0x01, /* this is a one-way call: async, no return */ - TF_ROOT_OBJECT = 0x04, /* contents are the component's root object */ - TF_STATUS_CODE = 0x08, /* contents are a 32-bit status code */ - TF_ACCEPT_FDS = 0x10, /* allow replies with file descriptors */ -}; - -struct binder_transaction_data { - /* The first two are only used for bcTRANSACTION and brTRANSACTION, - * identifying the target and contents of the transaction. - */ - union { - size_t handle; /* target descriptor of command transaction */ - void *ptr; /* target descriptor of return transaction */ - } target; - void *cookie; /* target object cookie */ - unsigned int code; /* transaction command */ - - /* General information about the transaction. */ - unsigned int flags; - pid_t sender_pid; - uid_t sender_euid; - size_t data_size; /* number of bytes of data */ - size_t offsets_size; /* number of bytes of offsets */ - - /* If this transaction is inline, the data immediately - * follows here; otherwise, it ends with a pointer to - * the data buffer. - */ - union { - struct { - /* transaction data */ - const void *buffer; - /* offsets from buffer to flat_binder_object structs */ - const void *offsets; - } ptr; - uint8_t buf[8]; - } data; -}; - -struct binder_ptr_cookie { - void *ptr; - void *cookie; -}; - -struct binder_pri_desc { - int priority; - int desc; -}; - -struct binder_pri_ptr_cookie { - int priority; - void *ptr; - void *cookie; -}; - -enum BinderDriverReturnProtocol { - BR_ERROR = _IOR('r', 0, int), - /* - * int: error code - */ - - BR_OK = _IO('r', 1), - /* No parameters! */ - - BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data), - BR_REPLY = _IOR('r', 3, struct binder_transaction_data), - /* - * binder_transaction_data: the received command. - */ - - BR_ACQUIRE_RESULT = _IOR('r', 4, int), - /* - * not currently supported - * int: 0 if the last bcATTEMPT_ACQUIRE was not successful. - * Else the remote object has acquired a primary reference. - */ - - BR_DEAD_REPLY = _IO('r', 5), - /* - * The target of the last transaction (either a bcTRANSACTION or - * a bcATTEMPT_ACQUIRE) is no longer with us. No parameters. - */ - - BR_TRANSACTION_COMPLETE = _IO('r', 6), - /* - * No parameters... always refers to the last transaction requested - * (including replies). Note that this will be sent even for - * asynchronous transactions. - */ - - BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie), - BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie), - BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie), - BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie for binder - */ - - BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie), - /* - * not currently supported - * int: priority - * void *: ptr to binder - * void *: cookie for binder - */ - - BR_NOOP = _IO('r', 12), - /* - * No parameters. Do nothing and examine the next command. It exists - * primarily so that we can replace it with a BR_SPAWN_LOOPER command. - */ - - BR_SPAWN_LOOPER = _IO('r', 13), - /* - * No parameters. The driver has determined that a process has no - * threads waiting to service incomming transactions. When a process - * receives this command, it must spawn a new service thread and - * register it via bcENTER_LOOPER. - */ - - BR_FINISHED = _IO('r', 14), - /* - * not currently supported - * stop threadpool thread - */ - - BR_DEAD_BINDER = _IOR('r', 15, void *), - /* - * void *: cookie - */ - BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, void *), - /* - * void *: cookie - */ - - BR_FAILED_REPLY = _IO('r', 17), - /* - * The the last transaction (either a bcTRANSACTION or - * a bcATTEMPT_ACQUIRE) failed (e.g. out of memory). No parameters. - */ -}; - -enum BinderDriverCommandProtocol { - BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data), - BC_REPLY = _IOW('c', 1, struct binder_transaction_data), - /* - * binder_transaction_data: the sent command. - */ - - BC_ACQUIRE_RESULT = _IOW('c', 2, int), - /* - * not currently supported - * int: 0 if the last BR_ATTEMPT_ACQUIRE was not successful. - * Else you have acquired a primary reference on the object. - */ - - BC_FREE_BUFFER = _IOW('c', 3, int), - /* - * void *: ptr to transaction data received on a read - */ - - BC_INCREFS = _IOW('c', 4, int), - BC_ACQUIRE = _IOW('c', 5, int), - BC_RELEASE = _IOW('c', 6, int), - BC_DECREFS = _IOW('c', 7, int), - /* - * int: descriptor - */ - - BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie), - BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie for binder - */ - - BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc), - /* - * not currently supported - * int: priority - * int: descriptor - */ - - BC_REGISTER_LOOPER = _IO('c', 11), - /* - * No parameters. - * Register a spawned looper thread with the device. - */ - - BC_ENTER_LOOPER = _IO('c', 12), - BC_EXIT_LOOPER = _IO('c', 13), - /* - * No parameters. - * These two commands are sent as an application-level thread - * enters and exits the binder loop, respectively. They are - * used so the binder can have an accurate count of the number - * of looping threads it has available. - */ - - BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie - */ - - BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_ptr_cookie), - /* - * void *: ptr to binder - * void *: cookie - */ - - BC_DEAD_BINDER_DONE = _IOW('c', 16, void *), - /* - * void *: cookie - */ -}; - -#endif /* _LINUX_BINDER_H */ - diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/android/Kconfig linux-2.6.32-rc6-staging/drivers/staging/android/Kconfig --- linux-2.6.32-rc6/drivers/staging/android/Kconfig 2009-11-04 15:20:32.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/android/Kconfig 1969-12-31 16:00:00.000000000 -0800 @@ -1,96 +0,0 @@ -menu "Android" - -config ANDROID - bool "Android Drivers" - depends on BROKEN - default N - ---help--- - Enable support for various drivers needed on the Android platform - -if ANDROID - -config ANDROID_BINDER_IPC - bool "Android Binder IPC Driver" - default n - -config ANDROID_LOGGER - tristate "Android log driver" - default n - -config ANDROID_RAM_CONSOLE - bool "Android RAM buffer console" - default n - -config ANDROID_RAM_CONSOLE_ENABLE_VERBOSE - bool "Enable verbose console messages on Android RAM console" - default y - depends on ANDROID_RAM_CONSOLE - -menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION - bool "Android RAM Console Enable error correction" - default n - depends on ANDROID_RAM_CONSOLE - depends on !ANDROID_RAM_CONSOLE_EARLY_INIT - select REED_SOLOMON - select REED_SOLOMON_ENC8 - select REED_SOLOMON_DEC8 - -if ANDROID_RAM_CONSOLE_ERROR_CORRECTION - -config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE - int "Android RAM Console Data data size" - default 128 - help - Must be a power of 2. - -config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE - int "Android RAM Console ECC size" - default 16 - -config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE - int "Android RAM Console Symbol size" - default 8 - -config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL - hex "Android RAM Console Polynomial" - default 0x19 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 4) - default 0x29 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 5) - default 0x61 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 6) - default 0x89 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 7) - default 0x11d if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 8) - -endif # ANDROID_RAM_CONSOLE_ERROR_CORRECTION - -config ANDROID_RAM_CONSOLE_EARLY_INIT - bool "Start Android RAM console early" - default n - depends on ANDROID_RAM_CONSOLE - -config ANDROID_RAM_CONSOLE_EARLY_ADDR - hex "Android RAM console virtual address" - default 0 - depends on ANDROID_RAM_CONSOLE_EARLY_INIT - -config ANDROID_RAM_CONSOLE_EARLY_SIZE - hex "Android RAM console buffer size" - default 0 - depends on ANDROID_RAM_CONSOLE_EARLY_INIT - -config ANDROID_TIMED_OUTPUT - bool "Timed output class driver" - default y - -config ANDROID_TIMED_GPIO - tristate "Android timed gpio driver" - depends on GENERIC_GPIO && ANDROID_TIMED_OUTPUT - default n - -config ANDROID_LOW_MEMORY_KILLER - bool "Android Low Memory Killer" - default N - ---help--- - Register processes to be killed when memory is low - -endif # if ANDROID - -endmenu diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/android/logger.c linux-2.6.32-rc6-staging/drivers/staging/android/logger.c --- linux-2.6.32-rc6/drivers/staging/android/logger.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/android/logger.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,607 +0,0 @@ -/* - * drivers/misc/logger.c - * - * A Logging Subsystem - * - * Copyright (C) 2007-2008 Google, Inc. - * - * Robert Love - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include "logger.h" - -#include - -/* - * struct logger_log - represents a specific log, such as 'main' or 'radio' - * - * This structure lives from module insertion until module removal, so it does - * not need additional reference counting. The structure is protected by the - * mutex 'mutex'. - */ -struct logger_log { - unsigned char *buffer;/* the ring buffer itself */ - struct miscdevice misc; /* misc device representing the log */ - wait_queue_head_t wq; /* wait queue for readers */ - struct list_head readers; /* this log's readers */ - struct mutex mutex; /* mutex protecting buffer */ - size_t w_off; /* current write head offset */ - size_t head; /* new readers start here */ - size_t size; /* size of the log */ -}; - -/* - * struct logger_reader - a logging device open for reading - * - * This object lives from open to release, so we don't need additional - * reference counting. The structure is protected by log->mutex. - */ -struct logger_reader { - struct logger_log *log; /* associated log */ - struct list_head list; /* entry in logger_log's list */ - size_t r_off; /* current read head offset */ -}; - -/* logger_offset - returns index 'n' into the log via (optimized) modulus */ -#define logger_offset(n) ((n) & (log->size - 1)) - -/* - * file_get_log - Given a file structure, return the associated log - * - * This isn't aesthetic. We have several goals: - * - * 1) Need to quickly obtain the associated log during an I/O operation - * 2) Readers need to maintain state (logger_reader) - * 3) Writers need to be very fast (open() should be a near no-op) - * - * In the reader case, we can trivially go file->logger_reader->logger_log. - * For a writer, we don't want to maintain a logger_reader, so we just go - * file->logger_log. Thus what file->private_data points at depends on whether - * or not the file was opened for reading. This function hides that dirtiness. - */ -static inline struct logger_log *file_get_log(struct file *file) -{ - if (file->f_mode & FMODE_READ) { - struct logger_reader *reader = file->private_data; - return reader->log; - } else - return file->private_data; -} - -/* - * get_entry_len - Grabs the length of the payload of the next entry starting - * from 'off'. - * - * Caller needs to hold log->mutex. - */ -static __u32 get_entry_len(struct logger_log *log, size_t off) -{ - __u16 val; - - switch (log->size - off) { - case 1: - memcpy(&val, log->buffer + off, 1); - memcpy(((char *) &val) + 1, log->buffer, 1); - break; - default: - memcpy(&val, log->buffer + off, 2); - } - - return sizeof(struct logger_entry) + val; -} - -/* - * do_read_log_to_user - reads exactly 'count' bytes from 'log' into the - * user-space buffer 'buf'. Returns 'count' on success. - * - * Caller must hold log->mutex. - */ -static ssize_t do_read_log_to_user(struct logger_log *log, - struct logger_reader *reader, - char __user *buf, - size_t count) -{ - size_t len; - - /* - * We read from the log in two disjoint operations. First, we read from - * the current read head offset up to 'count' bytes or to the end of - * the log, whichever comes first. - */ - len = min(count, log->size - reader->r_off); - if (copy_to_user(buf, log->buffer + reader->r_off, len)) - return -EFAULT; - - /* - * Second, we read any remaining bytes, starting back at the head of - * the log. - */ - if (count != len) - if (copy_to_user(buf + len, log->buffer, count - len)) - return -EFAULT; - - reader->r_off = logger_offset(reader->r_off + count); - - return count; -} - -/* - * logger_read - our log's read() method - * - * Behavior: - * - * - O_NONBLOCK works - * - If there are no log entries to read, blocks until log is written to - * - Atomically reads exactly one log entry - * - * Optimal read size is LOGGER_ENTRY_MAX_LEN. Will set errno to EINVAL if read - * buffer is insufficient to hold next entry. - */ -static ssize_t logger_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct logger_reader *reader = file->private_data; - struct logger_log *log = reader->log; - ssize_t ret; - DEFINE_WAIT(wait); - -start: - while (1) { - prepare_to_wait(&log->wq, &wait, TASK_INTERRUPTIBLE); - - mutex_lock(&log->mutex); - ret = (log->w_off == reader->r_off); - mutex_unlock(&log->mutex); - if (!ret) - break; - - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; - } - - if (signal_pending(current)) { - ret = -EINTR; - break; - } - - schedule(); - } - - finish_wait(&log->wq, &wait); - if (ret) - return ret; - - mutex_lock(&log->mutex); - - /* is there still something to read or did we race? */ - if (unlikely(log->w_off == reader->r_off)) { - mutex_unlock(&log->mutex); - goto start; - } - - /* get the size of the next entry */ - ret = get_entry_len(log, reader->r_off); - if (count < ret) { - ret = -EINVAL; - goto out; - } - - /* get exactly one entry from the log */ - ret = do_read_log_to_user(log, reader, buf, ret); - -out: - mutex_unlock(&log->mutex); - - return ret; -} - -/* - * get_next_entry - return the offset of the first valid entry at least 'len' - * bytes after 'off'. - * - * Caller must hold log->mutex. - */ -static size_t get_next_entry(struct logger_log *log, size_t off, size_t len) -{ - size_t count = 0; - - do { - size_t nr = get_entry_len(log, off); - off = logger_offset(off + nr); - count += nr; - } while (count < len); - - return off; -} - -/* - * clock_interval - is a < c < b in mod-space? Put another way, does the line - * from a to b cross c? - */ -static inline int clock_interval(size_t a, size_t b, size_t c) -{ - if (b < a) { - if (a < c || b >= c) - return 1; - } else { - if (a < c && b >= c) - return 1; - } - - return 0; -} - -/* - * fix_up_readers - walk the list of all readers and "fix up" any who were - * lapped by the writer; also do the same for the default "start head". - * We do this by "pulling forward" the readers and start head to the first - * entry after the new write head. - * - * The caller needs to hold log->mutex. - */ -static void fix_up_readers(struct logger_log *log, size_t len) -{ - size_t old = log->w_off; - size_t new = logger_offset(old + len); - struct logger_reader *reader; - - if (clock_interval(old, new, log->head)) - log->head = get_next_entry(log, log->head, len); - - list_for_each_entry(reader, &log->readers, list) - if (clock_interval(old, new, reader->r_off)) - reader->r_off = get_next_entry(log, reader->r_off, len); -} - -/* - * do_write_log - writes 'len' bytes from 'buf' to 'log' - * - * The caller needs to hold log->mutex. - */ -static void do_write_log(struct logger_log *log, const void *buf, size_t count) -{ - size_t len; - - len = min(count, log->size - log->w_off); - memcpy(log->buffer + log->w_off, buf, len); - - if (count != len) - memcpy(log->buffer, buf + len, count - len); - - log->w_off = logger_offset(log->w_off + count); - -} - -/* - * do_write_log_user - writes 'len' bytes from the user-space buffer 'buf' to - * the log 'log' - * - * The caller needs to hold log->mutex. - * - * Returns 'count' on success, negative error code on failure. - */ -static ssize_t do_write_log_from_user(struct logger_log *log, - const void __user *buf, size_t count) -{ - size_t len; - - len = min(count, log->size - log->w_off); - if (len && copy_from_user(log->buffer + log->w_off, buf, len)) - return -EFAULT; - - if (count != len) - if (copy_from_user(log->buffer, buf + len, count - len)) - return -EFAULT; - - log->w_off = logger_offset(log->w_off + count); - - return count; -} - -/* - * logger_aio_write - our write method, implementing support for write(), - * writev(), and aio_write(). Writes are our fast path, and we try to optimize - * them above all else. - */ -ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t ppos) -{ - struct logger_log *log = file_get_log(iocb->ki_filp); - size_t orig = log->w_off; - struct logger_entry header; - struct timespec now; - ssize_t ret = 0; - - now = current_kernel_time(); - - header.pid = current->tgid; - header.tid = current->pid; - header.sec = now.tv_sec; - header.nsec = now.tv_nsec; - header.len = min_t(size_t, iocb->ki_left, LOGGER_ENTRY_MAX_PAYLOAD); - - /* null writes succeed, return zero */ - if (unlikely(!header.len)) - return 0; - - mutex_lock(&log->mutex); - - /* - * Fix up any readers, pulling them forward to the first readable - * entry after (what will be) the new write offset. We do this now - * because if we partially fail, we can end up with clobbered log - * entries that encroach on readable buffer. - */ - fix_up_readers(log, sizeof(struct logger_entry) + header.len); - - do_write_log(log, &header, sizeof(struct logger_entry)); - - while (nr_segs-- > 0) { - size_t len; - ssize_t nr; - - /* figure out how much of this vector we can keep */ - len = min_t(size_t, iov->iov_len, header.len - ret); - - /* write out this segment's payload */ - nr = do_write_log_from_user(log, iov->iov_base, len); - if (unlikely(nr < 0)) { - log->w_off = orig; - mutex_unlock(&log->mutex); - return nr; - } - - iov++; - ret += nr; - } - - mutex_unlock(&log->mutex); - - /* wake up any blocked readers */ - wake_up_interruptible(&log->wq); - - return ret; -} - -static struct logger_log *get_log_from_minor(int); - -/* - * logger_open - the log's open() file operation - * - * Note how near a no-op this is in the write-only case. Keep it that way! - */ -static int logger_open(struct inode *inode, struct file *file) -{ - struct logger_log *log; - int ret; - - ret = nonseekable_open(inode, file); - if (ret) - return ret; - - log = get_log_from_minor(MINOR(inode->i_rdev)); - if (!log) - return -ENODEV; - - if (file->f_mode & FMODE_READ) { - struct logger_reader *reader; - - reader = kmalloc(sizeof(struct logger_reader), GFP_KERNEL); - if (!reader) - return -ENOMEM; - - reader->log = log; - INIT_LIST_HEAD(&reader->list); - - mutex_lock(&log->mutex); - reader->r_off = log->head; - list_add_tail(&reader->list, &log->readers); - mutex_unlock(&log->mutex); - - file->private_data = reader; - } else - file->private_data = log; - - return 0; -} - -/* - * logger_release - the log's release file operation - * - * Note this is a total no-op in the write-only case. Keep it that way! - */ -static int logger_release(struct inode *ignored, struct file *file) -{ - if (file->f_mode & FMODE_READ) { - struct logger_reader *reader = file->private_data; - list_del(&reader->list); - kfree(reader); - } - - return 0; -} - -/* - * logger_poll - the log's poll file operation, for poll/select/epoll - * - * Note we always return POLLOUT, because you can always write() to the log. - * Note also that, strictly speaking, a return value of POLLIN does not - * guarantee that the log is readable without blocking, as there is a small - * chance that the writer can lap the reader in the interim between poll() - * returning and the read() request. - */ -static unsigned int logger_poll(struct file *file, poll_table *wait) -{ - struct logger_reader *reader; - struct logger_log *log; - unsigned int ret = POLLOUT | POLLWRNORM; - - if (!(file->f_mode & FMODE_READ)) - return ret; - - reader = file->private_data; - log = reader->log; - - poll_wait(file, &log->wq, wait); - - mutex_lock(&log->mutex); - if (log->w_off != reader->r_off) - ret |= POLLIN | POLLRDNORM; - mutex_unlock(&log->mutex); - - return ret; -} - -static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct logger_log *log = file_get_log(file); - struct logger_reader *reader; - long ret = -ENOTTY; - - mutex_lock(&log->mutex); - - switch (cmd) { - case LOGGER_GET_LOG_BUF_SIZE: - ret = log->size; - break; - case LOGGER_GET_LOG_LEN: - if (!(file->f_mode & FMODE_READ)) { - ret = -EBADF; - break; - } - reader = file->private_data; - if (log->w_off >= reader->r_off) - ret = log->w_off - reader->r_off; - else - ret = (log->size - reader->r_off) + log->w_off; - break; - case LOGGER_GET_NEXT_ENTRY_LEN: - if (!(file->f_mode & FMODE_READ)) { - ret = -EBADF; - break; - } - reader = file->private_data; - if (log->w_off != reader->r_off) - ret = get_entry_len(log, reader->r_off); - else - ret = 0; - break; - case LOGGER_FLUSH_LOG: - if (!(file->f_mode & FMODE_WRITE)) { - ret = -EBADF; - break; - } - list_for_each_entry(reader, &log->readers, list) - reader->r_off = log->w_off; - log->head = log->w_off; - ret = 0; - break; - } - - mutex_unlock(&log->mutex); - - return ret; -} - -static const struct file_operations logger_fops = { - .owner = THIS_MODULE, - .read = logger_read, - .aio_write = logger_aio_write, - .poll = logger_poll, - .unlocked_ioctl = logger_ioctl, - .compat_ioctl = logger_ioctl, - .open = logger_open, - .release = logger_release, -}; - -/* - * Defines a log structure with name 'NAME' and a size of 'SIZE' bytes, which - * must be a power of two, greater than LOGGER_ENTRY_MAX_LEN, and less than - * LONG_MAX minus LOGGER_ENTRY_MAX_LEN. - */ -#define DEFINE_LOGGER_DEVICE(VAR, NAME, SIZE) \ -static unsigned char _buf_ ## VAR[SIZE]; \ -static struct logger_log VAR = { \ - .buffer = _buf_ ## VAR, \ - .misc = { \ - .minor = MISC_DYNAMIC_MINOR, \ - .name = NAME, \ - .fops = &logger_fops, \ - .parent = NULL, \ - }, \ - .wq = __WAIT_QUEUE_HEAD_INITIALIZER(VAR .wq), \ - .readers = LIST_HEAD_INIT(VAR .readers), \ - .mutex = __MUTEX_INITIALIZER(VAR .mutex), \ - .w_off = 0, \ - .head = 0, \ - .size = SIZE, \ -}; - -DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 64*1024) -DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024) -DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 64*1024) - -static struct logger_log *get_log_from_minor(int minor) -{ - if (log_main.misc.minor == minor) - return &log_main; - if (log_events.misc.minor == minor) - return &log_events; - if (log_radio.misc.minor == minor) - return &log_radio; - return NULL; -} - -static int __init init_log(struct logger_log *log) -{ - int ret; - - ret = misc_register(&log->misc); - if (unlikely(ret)) { - printk(KERN_ERR "logger: failed to register misc " - "device for log '%s'!\n", log->misc.name); - return ret; - } - - printk(KERN_INFO "logger: created %luK log '%s'\n", - (unsigned long) log->size >> 10, log->misc.name); - - return 0; -} - -static int __init logger_init(void) -{ - int ret; - - ret = init_log(&log_main); - if (unlikely(ret)) - goto out; - - ret = init_log(&log_events); - if (unlikely(ret)) - goto out; - - ret = init_log(&log_radio); - if (unlikely(ret)) - goto out; - -out: - return ret; -} -device_initcall(logger_init); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/android/logger.h linux-2.6.32-rc6-staging/drivers/staging/android/logger.h --- linux-2.6.32-rc6/drivers/staging/android/logger.h 2009-03-23 16:12:14.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/android/logger.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,48 +0,0 @@ -/* include/linux/logger.h - * - * Copyright (C) 2007-2008 Google, Inc. - * Author: Robert Love - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _LINUX_LOGGER_H -#define _LINUX_LOGGER_H - -#include -#include - -struct logger_entry { - __u16 len; /* length of the payload */ - __u16 __pad; /* no matter what, we get 2 bytes of padding */ - __s32 pid; /* generating process's pid */ - __s32 tid; /* generating process's tid */ - __s32 sec; /* seconds since Epoch */ - __s32 nsec; /* nanoseconds */ - char msg[0]; /* the entry's payload */ -}; - -#define LOGGER_LOG_RADIO "log_radio" /* radio-related messages */ -#define LOGGER_LOG_EVENTS "log_events" /* system/hardware events */ -#define LOGGER_LOG_MAIN "log_main" /* everything else */ - -#define LOGGER_ENTRY_MAX_LEN (4*1024) -#define LOGGER_ENTRY_MAX_PAYLOAD \ - (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry)) - -#define __LOGGERIO 0xAE - -#define LOGGER_GET_LOG_BUF_SIZE _IO(__LOGGERIO, 1) /* size of log */ -#define LOGGER_GET_LOG_LEN _IO(__LOGGERIO, 2) /* used log len */ -#define LOGGER_GET_NEXT_ENTRY_LEN _IO(__LOGGERIO, 3) /* next entry len */ -#define LOGGER_FLUSH_LOG _IO(__LOGGERIO, 4) /* flush log */ - -#endif /* _LINUX_LOGGER_H */ diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/android/lowmemorykiller.c linux-2.6.32-rc6-staging/drivers/staging/android/lowmemorykiller.c --- linux-2.6.32-rc6/drivers/staging/android/lowmemorykiller.c 2009-11-04 15:20:32.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/android/lowmemorykiller.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,173 +0,0 @@ -/* drivers/misc/lowmemorykiller.c - * - * The lowmemorykiller driver lets user-space specify a set of memory thresholds - * where processes with a range of oom_adj values will get killed. Specify the - * minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the - * number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both - * files take a comma separated list of numbers in ascending order. - * - * For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and - * "1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes - * with a oom_adj value of 8 or higher when the free memory drops below 4096 pages - * and kill processes with a oom_adj value of 0 or higher when the free memory - * drops below 1024 pages. - * - * The driver considers memory used for caches to be free, but if a large - * percentage of the cached memory is locked this can be very inaccurate - * and processes may not get killed until the normal oom killer is triggered. - * - * Copyright (C) 2007-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -static uint32_t lowmem_debug_level = 2; -static int lowmem_adj[6] = { - 0, - 1, - 6, - 12, -}; -static int lowmem_adj_size = 4; -static size_t lowmem_minfree[6] = { - 3 * 512, /* 6MB */ - 2 * 1024, /* 8MB */ - 4 * 1024, /* 16MB */ - 16 * 1024, /* 64MB */ -}; -static int lowmem_minfree_size = 4; - -#define lowmem_print(level, x...) \ - do { \ - if (lowmem_debug_level >= (level)) \ - printk(x); \ - } while (0) - -static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask) -{ - struct task_struct *p; - struct task_struct *selected = NULL; - int rem = 0; - int tasksize; - int i; - int min_adj = OOM_ADJUST_MAX + 1; - int selected_tasksize = 0; - int selected_oom_adj; - int array_size = ARRAY_SIZE(lowmem_adj); - int other_free = global_page_state(NR_FREE_PAGES); - int other_file = global_page_state(NR_FILE_PAGES); - - if (lowmem_adj_size < array_size) - array_size = lowmem_adj_size; - if (lowmem_minfree_size < array_size) - array_size = lowmem_minfree_size; - for (i = 0; i < array_size; i++) { - if (other_free < lowmem_minfree[i] && - other_file < lowmem_minfree[i]) { - min_adj = lowmem_adj[i]; - break; - } - } - if (nr_to_scan > 0) - lowmem_print(3, "lowmem_shrink %d, %x, ofree %d %d, ma %d\n", - nr_to_scan, gfp_mask, other_free, other_file, - min_adj); - rem = global_page_state(NR_ACTIVE_ANON) + - global_page_state(NR_ACTIVE_FILE) + - global_page_state(NR_INACTIVE_ANON) + - global_page_state(NR_INACTIVE_FILE); - if (nr_to_scan <= 0 || min_adj == OOM_ADJUST_MAX + 1) { - lowmem_print(5, "lowmem_shrink %d, %x, return %d\n", - nr_to_scan, gfp_mask, rem); - return rem; - } - selected_oom_adj = min_adj; - - read_lock(&tasklist_lock); - for_each_process(p) { - struct mm_struct *mm; - int oom_adj; - - task_lock(p); - mm = p->mm; - if (!mm) { - task_unlock(p); - continue; - } - oom_adj = mm->oom_adj; - if (oom_adj < min_adj) { - task_unlock(p); - continue; - } - tasksize = get_mm_rss(mm); - task_unlock(p); - if (tasksize <= 0) - continue; - if (selected) { - if (oom_adj < selected_oom_adj) - continue; - if (oom_adj == selected_oom_adj && - tasksize <= selected_tasksize) - continue; - } - selected = p; - selected_tasksize = tasksize; - selected_oom_adj = oom_adj; - lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n", - p->pid, p->comm, oom_adj, tasksize); - } - if (selected) { - lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", - selected->pid, selected->comm, - selected_oom_adj, selected_tasksize); - force_sig(SIGKILL, selected); - rem -= selected_tasksize; - } - lowmem_print(4, "lowmem_shrink %d, %x, return %d\n", - nr_to_scan, gfp_mask, rem); - read_unlock(&tasklist_lock); - return rem; -} - -static struct shrinker lowmem_shrinker = { - .shrink = lowmem_shrink, - .seeks = DEFAULT_SEEKS * 16 -}; - -static int __init lowmem_init(void) -{ - register_shrinker(&lowmem_shrinker); - return 0; -} - -static void __exit lowmem_exit(void) -{ - unregister_shrinker(&lowmem_shrinker); -} - -module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR); -module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size, - S_IRUGO | S_IWUSR); -module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size, - S_IRUGO | S_IWUSR); -module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR); - -module_init(lowmem_init); -module_exit(lowmem_exit); - -MODULE_LICENSE("GPL"); - diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/android/Makefile linux-2.6.32-rc6-staging/drivers/staging/android/Makefile --- linux-2.6.32-rc6/drivers/staging/android/Makefile 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/android/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,6 +0,0 @@ -obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o -obj-$(CONFIG_ANDROID_LOGGER) += logger.o -obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o -obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o -obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o -obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/android/ram_console.c linux-2.6.32-rc6-staging/drivers/staging/android/ram_console.c --- linux-2.6.32-rc6/drivers/staging/android/ram_console.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/android/ram_console.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,410 +0,0 @@ -/* drivers/android/ram_console.c - * - * Copyright (C) 2007-2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -#include -#endif - -struct ram_console_buffer { - uint32_t sig; - uint32_t start; - uint32_t size; - uint8_t data[0]; -}; - -#define RAM_CONSOLE_SIG (0x43474244) /* DBGC */ - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT -static char __initdata - ram_console_old_log_init_buffer[CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE]; -#endif -static char *ram_console_old_log; -static size_t ram_console_old_log_size; - -static struct ram_console_buffer *ram_console_buffer; -static size_t ram_console_buffer_size; -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -static char *ram_console_par_buffer; -static struct rs_control *ram_console_rs_decoder; -static int ram_console_corrected_bytes; -static int ram_console_bad_blocks; -#define ECC_BLOCK_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE -#define ECC_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE -#define ECC_SYMSIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE -#define ECC_POLY CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL -#endif - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -static void ram_console_encode_rs8(uint8_t *data, size_t len, uint8_t *ecc) -{ - int i; - uint16_t par[ECC_SIZE]; - /* Initialize the parity buffer */ - memset(par, 0, sizeof(par)); - encode_rs8(ram_console_rs_decoder, data, len, par, 0); - for (i = 0; i < ECC_SIZE; i++) - ecc[i] = par[i]; -} - -static int ram_console_decode_rs8(void *data, size_t len, uint8_t *ecc) -{ - int i; - uint16_t par[ECC_SIZE]; - for (i = 0; i < ECC_SIZE; i++) - par[i] = ecc[i]; - return decode_rs8(ram_console_rs_decoder, data, par, len, - NULL, 0, NULL, 0, NULL); -} -#endif - -static void ram_console_update(const char *s, unsigned int count) -{ - struct ram_console_buffer *buffer = ram_console_buffer; -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - uint8_t *buffer_end = buffer->data + ram_console_buffer_size; - uint8_t *block; - uint8_t *par; - int size = ECC_BLOCK_SIZE; -#endif - memcpy(buffer->data + buffer->start, s, count); -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - block = buffer->data + (buffer->start & ~(ECC_BLOCK_SIZE - 1)); - par = ram_console_par_buffer + - (buffer->start / ECC_BLOCK_SIZE) * ECC_SIZE; - do { - if (block + ECC_BLOCK_SIZE > buffer_end) - size = buffer_end - block; - ram_console_encode_rs8(block, size, par); - block += ECC_BLOCK_SIZE; - par += ECC_SIZE; - } while (block < buffer->data + buffer->start + count); -#endif -} - -static void ram_console_update_header(void) -{ -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - struct ram_console_buffer *buffer = ram_console_buffer; - uint8_t *par; - par = ram_console_par_buffer + - DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE; - ram_console_encode_rs8((uint8_t *)buffer, sizeof(*buffer), par); -#endif -} - -static void -ram_console_write(struct console *console, const char *s, unsigned int count) -{ - int rem; - struct ram_console_buffer *buffer = ram_console_buffer; - - if (count > ram_console_buffer_size) { - s += count - ram_console_buffer_size; - count = ram_console_buffer_size; - } - rem = ram_console_buffer_size - buffer->start; - if (rem < count) { - ram_console_update(s, rem); - s += rem; - count -= rem; - buffer->start = 0; - buffer->size = ram_console_buffer_size; - } - ram_console_update(s, count); - - buffer->start += count; - if (buffer->size < ram_console_buffer_size) - buffer->size += count; - ram_console_update_header(); -} - -static struct console ram_console = { - .name = "ram", - .write = ram_console_write, - .flags = CON_PRINTBUFFER | CON_ENABLED, - .index = -1, -}; - -static void __init -ram_console_save_old(struct ram_console_buffer *buffer, char *dest) -{ - size_t old_log_size = buffer->size; -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - uint8_t *block; - uint8_t *par; - char strbuf[80]; - int strbuf_len; - - block = buffer->data; - par = ram_console_par_buffer; - while (block < buffer->data + buffer->size) { - int numerr; - int size = ECC_BLOCK_SIZE; - if (block + size > buffer->data + ram_console_buffer_size) - size = buffer->data + ram_console_buffer_size - block; - numerr = ram_console_decode_rs8(block, size, par); - if (numerr > 0) { -#if 0 - printk(KERN_INFO "ram_console: error in block %p, %d\n", - block, numerr); -#endif - ram_console_corrected_bytes += numerr; - } else if (numerr < 0) { -#if 0 - printk(KERN_INFO "ram_console: uncorrectable error in " - "block %p\n", block); -#endif - ram_console_bad_blocks++; - } - block += ECC_BLOCK_SIZE; - par += ECC_SIZE; - } - if (ram_console_corrected_bytes || ram_console_bad_blocks) - strbuf_len = snprintf(strbuf, sizeof(strbuf), - "\n%d Corrected bytes, %d unrecoverable blocks\n", - ram_console_corrected_bytes, ram_console_bad_blocks); - else - strbuf_len = snprintf(strbuf, sizeof(strbuf), - "\nNo errors detected\n"); - if (strbuf_len >= sizeof(strbuf)) - strbuf_len = sizeof(strbuf) - 1; - old_log_size += strbuf_len; -#endif - - if (dest == NULL) { - dest = kmalloc(old_log_size, GFP_KERNEL); - if (dest == NULL) { - printk(KERN_ERR - "ram_console: failed to allocate buffer\n"); - return; - } - } - - ram_console_old_log = dest; - ram_console_old_log_size = old_log_size; - memcpy(ram_console_old_log, - &buffer->data[buffer->start], buffer->size - buffer->start); - memcpy(ram_console_old_log + buffer->size - buffer->start, - &buffer->data[0], buffer->start); -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - memcpy(ram_console_old_log + old_log_size - strbuf_len, - strbuf, strbuf_len); -#endif -} - -static int __init ram_console_init(struct ram_console_buffer *buffer, - size_t buffer_size, char *old_buf) -{ -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - int numerr; - uint8_t *par; -#endif - ram_console_buffer = buffer; - ram_console_buffer_size = - buffer_size - sizeof(struct ram_console_buffer); - - if (ram_console_buffer_size > buffer_size) { - pr_err("ram_console: buffer %p, invalid size %zu, " - "datasize %zu\n", buffer, buffer_size, - ram_console_buffer_size); - return 0; - } - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - ram_console_buffer_size -= (DIV_ROUND_UP(ram_console_buffer_size, - ECC_BLOCK_SIZE) + 1) * ECC_SIZE; - - if (ram_console_buffer_size > buffer_size) { - pr_err("ram_console: buffer %p, invalid size %zu, " - "non-ecc datasize %zu\n", - buffer, buffer_size, ram_console_buffer_size); - return 0; - } - - ram_console_par_buffer = buffer->data + ram_console_buffer_size; - - - /* first consecutive root is 0 - * primitive element to generate roots = 1 - */ - ram_console_rs_decoder = init_rs(ECC_SYMSIZE, ECC_POLY, 0, 1, ECC_SIZE); - if (ram_console_rs_decoder == NULL) { - printk(KERN_INFO "ram_console: init_rs failed\n"); - return 0; - } - - ram_console_corrected_bytes = 0; - ram_console_bad_blocks = 0; - - par = ram_console_par_buffer + - DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE; - - numerr = ram_console_decode_rs8(buffer, sizeof(*buffer), par); - if (numerr > 0) { - printk(KERN_INFO "ram_console: error in header, %d\n", numerr); - ram_console_corrected_bytes += numerr; - } else if (numerr < 0) { - printk(KERN_INFO - "ram_console: uncorrectable error in header\n"); - ram_console_bad_blocks++; - } -#endif - - if (buffer->sig == RAM_CONSOLE_SIG) { - if (buffer->size > ram_console_buffer_size - || buffer->start > buffer->size) - printk(KERN_INFO "ram_console: found existing invalid " - "buffer, size %d, start %d\n", - buffer->size, buffer->start); - else { - printk(KERN_INFO "ram_console: found existing buffer, " - "size %d, start %d\n", - buffer->size, buffer->start); - ram_console_save_old(buffer, old_buf); - } - } else { - printk(KERN_INFO "ram_console: no valid data in buffer " - "(sig = 0x%08x)\n", buffer->sig); - } - - buffer->sig = RAM_CONSOLE_SIG; - buffer->start = 0; - buffer->size = 0; - - register_console(&ram_console); -#ifdef CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE - console_verbose(); -#endif - return 0; -} - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT -static int __init ram_console_early_init(void) -{ - return ram_console_init((struct ram_console_buffer *) - CONFIG_ANDROID_RAM_CONSOLE_EARLY_ADDR, - CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE, - ram_console_old_log_init_buffer); -} -#else -static int ram_console_driver_probe(struct platform_device *pdev) -{ - struct resource *res = pdev->resource; - size_t start; - size_t buffer_size; - void *buffer; - - if (res == NULL || pdev->num_resources != 1 || - !(res->flags & IORESOURCE_MEM)) { - printk(KERN_ERR "ram_console: invalid resource, %p %d flags " - "%lx\n", res, pdev->num_resources, res ? res->flags : 0); - return -ENXIO; - } - buffer_size = res->end - res->start + 1; - start = res->start; - printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n", - start, buffer_size); - buffer = ioremap(res->start, buffer_size); - if (buffer == NULL) { - printk(KERN_ERR "ram_console: failed to map memory\n"); - return -ENOMEM; - } - - return ram_console_init(buffer, buffer_size, NULL/* allocate */); -} - -static struct platform_driver ram_console_driver = { - .probe = ram_console_driver_probe, - .driver = { - .name = "ram_console", - }, -}; - -static int __init ram_console_module_init(void) -{ - int err; - err = platform_driver_register(&ram_console_driver); - return err; -} -#endif - -static ssize_t ram_console_read_old(struct file *file, char __user *buf, - size_t len, loff_t *offset) -{ - loff_t pos = *offset; - ssize_t count; - - if (pos >= ram_console_old_log_size) - return 0; - - count = min(len, (size_t)(ram_console_old_log_size - pos)); - if (copy_to_user(buf, ram_console_old_log + pos, count)) - return -EFAULT; - - *offset += count; - return count; -} - -static const struct file_operations ram_console_file_ops = { - .owner = THIS_MODULE, - .read = ram_console_read_old, -}; - -static int __init ram_console_late_init(void) -{ - struct proc_dir_entry *entry; - - if (ram_console_old_log == NULL) - return 0; -#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT - ram_console_old_log = kmalloc(ram_console_old_log_size, GFP_KERNEL); - if (ram_console_old_log == NULL) { - printk(KERN_ERR - "ram_console: failed to allocate buffer for old log\n"); - ram_console_old_log_size = 0; - return 0; - } - memcpy(ram_console_old_log, - ram_console_old_log_init_buffer, ram_console_old_log_size); -#endif - entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL); - if (!entry) { - printk(KERN_ERR "ram_console: failed to create proc entry\n"); - kfree(ram_console_old_log); - ram_console_old_log = NULL; - return 0; - } - - entry->proc_fops = &ram_console_file_ops; - entry->size = ram_console_old_log_size; - return 0; -} - -#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT -console_initcall(ram_console_early_init); -#else -module_init(ram_console_module_init); -#endif -late_initcall(ram_console_late_init); - diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/android/timed_gpio.c linux-2.6.32-rc6-staging/drivers/staging/android/timed_gpio.c --- linux-2.6.32-rc6/drivers/staging/android/timed_gpio.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/android/timed_gpio.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,166 +0,0 @@ -/* drivers/misc/timed_gpio.c - * - * Copyright (C) 2008 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -#include "timed_output.h" -#include "timed_gpio.h" - - -struct timed_gpio_data { - struct timed_output_dev dev; - struct hrtimer timer; - spinlock_t lock; - unsigned gpio; - int max_timeout; - u8 active_low; -}; - -static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer) -{ - struct timed_gpio_data *data = - container_of(timer, struct timed_gpio_data, timer); - - gpio_direction_output(data->gpio, data->active_low ? 1 : 0); - return HRTIMER_NORESTART; -} - -static int gpio_get_time(struct timed_output_dev *dev) -{ - struct timed_gpio_data *data = - container_of(dev, struct timed_gpio_data, dev); - - if (hrtimer_active(&data->timer)) { - ktime_t r = hrtimer_get_remaining(&data->timer); - struct timeval t = ktime_to_timeval(r); - return t.tv_sec * 1000 + t.tv_usec / 1000; - } else - return 0; -} - -static void gpio_enable(struct timed_output_dev *dev, int value) -{ - struct timed_gpio_data *data = - container_of(dev, struct timed_gpio_data, dev); - unsigned long flags; - - spin_lock_irqsave(&data->lock, flags); - - /* cancel previous timer and set GPIO according to value */ - hrtimer_cancel(&data->timer); - gpio_direction_output(data->gpio, data->active_low ? !value : !!value); - - if (value > 0) { - if (value > data->max_timeout) - value = data->max_timeout; - - hrtimer_start(&data->timer, - ktime_set(value / 1000, (value % 1000) * 1000000), - HRTIMER_MODE_REL); - } - - spin_unlock_irqrestore(&data->lock, flags); -} - -static int timed_gpio_probe(struct platform_device *pdev) -{ - struct timed_gpio_platform_data *pdata = pdev->dev.platform_data; - struct timed_gpio *cur_gpio; - struct timed_gpio_data *gpio_data, *gpio_dat; - int i, j, ret = 0; - - if (!pdata) - return -EBUSY; - - gpio_data = kzalloc(sizeof(struct timed_gpio_data) * pdata->num_gpios, - GFP_KERNEL); - if (!gpio_data) - return -ENOMEM; - - for (i = 0; i < pdata->num_gpios; i++) { - cur_gpio = &pdata->gpios[i]; - gpio_dat = &gpio_data[i]; - - hrtimer_init(&gpio_dat->timer, CLOCK_MONOTONIC, - HRTIMER_MODE_REL); - gpio_dat->timer.function = gpio_timer_func; - spin_lock_init(&gpio_dat->lock); - - gpio_dat->dev.name = cur_gpio->name; - gpio_dat->dev.get_time = gpio_get_time; - gpio_dat->dev.enable = gpio_enable; - ret = timed_output_dev_register(&gpio_dat->dev); - if (ret < 0) { - for (j = 0; j < i; j++) - timed_output_dev_unregister(&gpio_data[i].dev); - kfree(gpio_data); - return ret; - } - - gpio_dat->gpio = cur_gpio->gpio; - gpio_dat->max_timeout = cur_gpio->max_timeout; - gpio_dat->active_low = cur_gpio->active_low; - gpio_direction_output(gpio_dat->gpio, gpio_dat->active_low); - } - - platform_set_drvdata(pdev, gpio_data); - - return 0; -} - -static int timed_gpio_remove(struct platform_device *pdev) -{ - struct timed_gpio_platform_data *pdata = pdev->dev.platform_data; - struct timed_gpio_data *gpio_data = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < pdata->num_gpios; i++) - timed_output_dev_unregister(&gpio_data[i].dev); - - kfree(gpio_data); - - return 0; -} - -static struct platform_driver timed_gpio_driver = { - .probe = timed_gpio_probe, - .remove = timed_gpio_remove, - .driver = { - .name = TIMED_GPIO_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init timed_gpio_init(void) -{ - return platform_driver_register(&timed_gpio_driver); -} - -static void __exit timed_gpio_exit(void) -{ - platform_driver_unregister(&timed_gpio_driver); -} - -module_init(timed_gpio_init); -module_exit(timed_gpio_exit); - -MODULE_AUTHOR("Mike Lockwood "); -MODULE_DESCRIPTION("timed gpio driver"); -MODULE_LICENSE("GPL"); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/android/timed_gpio.h linux-2.6.32-rc6-staging/drivers/staging/android/timed_gpio.h --- linux-2.6.32-rc6/drivers/staging/android/timed_gpio.h 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/android/timed_gpio.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,33 +0,0 @@ -/* include/linux/timed_gpio.h - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * -*/ - -#ifndef _LINUX_TIMED_GPIO_H -#define _LINUX_TIMED_GPIO_H - -#define TIMED_GPIO_NAME "timed-gpio" - -struct timed_gpio { - const char *name; - unsigned gpio; - int max_timeout; - u8 active_low; -}; - -struct timed_gpio_platform_data { - int num_gpios; - struct timed_gpio *gpios; -}; - -#endif diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/android/timed_output.c linux-2.6.32-rc6-staging/drivers/staging/android/timed_output.c --- linux-2.6.32-rc6/drivers/staging/android/timed_output.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/android/timed_output.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,121 +0,0 @@ -/* drivers/misc/timed_output.c - * - * Copyright (C) 2009 Google, Inc. - * Author: Mike Lockwood - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -#include "timed_output.h" - -static struct class *timed_output_class; -static atomic_t device_count; - -static ssize_t enable_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct timed_output_dev *tdev = dev_get_drvdata(dev); - int remaining = tdev->get_time(tdev); - - return sprintf(buf, "%d\n", remaining); -} - -static ssize_t enable_store( - struct device *dev, struct device_attribute *attr, - const char *buf, size_t size) -{ - struct timed_output_dev *tdev = dev_get_drvdata(dev); - int value; - - sscanf(buf, "%d", &value); - tdev->enable(tdev, value); - - return size; -} - -static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store); - -static int create_timed_output_class(void) -{ - if (!timed_output_class) { - timed_output_class = class_create(THIS_MODULE, "timed_output"); - if (IS_ERR(timed_output_class)) - return PTR_ERR(timed_output_class); - atomic_set(&device_count, 0); - } - - return 0; -} - -int timed_output_dev_register(struct timed_output_dev *tdev) -{ - int ret; - - if (!tdev || !tdev->name || !tdev->enable || !tdev->get_time) - return -EINVAL; - - ret = create_timed_output_class(); - if (ret < 0) - return ret; - - tdev->index = atomic_inc_return(&device_count); - tdev->dev = device_create(timed_output_class, NULL, - MKDEV(0, tdev->index), NULL, tdev->name); - if (IS_ERR(tdev->dev)) - return PTR_ERR(tdev->dev); - - ret = device_create_file(tdev->dev, &dev_attr_enable); - if (ret < 0) - goto err_create_file; - - dev_set_drvdata(tdev->dev, tdev); - tdev->state = 0; - return 0; - -err_create_file: - device_destroy(timed_output_class, MKDEV(0, tdev->index)); - printk(KERN_ERR "timed_output: Failed to register driver %s\n", - tdev->name); - - return ret; -} -EXPORT_SYMBOL_GPL(timed_output_dev_register); - -void timed_output_dev_unregister(struct timed_output_dev *tdev) -{ - device_remove_file(tdev->dev, &dev_attr_enable); - device_destroy(timed_output_class, MKDEV(0, tdev->index)); - dev_set_drvdata(tdev->dev, NULL); -} -EXPORT_SYMBOL_GPL(timed_output_dev_unregister); - -static int __init timed_output_init(void) -{ - return create_timed_output_class(); -} - -static void __exit timed_output_exit(void) -{ - class_destroy(timed_output_class); -} - -module_init(timed_output_init); -module_exit(timed_output_exit); - -MODULE_AUTHOR("Mike Lockwood "); -MODULE_DESCRIPTION("timed output class driver"); -MODULE_LICENSE("GPL"); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/android/timed_output.h linux-2.6.32-rc6-staging/drivers/staging/android/timed_output.h --- linux-2.6.32-rc6/drivers/staging/android/timed_output.h 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/android/timed_output.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,37 +0,0 @@ -/* include/linux/timed_output.h - * - * Copyright (C) 2008 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * -*/ - -#ifndef _LINUX_TIMED_OUTPUT_H -#define _LINUX_TIMED_OUTPUT_H - -struct timed_output_dev { - const char *name; - - /* enable the output and set the timer */ - void (*enable)(struct timed_output_dev *sdev, int timeout); - - /* returns the current number of milliseconds remaining on the timer */ - int (*get_time)(struct timed_output_dev *sdev); - - /* private data */ - struct device *dev; - int index; - int state; -}; - -extern int timed_output_dev_register(struct timed_output_dev *dev); -extern void timed_output_dev_unregister(struct timed_output_dev *dev); - -#endif diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/android/TODO linux-2.6.32-rc6-staging/drivers/staging/android/TODO --- linux-2.6.32-rc6/drivers/staging/android/TODO 2009-03-23 16:12:14.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/android/TODO 1969-12-31 16:00:00.000000000 -0800 @@ -1,10 +0,0 @@ -TODO: - - checkpatch.pl cleanups - - sparse fixes - - rename files to be not so "generic" - - make sure things build as modules properly - - add proper arch dependancies as needed - - audit userspace interfaces to make sure they are sane - -Please send patches to Greg Kroah-Hartman and Cc: -Brian Swetland diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/arlan/TODO linux-2.6.32-rc6-staging/drivers/staging/arlan/TODO --- linux-2.6.32-rc6/drivers/staging/arlan/TODO 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/arlan/TODO 2009-11-06 20:57:54.000000000 -0800 @@ -0,0 +1,7 @@ +TODO: + - step up and maintain this driver to ensure that it continues + to work. Having the hardware for this is pretty much a + requirement. If this does not happen, the will be removed in + the 2.6.35 kernel release. + +Please send patches to Greg Kroah-Hartman . diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/b3dfg/b3dfg.c linux-2.6.32-rc6-staging/drivers/staging/b3dfg/b3dfg.c --- linux-2.6.32-rc6/drivers/staging/b3dfg/b3dfg.c 2009-11-04 15:20:32.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/b3dfg/b3dfg.c 2009-11-06 20:57:47.000000000 -0800 @@ -468,7 +468,6 @@ static int enable_transmission(struct b3dfg_dev *fgdev) { - u16 command; unsigned long flags; struct device *dev = &fgdev->pdev->dev; @@ -480,17 +479,6 @@ return -EINVAL; } - /* - * Check we're a bus master. - * TODO: I think we can remove this having added the pci_set_master call - */ - pci_read_config_word(fgdev->pdev, PCI_COMMAND, &command); - if (!(command & PCI_COMMAND_MASTER)) { - dev_err(dev, "not a bus master, force-enabling\n"); - pci_write_config_word(fgdev->pdev, PCI_COMMAND, - command | PCI_COMMAND_MASTER); - } - spin_lock_irqsave(&fgdev->buffer_lock, flags); /* Handle racing enable_transmission calls. */ diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/comedi_compat32.c linux-2.6.32-rc6-staging/drivers/staging/comedi/comedi_compat32.c --- linux-2.6.32-rc6/drivers/staging/comedi/comedi_compat32.c 2009-11-04 15:20:32.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/comedi_compat32.c 2009-11-06 20:57:47.000000000 -0800 @@ -27,16 +27,12 @@ #define __NO_VERSION__ #include "comedi.h" #include -#include +#include #include "comedi_compat32.h" #ifdef CONFIG_COMPAT -#ifndef HAVE_COMPAT_IOCTL -#include /* for (un)register_ioctl32_conversion */ -#endif - #define COMEDI32_CHANINFO _IOR(CIO, 3, struct comedi32_chaninfo_struct) #define COMEDI32_RANGEINFO _IOR(CIO, 8, struct comedi32_rangeinfo_struct) /* N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR. @@ -101,22 +97,9 @@ if (!file->f_op) return -ENOTTY; -#ifdef HAVE_UNLOCKED_IOCTL - if (file->f_op->unlocked_ioctl) { - int rc = (int)(*file->f_op->unlocked_ioctl) (file, cmd, arg); - if (rc == -ENOIOCTLCMD) - rc = -ENOTTY; - return rc; - } -#endif - if (file->f_op->ioctl) { - int rc; - lock_kernel(); - rc = (*file->f_op->ioctl) (file->f_dentry->d_inode, - file, cmd, arg); - unlock_kernel(); - return rc; - } + if (file->f_op->unlocked_ioctl) + return file->f_op->unlocked_ioctl(file, cmd, arg); + return -ENOTTY; } @@ -186,8 +169,8 @@ } /* Copy 32-bit cmd structure to native cmd structure. */ -static int get_compat_cmd(struct comedi_cmd __user * cmd, - struct comedi32_cmd_struct __user * cmd32) +static int get_compat_cmd(struct comedi_cmd __user *cmd, + struct comedi32_cmd_struct __user *cmd32) { int err; union { @@ -237,8 +220,8 @@ } /* Copy native cmd structure to 32-bit cmd structure. */ -static int put_compat_cmd(struct comedi32_cmd_struct __user * cmd32, - struct comedi_cmd __user * cmd) +static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32, + struct comedi_cmd __user *cmd) { int err; unsigned int temp; @@ -328,8 +311,8 @@ } /* Copy 32-bit insn structure to native insn structure. */ -static int get_compat_insn(struct comedi_insn __user * insn, - struct comedi32_insn_struct __user * insn32) +static int get_compat_insn(struct comedi_insn __user *insn, + struct comedi32_insn_struct __user *insn32) { int err; union { @@ -372,9 +355,9 @@ insnlist32 = compat_ptr(arg); /* Get 32-bit insnlist structure. */ - if (!access_ok(VERIFY_READ, insnlist32, sizeof(*insnlist32))) { + if (!access_ok(VERIFY_READ, insnlist32, sizeof(*insnlist32))) return -EFAULT; - } + err = 0; err |= __get_user(n_insns, &insnlist32->n_insns); err |= __get_user(uptr, &insnlist32->insns); @@ -387,9 +370,9 @@ insn[n_insns])); /* Set native insnlist structure. */ - if (!access_ok(VERIFY_WRITE, &s->insnlist, sizeof(s->insnlist))) { + if (!access_ok(VERIFY_WRITE, &s->insnlist, sizeof(s->insnlist))) return -EFAULT; - } + err |= __put_user(n_insns, &s->insnlist.n_insns); err |= __put_user(&s->insn[0], &s->insnlist.insns); if (err) @@ -472,8 +455,6 @@ return rc; } -#ifdef HAVE_COMPAT_IOCTL /* defined in 2.6.11 onwards */ - /* compat_ioctl file operation. */ /* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */ long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -481,106 +462,4 @@ return raw_ioctl(file, cmd, arg); } -#else /* HAVE_COMPAT_IOCTL */ - -/* - * Brain-dead ioctl compatibility for 2.6.10 and earlier. - * - * It's brain-dead because cmd numbers need to be unique system-wide! - * The comedi driver could end up attempting to execute ioctls for non-Comedi - * devices because it registered the system-wide cmd code first. Similarly, - * another driver could end up attempting to execute ioctls for a Comedi - * device because it registered the cmd code first. Chaos ensues. - */ - -/* Handler for all 32-bit ioctl codes registered by this driver. */ -static int mapped_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, - struct file *file) -{ - int rc; - - /* Make sure we are dealing with a Comedi device. */ - if (imajor(file->f_dentry->d_inode) != COMEDI_MAJOR) - return -ENOTTY; - - rc = raw_ioctl(file, cmd, arg); - /* Do not return -ENOIOCTLCMD. */ - if (rc == -ENOIOCTLCMD) - rc = -ENOTTY; - - return rc; -} - -struct ioctl32_map { - unsigned int cmd; - int (*handler) (unsigned int, unsigned int, unsigned long, - struct file *); - int registered; -}; - -static struct ioctl32_map comedi_ioctl32_map[] = { - {COMEDI_DEVCONFIG, mapped_ioctl, 0}, - {COMEDI_DEVINFO, mapped_ioctl, 0}, - {COMEDI_SUBDINFO, mapped_ioctl, 0}, - {COMEDI_BUFCONFIG, mapped_ioctl, 0}, - {COMEDI_BUFINFO, mapped_ioctl, 0}, - {COMEDI_LOCK, mapped_ioctl, 0}, - {COMEDI_UNLOCK, mapped_ioctl, 0}, - {COMEDI_CANCEL, mapped_ioctl, 0}, - {COMEDI_POLL, mapped_ioctl, 0}, - {COMEDI32_CHANINFO, mapped_ioctl, 0}, - {COMEDI32_RANGEINFO, mapped_ioctl, 0}, - {COMEDI32_CMD, mapped_ioctl, 0}, - {COMEDI32_CMDTEST, mapped_ioctl, 0}, - {COMEDI32_INSNLIST, mapped_ioctl, 0}, - {COMEDI32_INSN, mapped_ioctl, 0}, -}; - -#define NUM_IOCTL32_MAPS ARRAY_SIZE(comedi_ioctl32_map) - -/* Register system-wide 32-bit ioctl handlers. */ -void comedi_register_ioctl32(void) -{ - int n, rc; - - for (n = 0; n < NUM_IOCTL32_MAPS; n++) { - rc = register_ioctl32_conversion(comedi_ioctl32_map[n].cmd, - comedi_ioctl32_map[n].handler); - if (rc) { - printk(KERN_WARNING - "comedi: failed to register 32-bit " - "compatible ioctl handler for 0x%X - " - "expect bad things to happen!\n", - comedi_ioctl32_map[n].cmd); - } - comedi_ioctl32_map[n].registered = !rc; - } -} - -/* Unregister system-wide 32-bit ioctl translations. */ -void comedi_unregister_ioctl32(void) -{ - int n, rc; - - for (n = 0; n < NUM_IOCTL32_MAPS; n++) { - if (comedi_ioctl32_map[n].registered) { - rc = unregister_ioctl32_conversion(comedi_ioctl32_map - [n].cmd, - comedi_ioctl32_map - [n].handler); - if (rc) { - printk(KERN_ERR - "comedi: failed to unregister 32-bit " - "compatible ioctl handler for 0x%X - " - "expect kernel Oops!\n", - comedi_ioctl32_map[n].cmd); - } else { - comedi_ioctl32_map[n].registered = 0; - } - } - } -} - -#endif /* HAVE_COMPAT_IOCTL */ - #endif /* CONFIG_COMPAT */ diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/comedi_compat32.h linux-2.6.32-rc6-staging/drivers/staging/comedi/comedi_compat32.h --- linux-2.6.32-rc6/drivers/staging/comedi/comedi_compat32.h 2009-11-04 15:20:32.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/comedi_compat32.h 2009-11-06 20:57:47.000000000 -0800 @@ -28,30 +28,16 @@ #define _COMEDI_COMPAT32_H #include -#include /* For HAVE_COMPAT_IOCTL and HAVE_UNLOCKED_IOCTL */ +#include #ifdef CONFIG_COMPAT -#ifdef HAVE_COMPAT_IOCTL - extern long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -#define comedi_register_ioctl32() do {} while (0) -#define comedi_unregister_ioctl32() do {} while (0) - -#else /* HAVE_COMPAT_IOCTL */ - -#define comedi_compat_ioctl 0 /* NULL */ -extern void comedi_register_ioctl32(void); -extern void comedi_unregister_ioctl32(void); - -#endif /* HAVE_COMPAT_IOCTL */ #else /* CONFIG_COMPAT */ #define comedi_compat_ioctl 0 /* NULL */ -#define comedi_register_ioctl32() do {} while (0) -#define comedi_unregister_ioctl32() do {} while (0) #endif /* CONFIG_COMPAT */ diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/comedidev.h linux-2.6.32-rc6-staging/drivers/staging/comedi/comedidev.h --- linux-2.6.32-rc6/drivers/staging/comedi/comedidev.h 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/comedidev.h 2009-11-06 20:57:47.000000000 -0800 @@ -49,7 +49,8 @@ } while (0) #define COMEDI_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) -#define COMEDI_VERSION_CODE COMEDI_VERSION(COMEDI_MAJORVERSION, COMEDI_MINORVERSION, COMEDI_MICROVERSION) +#define COMEDI_VERSION_CODE COMEDI_VERSION(COMEDI_MAJORVERSION, \ + COMEDI_MINORVERSION, COMEDI_MICROVERSION) #define COMEDI_RELEASE VERSION #define COMEDI_INITCLEANUP_NOMODULE(x) \ @@ -58,12 +59,12 @@ static void __exit x ## _cleanup_module(void) \ {comedi_driver_unregister(&(x)); } \ module_init(x ## _init_module); \ - module_exit(x ## _cleanup_module); \ + module_exit(x ## _cleanup_module); #define COMEDI_MODULE_MACROS \ MODULE_AUTHOR("Comedi http://www.comedi.org"); \ MODULE_DESCRIPTION("Comedi low-level driver"); \ - MODULE_LICENSE("GPL"); \ + MODULE_LICENSE("GPL"); #define COMEDI_INITCLEANUP(x) \ COMEDI_MODULE_MACROS \ @@ -75,7 +76,8 @@ { \ return comedi_pci_auto_config(dev, comedi_driver.driver_name); \ } \ - static void __devexit comedi_driver ## _pci_remove(struct pci_dev *dev) \ + static void __devexit comedi_driver ## _pci_remove(\ + struct pci_dev *dev) \ { \ comedi_pci_auto_unconfig(dev); \ } \ @@ -91,7 +93,8 @@ retval = comedi_driver_register(&comedi_driver); \ if (retval < 0) \ return retval; \ - comedi_driver ## _pci_driver.name = (char *)comedi_driver.driver_name; \ + comedi_driver ## _pci_driver.name = \ + (char *)comedi_driver.driver_name; \ return pci_register_driver(&comedi_driver ## _pci_driver); \ } \ static void __exit comedi_driver ## _cleanup_module(void) \ @@ -170,14 +173,15 @@ struct comedi_cmd *); int (*poll) (struct comedi_device *, struct comedi_subdevice *); int (*cancel) (struct comedi_device *, struct comedi_subdevice *); - /* int (*do_lock)(struct comedi_device *,struct comedi_subdevice *); */ - /* int (*do_unlock)(struct comedi_device *,struct comedi_subdevice *); */ + /* int (*do_lock)(struct comedi_device *, struct comedi_subdevice *); */ + /* int (*do_unlock)(struct comedi_device *, \ + struct comedi_subdevice *); */ /* called when the buffer changes */ - int (*buf_change) (struct comedi_device * dev, - struct comedi_subdevice * s, unsigned long new_size); + int (*buf_change) (struct comedi_device *dev, + struct comedi_subdevice *s, unsigned long new_size); - void (*munge) (struct comedi_device * dev, struct comedi_subdevice * s, + void (*munge) (struct comedi_device *dev, struct comedi_subdevice *s, void *data, unsigned int num_bytes, unsigned int start_chan_index); enum dma_data_direction async_dma_dir; @@ -198,16 +202,22 @@ void *prealloc_buf; /* pre-allocated buffer */ unsigned int prealloc_bufsz; /* buffer size, in bytes */ - struct comedi_buf_page *buf_page_list; /* virtual and dma address of each page */ + /* virtual and dma address of each page */ + struct comedi_buf_page *buf_page_list; unsigned n_buf_pages; /* num elements in buf_page_list */ unsigned int max_bufsize; /* maximum buffer size, bytes */ - unsigned int mmap_count; /* current number of mmaps of prealloc_buf */ + /* current number of mmaps of prealloc_buf */ + unsigned int mmap_count; - unsigned int buf_write_count; /* byte count for writer (write completed) */ - unsigned int buf_write_alloc_count; /* byte count for writer (allocated for writing) */ - unsigned int buf_read_count; /* byte count for reader (read completed) */ - unsigned int buf_read_alloc_count; /* byte count for reader (allocated for reading) */ + /* byte count for writer (write completed) */ + unsigned int buf_write_count; + /* byte count for writer (allocated for writing) */ + unsigned int buf_write_alloc_count; + /* byte count for reader (read completed) */ + unsigned int buf_read_count; + /* byte count for reader (allocated for reading) */ + unsigned int buf_read_alloc_count; unsigned int buf_write_ptr; /* buffer marker for writer */ unsigned int buf_read_ptr; /* buffer marker for reader */ @@ -233,7 +243,7 @@ int (*cb_func) (unsigned int flags, void *); void *cb_arg; - int (*inttrig) (struct comedi_device * dev, struct comedi_subdevice * s, + int (*inttrig) (struct comedi_device *dev, struct comedi_subdevice *s, unsigned int x); }; @@ -283,8 +293,8 @@ struct fasync_struct *async_queue; - void (*open) (struct comedi_device * dev); - void (*close) (struct comedi_device * dev); + void (*open) (struct comedi_device *dev); + void (*close) (struct comedi_device *dev); }; struct comedi_device_file_info { @@ -318,9 +328,8 @@ struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor); -static inline struct comedi_subdevice *comedi_get_read_subdevice(const struct - comedi_device_file_info - *info) +static inline struct comedi_subdevice *comedi_get_read_subdevice( + const struct comedi_device_file_info *info) { if (info->read_subdevice) return info->read_subdevice; @@ -329,9 +338,8 @@ return info->device->read_subdev; } -static inline struct comedi_subdevice *comedi_get_write_subdevice(const struct - comedi_device_file_info - *info) +static inline struct comedi_subdevice *comedi_get_write_subdevice( + const struct comedi_device_file_info *info) { if (info->write_subdevice) return info->write_subdevice; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/comedi_fops.c linux-2.6.32-rc6-staging/drivers/staging/comedi/comedi_fops.c --- linux-2.6.32-rc6/drivers/staging/comedi/comedi_fops.c 2009-11-04 15:20:32.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/comedi_fops.c 2009-11-06 20:57:47.000000000 -0800 @@ -110,13 +110,8 @@ static struct device_attribute dev_attr_max_write_buffer_kb; static struct device_attribute dev_attr_write_buffer_kb; -#ifdef HAVE_UNLOCKED_IOCTL static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -#else -static int comedi_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -#endif { const unsigned minor = iminor(file->f_dentry->d_inode); struct comedi_device_file_info *dev_file_info = @@ -1867,14 +1862,8 @@ const struct file_operations comedi_fops = { .owner = THIS_MODULE, -#ifdef HAVE_UNLOCKED_IOCTL .unlocked_ioctl = comedi_unlocked_ioctl, -#else - .ioctl = comedi_ioctl, -#endif -#ifdef HAVE_COMPAT_IOCTL .compat_ioctl = comedi_compat_ioctl, -#endif .open = comedi_open, .release = comedi_close, .read = comedi_read, @@ -1959,8 +1948,6 @@ } } - comedi_register_ioctl32(); - return 0; } @@ -1977,8 +1964,6 @@ unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS); comedi_proc_cleanup(); - - comedi_unregister_ioctl32(); } module_init(comedi_init); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/comedi.h linux-2.6.32-rc6-staging/drivers/staging/comedi/comedi.h --- linux-2.6.32-rc6/drivers/staging/comedi/comedi.h 2009-11-04 15:20:32.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/comedi.h 2009-11-06 20:57:47.000000000 -0800 @@ -24,10 +24,6 @@ #ifndef _COMEDI_H #define _COMEDI_H -#ifdef __cplusplus -extern "C" { -#endif - #define COMEDI_MAJORVERSION 0 #define COMEDI_MINORVERSION 7 #define COMEDI_MICROVERSION 76 @@ -871,8 +867,4 @@ AMPLC_DIO_GAT_RESERVED7 }; -#ifdef __cplusplus -} -#endif - #endif /* _COMEDI_H */ diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/8253.h linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/8253.h --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/8253.h 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/8253.h 2009-11-06 20:57:47.000000000 -0800 @@ -206,7 +206,8 @@ } *nanosec = div1 * div2 * i8253_osc_base; - *d1 = div1 & 0xffff; /* masking is done since counter maps zero to 0x10000 */ + /* masking is done since counter maps zero to 0x10000 */ + *d1 = div1 & 0xffff; *d2 = div2 & 0xffff; return; } diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/8255.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/8255.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/8255.c 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/8255.c 2009-11-06 20:57:47.000000000 -0800 @@ -132,6 +132,7 @@ comedi_event(dev, s); } +EXPORT_SYMBOL(subdev_8255_interrupt); static int subdev_8255_cb(int dir, int port, int data, unsigned long arg) { @@ -179,15 +180,14 @@ unsigned int bits; mask = 1 << CR_CHAN(insn->chanspec); - if (mask & 0x0000ff) { + if (mask & 0x0000ff) bits = 0x0000ff; - } else if (mask & 0x00ff00) { + else if (mask & 0x00ff00) bits = 0x00ff00; - } else if (mask & 0x0f0000) { + else if (mask & 0x0f0000) bits = 0x0f0000; - } else { + else bits = 0xf00000; - } switch (data[0]) { case INSN_CONFIG_DIO_INPUT: @@ -333,11 +333,10 @@ return -ENOMEM; CALLBACK_ARG = arg; - if (cb == NULL) { + if (cb == NULL) CALLBACK_FUNC = subdev_8255_cb; - } else { + else CALLBACK_FUNC = cb; - } s->insn_bits = subdev_8255_insn; s->insn_config = subdev_8255_insn_config; @@ -347,6 +346,7 @@ return 0; } +EXPORT_SYMBOL(subdev_8255_init); int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, int (*cb) (int, int, int, unsigned long), @@ -366,6 +366,7 @@ return 0; } +EXPORT_SYMBOL(subdev_8255_init_irq); void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -378,6 +379,7 @@ kfree(s->private); } } +EXPORT_SYMBOL(subdev_8255_cleanup); /* @@ -448,8 +450,3 @@ return 0; } - -EXPORT_SYMBOL(subdev_8255_init); -EXPORT_SYMBOL(subdev_8255_init_irq); -EXPORT_SYMBOL(subdev_8255_cleanup); -EXPORT_SYMBOL(subdev_8255_interrupt); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/acl7225b.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/acl7225b.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/acl7225b.c 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/acl7225b.c 2009-11-06 20:57:47.000000000 -0800 @@ -94,10 +94,11 @@ iobase = it->options[0]; iorange = this_board->io_range; - printk("comedi%d: acl7225b: board=%s 0x%04x ", dev->minor, + printk(KERN_INFO "comedi%d: acl7225b: board=%s 0x%04x\n", dev->minor, this_board->name, iobase); if (!request_region(iobase, iorange, "acl7225b")) { - printk("I/O port conflict\n"); + printk(KERN_ERR "comedi%d: request_region failed - I/O port conflict\n", + dev->minor); return -EIO; } dev->board_name = this_board->name; @@ -137,14 +138,12 @@ s->range_table = &range_digital; s->private = (void *)ACL7225_DI_LO; - printk("\n"); - return 0; } static int acl7225b_detach(struct comedi_device *dev) { - printk("comedi%d: acl7225b: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: acl7225b: remove\n", dev->minor); if (dev->iobase) release_region(dev->iobase, this_board->io_range); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c 2009-11-06 20:57:47.000000000 -0800 @@ -1386,8 +1386,7 @@ /* Test the timout parameter */ /*****************************/ - if ((ui_TimeOut >= 0) - && (ui_TimeOut <= 65535UL)) { + if (ui_TimeOut <= 65535UL) { for (;;) { /*******************/ diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c 2009-11-06 20:57:47.000000000 -0800 @@ -150,7 +150,7 @@ unsigned int ui_TmpValue = 0; unsigned int ui_Channel; ui_Channel = CR_CHAN(insn->chanspec); - if (ui_Channel >= 0 && ui_Channel <= 31) { + if (ui_Channel <= 31) { ui_TmpValue = (unsigned int) inl(devpriv->iobase + APCI1032_DIGITAL_IP); /* * since only 1 channel reqd to bring it to last bit it is rotated 8 diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c 2009-11-06 20:57:47.000000000 -0800 @@ -968,7 +968,7 @@ switch (data[0]) { case 0: - if (ui_Channel >= 0 && ui_Channel <= 15) { + if (ui_Channel <= 15) { ui_TmpValue = (unsigned int) inw(devpriv->i_IobaseAddon + APCI1500_DIGITAL_IP); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c 2009-11-06 20:57:47.000000000 -0800 @@ -79,7 +79,7 @@ unsigned int ui_TmpValue = 0; unsigned int ui_Channel; ui_Channel = CR_CHAN(insn->chanspec); - if (ui_Channel >= 0 && ui_Channel <= 7) { + if (ui_Channel <= 7) { ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI1516_DIGITAL_IP); /* since only 1 channel reqd to bring it to last bit it is rotated */ /* 8 +(chan - 1) times then ANDed with 1 for last bit. */ diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c 2009-11-06 20:57:47.000000000 -0800 @@ -154,7 +154,7 @@ unsigned int ui_Channel; ui_Channel = CR_CHAN(insn->chanspec); - if (ui_Channel >= 0 && ui_Channel <= 31) { + if (ui_Channel <= 31) { ui_TmpValue = (unsigned int) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP); /* diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c 2009-11-06 20:57:47.000000000 -0800 @@ -117,7 +117,7 @@ unsigned int ui_NoOfChannel; unsigned int ui_Temp, ui_Temp1; ui_NoOfChannel = CR_CHAN(insn->chanspec); - if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) { + if (ui_NoOfChannel > 15) { comedi_error(dev, "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n"); return -EINVAL; @@ -272,7 +272,7 @@ unsigned int ui_Temp; unsigned int ui_NoOfChannel; ui_NoOfChannel = CR_CHAN(insn->chanspec); - if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) { + if (ui_NoOfChannel > 15) { comedi_error(dev, "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n"); return -EINVAL; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c 2009-11-06 20:57:47.000000000 -0800 @@ -79,7 +79,7 @@ unsigned int ui_TmpValue = 0; unsigned int ui_Channel; ui_Channel = CR_CHAN(insn->chanspec); - if (ui_Channel >= 0 && ui_Channel <= 7) { + if (ui_Channel <= 7) { ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI2200_DIGITAL_IP); *data = (ui_TmpValue >> ui_Channel) & 0x1; } /* if(ui_Channel >= 0 && ui_Channel <=7) */ diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c 2009-11-06 20:57:47.000000000 -0800 @@ -2350,7 +2350,7 @@ ui_Chan = CR_CHAN(insn->chanspec); /* channel specified */ /* this_board->i_hwdrv_InsnReadDigitalInput(dev,ui_Chan,data); */ - if (ui_Chan >= 0 && ui_Chan <= 3) { + if (ui_Chan <= 3) { ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI3120_RD_STATUS); /* @@ -2539,8 +2539,7 @@ "Not a valid Data !!! ,Data should be 1 or 0\n"); return -EINVAL; } - if ((ui_NoOfChannel > (this_board->i_NbrDoChannel - 1)) - || (ui_NoOfChannel < 0)) { + if (ui_NoOfChannel > this_board->i_NbrDoChannel - 1) { comedi_error(dev, "This board doesn't have specified channel !!! \n"); return -EINVAL; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c 2009-11-06 20:57:47.000000000 -0800 @@ -461,7 +461,7 @@ if (s_BoardInfos[dev->minor].i_ConnectionType == 1) { /* if diff */ - if ((ui_Channel_num >= 0) && (ui_Channel_num <= 1)) + if (ui_Channel_num <= 1) i_DiffChannel = ui_Channel_num, i_Module = 0; else if ((ui_Channel_num >= 2) && (ui_Channel_num <= 3)) i_DiffChannel = ui_Channel_num - 2, i_Module = 1; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c 2009-11-06 20:57:47.000000000 -0800 @@ -148,7 +148,7 @@ /* Test the convert time value */ /*******************************/ - if ((dw_ReloadValue >= 0) && (dw_ReloadValue <= 65535)) { + if (dw_ReloadValue <= 65535) { dw_TestReloadValue = dw_ReloadValue; if (b_TimeBase == 1) { diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/adl_pci6208.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/adl_pci6208.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/adl_pci6208.c 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/adl_pci6208.c 2009-11-06 20:57:47.000000000 -0800 @@ -133,9 +133,11 @@ static int pci6208_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); -/* static int pci6208_dio_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, */ +/* static int pci6208_dio_insn_bits (struct comedi_device *dev, + * struct comedi_subdevice *s, */ /* struct comedi_insn *insn,unsigned int *data); */ -/* static int pci6208_dio_insn_config(struct comedi_device *dev,struct comedi_subdevice *s, */ +/* static int pci6208_dio_insn_config(struct comedi_device *dev, + * struct comedi_subdevice *s, */ /* struct comedi_insn *insn,unsigned int *data); */ /* @@ -151,7 +153,7 @@ int retval; unsigned long io_base; - printk("comedi%d: pci6208: ", dev->minor); + printk(KERN_INFO "comedi%d: pci6208: ", dev->minor); retval = alloc_private(dev, sizeof(struct pci6208_private)); if (retval < 0) @@ -195,7 +197,7 @@ /* s->insn_bits = pci6208_dio_insn_bits; */ /* s->insn_config = pci6208_dio_insn_config; */ - printk("attached\n"); + printk(KERN_INFO "attached\n"); return 1; } @@ -210,12 +212,11 @@ */ static int pci6208_detach(struct comedi_device *dev) { - printk("comedi%d: pci6208: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: pci6208: remove\n", dev->minor); if (devpriv && devpriv->pci_dev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } @@ -266,7 +267,8 @@ * useful to applications if you implement the insn_bits interface. * This allows packed reading/writing of the DIO channels. The * comedi core can convert between insn_bits and insn_read/write */ -/* static int pci6208_dio_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, */ +/* static int pci6208_dio_insn_bits(struct comedi_device *dev, + * struct comedi_subdevice *s, */ /* struct comedi_insn *insn,unsigned int *data) */ /* { */ /* if(insn->n!=2)return -EINVAL; */ @@ -290,7 +292,8 @@ /* return 2; */ /* } */ -/* static int pci6208_dio_insn_config(struct comedi_device *dev,struct comedi_subdevice *s, */ +/* static int pci6208_dio_insn_config(struct comedi_device *dev, + * struct comedi_subdevice *s, */ /* struct comedi_insn *insn,unsigned int *data) */ /* { */ /* int chan=CR_CHAN(insn->chanspec); */ @@ -320,10 +323,16 @@ pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) { if (pci_dev->vendor == PCI_VENDOR_ID_ADLINK) { for (i = 0; i < ARRAY_SIZE(pci6208_boards); i++) { - if (pci6208_boards[i].dev_id == pci_dev->device) { - /* was a particular bus/slot requested? */ + if (pci6208_boards[i].dev_id == + pci_dev->device) { + /* + * was a particular bus/slot requested? + */ if ((bus != 0) || (slot != 0)) { - /* are we on the wrong bus/slot? */ + /* + * are we on the + * wrong bus/slot? + */ if (pci_dev->bus->number != bus || PCI_SLOT(pci_dev->devfn) @@ -338,8 +347,9 @@ } } - printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, bus, slot); + printk(KERN_ERR "comedi%d: no supported board found! " + "(req. bus/slot : %d/%d)\n", + dev->minor, bus, slot); return -EIO; found: @@ -368,17 +378,20 @@ /* Enable PCI device and request regions */ if (comedi_pci_enable(pci_dev, PCI6208_DRIVER_NAME) < 0) { - printk - ("comedi%d: Failed to enable PCI device and request regions\n", - dev_minor); + printk(KERN_ERR "comedi%d: Failed to enable PCI device " + "and request regions\n", + dev_minor); return -EIO; } - /* Read local configuration register base address [PCI_BASE_ADDRESS #1]. */ + /* Read local configuration register + * base address [PCI_BASE_ADDRESS #1]. + */ lcr_io_base = pci_resource_start(pci_dev, 1); lcr_io_range = pci_resource_len(pci_dev, 1); - printk("comedi%d: local config registers at address 0x%4lx [0x%4lx]\n", - dev_minor, lcr_io_base, lcr_io_range); + printk(KERN_INFO "comedi%d: local config registers at address" + " 0x%4lx [0x%4lx]\n", + dev_minor, lcr_io_base, lcr_io_range); /* Read PCI6208 register base address [PCI_BASE_ADDRESS #2]. */ io_base = pci_resource_start(pci_dev, 2); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/adl_pci7296.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/adl_pci7296.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/adl_pci7296.c 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/adl_pci7296.c 2009-11-06 20:57:47.000000000 -0800 @@ -82,8 +82,7 @@ int bus, slot; int ret; - printk("comedi: attempt to attach...\n"); - printk("comedi%d: adl_pci7432\n", dev->minor); + printk(KERN_INFO "comedi%d: attach adl_pci7432\n", dev->minor); dev->board_name = "pci7432"; bus = it->options[0]; @@ -110,14 +109,14 @@ } devpriv->pci_dev = pcidev; if (comedi_pci_enable(pcidev, "adl_pci7296") < 0) { - printk - ("comedi%d: Failed to enable PCI device and request regions\n", + printk(KERN_ERR "comedi%d: Failed to enable PCI device and request regions\n", dev->minor); return -EIO; } dev->iobase = pci_resource_start(pcidev, 2); - printk("comedi: base addr %4lx\n", dev->iobase); + printk(KERN_INFO "comedi: base addr %4lx\n", + dev->iobase); /* four 8255 digital io subdevices */ s = dev->subdevices + 0; @@ -145,25 +144,25 @@ if (ret < 0) return ret; - printk("attached\n"); + printk(KERN_DEBUG "comedi%d: adl_pci7432 attached\n", + dev->minor); return 1; } } - printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", + printk(KERN_ERR "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", dev->minor, bus, slot); return -EIO; } static int adl_pci7296_detach(struct comedi_device *dev) { - printk("comedi%d: pci7432: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: pci7432: remove\n", dev->minor); if (devpriv && devpriv->pci_dev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } /* detach four 8255 digital io subdevices */ diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/adl_pci7432.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/adl_pci7432.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/adl_pci7432.c 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/adl_pci7432.c 2009-11-06 20:57:47.000000000 -0800 @@ -90,8 +90,7 @@ struct comedi_subdevice *s; int bus, slot; - printk("comedi: attempt to attach...\n"); - printk("comedi%d: adl_pci7432\n", dev->minor); + printk(KERN_INFO "comedi%d: attach adl_pci7432\n", dev->minor); dev->board_name = "pci7432"; bus = it->options[0]; @@ -118,13 +117,13 @@ } devpriv->pci_dev = pcidev; if (comedi_pci_enable(pcidev, "adl_pci7432") < 0) { - printk - ("comedi%d: Failed to enable PCI device and request regions\n", + printk(KERN_ERR "comedi%d: Failed to enable PCI device and request regions\n", dev->minor); return -EIO; } dev->iobase = pci_resource_start(pcidev, 2); - printk("comedi: base addr %4lx\n", dev->iobase); + printk(KERN_INFO "comedi: base addr %4lx\n", + dev->iobase); s = dev->subdevices + 0; s->type = COMEDI_SUBD_DI; @@ -148,25 +147,24 @@ s->range_table = &range_digital; s->insn_bits = adl_pci7432_do_insn_bits; - printk("comedi: attached\n"); - + printk(KERN_DEBUG "comedi%d: adl_pci7432 attached\n", + dev->minor); return 1; } } - printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", + printk(KERN_ERR "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", dev->minor, bus, slot); return -EIO; } static int adl_pci7432_detach(struct comedi_device *dev) { - printk("comedi%d: pci7432: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: pci7432: remove\n", dev->minor); if (devpriv && devpriv->pci_dev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } @@ -178,8 +176,8 @@ struct comedi_insn *insn, unsigned int *data) { - printk("comedi: pci7432_do_insn_bits called\n"); - printk("comedi: data0: %8x data1: %8x\n", data[0], data[1]); + printk(KERN_DEBUG "comedi: pci7432_do_insn_bits called\n"); + printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); if (insn->n != 2) return -EINVAL; @@ -188,7 +186,7 @@ s->state &= ~data[0]; s->state |= (data[0] & data[1]); - printk("comedi: out: %8x on iobase %4lx\n", s->state, + printk(KERN_DEBUG "comedi: out: %8x on iobase %4lx\n", s->state, dev->iobase + PCI7432_DO); outl(s->state & 0xffffffff, dev->iobase + PCI7432_DO); } @@ -200,14 +198,14 @@ struct comedi_insn *insn, unsigned int *data) { - printk("comedi: pci7432_di_insn_bits called\n"); - printk("comedi: data0: %8x data1: %8x\n", data[0], data[1]); + printk(KERN_DEBUG "comedi: pci7432_di_insn_bits called\n"); + printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); if (insn->n != 2) return -EINVAL; data[1] = inl(dev->iobase + PCI7432_DI) & 0xffffffff; - printk("comedi: data1 %8x\n", data[1]); + printk(KERN_DEBUG "comedi: data1 %8x\n", data[1]); return 2; } diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/adl_pci8164.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/adl_pci8164.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/adl_pci8164.c 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/adl_pci8164.c 2009-11-06 20:57:47.000000000 -0800 @@ -35,6 +35,7 @@ */ #include "../comedidev.h" +#include #include #include "comedi_fc.h" #include "comedi_pci.h" @@ -128,8 +129,8 @@ struct comedi_subdevice *s; int bus, slot; - printk("comedi: attempt to attach...\n"); - printk("comedi%d: adl_pci8164\n", dev->minor); + printk(KERN_INFO "comedi: attempt to attach...\n"); + printk(KERN_INFO "comedi%d: adl_pci8164\n", dev->minor); dev->board_name = "pci8164"; bus = it->options[0]; @@ -150,19 +151,18 @@ if (bus || slot) { /* requested particular bus/slot */ if (pcidev->bus->number != bus - || PCI_SLOT(pcidev->devfn) != slot) { + || PCI_SLOT(pcidev->devfn) != slot) continue; - } } devpriv->pci_dev = pcidev; if (comedi_pci_enable(pcidev, "adl_pci8164") < 0) { - printk - ("comedi%d: Failed to enable PCI device and request regions\n", - dev->minor); + printk(KERN_ERR "comedi%d: Failed to enable " + "PCI device and request regions\n", dev->minor); return -EIO; } dev->iobase = pci_resource_start(pcidev, 2); - printk("comedi: base addr %4lx\n", dev->iobase); + printk(KERN_DEBUG "comedi: base addr %4lx\n", + dev->iobase); s = dev->subdevices + 0; s->type = COMEDI_SUBD_PROC; @@ -204,25 +204,24 @@ s->insn_read = adl_pci8164_insn_read_buf1; s->insn_write = adl_pci8164_insn_write_buf1; - printk("comedi: attached\n"); + printk(KERN_INFO "comedi: attached\n"); return 1; } } - printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, bus, slot); + printk(KERN_ERR "comedi%d: no supported board found!" + "(req. bus/slot : %d/%d)\n", dev->minor, bus, slot); return -EIO; } static int adl_pci8164_detach(struct comedi_device *dev) { - printk("comedi%d: pci8164: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: pci8164: remove\n", dev->minor); if (devpriv && devpriv->pci_dev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } @@ -267,8 +266,9 @@ } data[0] = inw(dev->iobase + axis_reg + offset); - printk("comedi: pci8164 %s read -> %04X:%04X on axis %s\n", action, - data[0], data[1], axisname); + printk(KERN_DEBUG "comedi: pci8164 %s read -> " + "%04X:%04X on axis %s\n", + action, data[0], data[1], axisname); } static int adl_pci8164_insn_read_msts(struct comedi_device *dev, @@ -347,8 +347,9 @@ outw(data[0], dev->iobase + axis_reg + offset); - printk("comedi: pci8164 %s write -> %04X:%04X on axis %s\n", action, - data[0], data[1], axisname); + printk(KERN_DEBUG "comedi: pci8164 %s write -> " + "%04X:%04X on axis %s\n", + action, data[0], data[1], axisname); } diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/amplc_pc263.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/amplc_pc263.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/amplc_pc263.c 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/amplc_pc263.c 2009-11-06 20:57:47.000000000 -0800 @@ -117,7 +117,8 @@ /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, - feel free to suggest moving the variable to the struct comedi_device struct. */ + feel free to suggest moving the variable to the struct comedi_device struct. +*/ #ifdef CONFIG_COMEDI_PCI struct pc263_private { /* PCI device. */ @@ -281,7 +282,8 @@ ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME); if (ret < 0) { printk(KERN_ERR - "comedi%d: error! cannot enable PCI device and request regions!\n", + "comedi%d: error! cannot enable PCI device and " + "request regions!\n", dev->minor); return ret; } @@ -290,9 +292,8 @@ #endif { ret = pc263_request_region(dev->minor, iobase, PC263_IO_SIZE); - if (ret < 0) { + if (ret < 0) return ret; - } } dev->iobase = iobase; @@ -350,21 +351,18 @@ PC263_DRIVER_NAME); #ifdef CONFIG_COMEDI_PCI - if (devpriv) + if (devpriv) { #endif - { #ifdef CONFIG_COMEDI_PCI if (devpriv->pci_dev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } else #endif { - if (dev->iobase) { + if (dev->iobase) release_region(dev->iobase, PC263_IO_SIZE); - } } } if (dev->board_name) { diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/cb_das16_cs.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/cb_das16_cs.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/cb_das16_cs.c 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/cb_das16_cs.c 2009-11-06 20:57:48.000000000 -0800 @@ -100,7 +100,7 @@ .detach = das16cs_detach, }; -static struct pcmcia_device *cur_dev = NULL; +static struct pcmcia_device *cur_dev; static const struct comedi_lrange das16cs_ai_range = { 4, { RANGE(-10, 10), @@ -169,9 +169,8 @@ id = get_prodid(dev, link); for (i = 0; i < n_boards; i++) { - if (das16cs_boards[i].device_id == id) { + if (das16cs_boards[i].device_id == id) return das16cs_boards + i; - } } printk("unknown board!\n"); @@ -197,16 +196,14 @@ printk("I/O base=0x%04lx ", dev->iobase); printk("fingerprint:\n"); - for (i = 0; i < 48; i += 2) { + for (i = 0; i < 48; i += 2) printk("%04x ", inw(dev->iobase + i)); - } printk("\n"); ret = request_irq(link->irq.AssignedIRQ, das16cs_interrupt, IRQF_SHARED, "cb_das16_cs", dev); - if (ret < 0) { + if (ret < 0) return ret; - } dev->irq = link->irq.AssignedIRQ; printk("irq=%u ", dev->irq); @@ -284,9 +281,8 @@ { printk("comedi%d: das16cs: remove\n", dev->minor); - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } return 0; } @@ -393,9 +389,10 @@ if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* step 2: make sure trigger sources are unique + * and mutually compatible */ - /* note that mutual compatiblity is not an issue here */ + /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_TIMER && cmd->scan_begin_src != TRIG_EXT) err++; @@ -672,9 +669,10 @@ #ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; module_param(pc_debug, int, 0644); -#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) +#define DEBUG(n, args...) if (pc_debug > (n)) printk(KERN_DEBUG args) static char *version = - "cb_das16_cs.c pcmcia code (David Schleef), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)"; + "cb_das16_cs.c pcmcia code (David Schleef),"\ + " modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -869,7 +867,8 @@ link->io.BasePort2 = io->win[1].base; link->io.NumPorts2 = io->win[1].len; } - /* This reserves IO space but doesn't actually enable it */ + /* This reserves IO space + * but doesn't actually enable it */ if (pcmcia_request_io(link, &link->io)) goto next_entry; } diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/cb_pcidda.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/cb_pcidda.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/cb_pcidda.c 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/cb_pcidda.c 2009-11-06 20:57:47.000000000 -0800 @@ -497,7 +497,7 @@ /* step 2: make sure trigger sources are unique and mutually compatible */ - /* note that mutual compatiblity is not an issue here */ + /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_TIMER && cmd->scan_begin_src != TRIG_EXT) err++; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/comedi_fc.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/comedi_fc.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/comedi_fc.c 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/comedi_fc.c 2009-11-06 20:57:47.000000000 -0800 @@ -53,7 +53,7 @@ retval = comedi_buf_write_alloc(async, num_bytes); if (retval != num_bytes) { - printk("comedi: buffer overrun\n"); + printk(KERN_WARNING "comedi: buffer overrun\n"); async->events |= COMEDI_CB_OVERFLOW; return 0; } @@ -65,7 +65,6 @@ return num_bytes; } - EXPORT_SYMBOL(cfc_write_array_to_buffer); unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd, @@ -84,7 +83,6 @@ return num_bytes; } - EXPORT_SYMBOL(cfc_read_array_from_buffer); unsigned int cfc_handle_events(struct comedi_device *dev, @@ -102,7 +100,6 @@ return events; } - EXPORT_SYMBOL(cfc_handle_events); MODULE_AUTHOR("Frank Mori Hess "); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/dmm32at.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/dmm32at.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/dmm32at.c 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/dmm32at.c 2009-11-06 20:57:47.000000000 -0800 @@ -629,7 +629,7 @@ /* step 2: make sure trigger sources are unique and mutually compatible */ - /* note that mutual compatiblity is not an issue here */ + /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_TIMER && cmd->scan_begin_src != TRIG_EXT) err++; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/dt2814.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/dt2814.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/dt2814.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/dt2814.c 2009-11-06 20:57:47.000000000 -0800 @@ -175,7 +175,7 @@ /* step 2: make sure trigger sources are unique and mutually compatible */ - /* note that mutual compatiblity is not an issue here */ + /* note that mutual compatibility is not an issue here */ if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT) err++; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/dt282x.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/dt282x.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/dt282x.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/dt282x.c 2009-11-06 20:57:47.000000000 -0800 @@ -777,7 +777,7 @@ /* step 2: make sure trigger sources are unique and mutually compatible */ - /* note that mutual compatiblity is not an issue here */ + /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->scan_begin_src != TRIG_EXT) err++; @@ -1050,7 +1050,7 @@ /* step 2: make sure trigger sources are unique and mutually compatible */ - /* note that mutual compatiblity is not an issue here */ + /* note that mutual compatibility is not an issue here */ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) err++; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/gsc_hpdi.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/gsc_hpdi.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/gsc_hpdi.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/gsc_hpdi.c 2009-11-06 20:57:47.000000000 -0800 @@ -55,7 +55,7 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it); static int hpdi_detach(struct comedi_device *dev); -void abort_dma(struct comedi_device *dev, unsigned int channel); +static void abort_dma(struct comedi_device *dev, unsigned int channel); static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s); static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd); @@ -110,7 +110,8 @@ int command_channel_valid(unsigned int channel) { if (channel == 0 || channel > 6) { - printk("gsc_hpdi: bug! invalid cable command channel\n"); + printk(KERN_WARNING + "gsc_hpdi: bug! invalid cable command channel\n"); return 0; } return 1; @@ -142,7 +143,8 @@ RX_FIFO_RESET_BIT = 0x4, TX_ENABLE_BIT = 0x10, RX_ENABLE_BIT = 0x20, - DEMAND_DMA_DIRECTION_TX_BIT = 0x40, /* for channel 0, channel 1 can only transmit (when present) */ + DEMAND_DMA_DIRECTION_TX_BIT = 0x40, + /* for ch 0, ch 1 can only transmit (when present) */ LINE_VALID_ON_STATUS_VALID_BIT = 0x80, START_TX_BIT = 0x10, CABLE_THROTTLE_ENABLE_BIT = 0x20, @@ -420,9 +422,11 @@ bits |= PLX_DMA_EN_READYIN_BIT; /* enable dma chaining */ bits |= PLX_EN_CHAIN_BIT; - /* enable interrupt on dma done (probably don't need this, since chain never finishes) */ + /* enable interrupt on dma done + * (probably don't need this, since chain never finishes) */ bits |= PLX_EN_DMA_DONE_INTR_BIT; - /* don't increment local address during transfers (we are transferring from a fixed fifo register) */ + /* don't increment local address during transfers + * (we are transferring from a fixed fifo register) */ bits |= PLX_LOCAL_ADDR_CONST_BIT; /* route dma interrupt to pci bus */ bits |= PLX_DMA_INTR_PCI_BIT; @@ -560,7 +564,7 @@ int i; int retval; - printk("comedi%d: gsc_hpdi\n", dev->minor); + printk(KERN_WARNING "comedi%d: gsc_hpdi\n", dev->minor); if (alloc_private(dev, sizeof(struct hpdi_private)) < 0) return -ENOMEM; @@ -588,11 +592,12 @@ } while (pcidev != NULL); } if (dev->board_ptr == NULL) { - printk("gsc_hpdi: no hpdi card found\n"); + printk(KERN_WARNING "gsc_hpdi: no hpdi card found\n"); return -EIO; } - printk("gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name, + printk(KERN_WARNING + "gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name, pcidev->bus->number, PCI_SLOT(pcidev->devfn)); if (comedi_pci_enable(pcidev, driver_hpdi.driver_name)) { @@ -618,7 +623,7 @@ ioremap(priv(dev)->hpdi_phys_iobase, pci_resource_len(pcidev, HPDI_BADDRINDEX)); if (!priv(dev)->plx9080_iobase || !priv(dev)->hpdi_iobase) { - printk(" failed to remap io memory\n"); + printk(KERN_WARNING " failed to remap io memory\n"); return -ENOMEM; } @@ -630,12 +635,13 @@ /* get irq */ if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, driver_hpdi.driver_name, dev)) { - printk(" unable to allocate irq %u\n", pcidev->irq); + printk(KERN_WARNING + " unable to allocate irq %u\n", pcidev->irq); return -EINVAL; } dev->irq = pcidev->irq; - printk(" irq %u\n", dev->irq); + printk(KERN_WARNING " irq %u\n", dev->irq); /* alocate pci dma buffers */ for (i = 0; i < NUM_DMA_BUFFERS; i++) { @@ -653,7 +659,8 @@ &priv(dev)-> dma_desc_phys_addr); if (priv(dev)->dma_desc_phys_addr & 0xf) { - printk(" dma descriptors not quad-word aligned (bug)\n"); + printk(KERN_WARNING + " dma descriptors not quad-word aligned (bug)\n"); return -EIO; } @@ -672,42 +679,39 @@ { unsigned int i; - printk("comedi%d: gsc_hpdi: remove\n", dev->minor); + printk(KERN_WARNING "comedi%d: gsc_hpdi: remove\n", dev->minor); if (dev->irq) free_irq(dev->irq, dev); - if (priv(dev)) { - if (priv(dev)->hw_dev) { - if (priv(dev)->plx9080_iobase) { - disable_plx_interrupts(dev); - iounmap((void *)priv(dev)->plx9080_iobase); - } - if (priv(dev)->hpdi_iobase) - iounmap((void *)priv(dev)->hpdi_iobase); - /* free pci dma buffers */ - for (i = 0; i < NUM_DMA_BUFFERS; i++) { - if (priv(dev)->dio_buffer[i]) - pci_free_consistent(priv(dev)->hw_dev, - DMA_BUFFER_SIZE, - priv(dev)-> - dio_buffer[i], - priv - (dev)->dio_buffer_phys_addr - [i]); - } - /* free dma descriptors */ - if (priv(dev)->dma_desc) + if ((priv(dev)) && (priv(dev)->hw_dev)) { + if (priv(dev)->plx9080_iobase) { + disable_plx_interrupts(dev); + iounmap((void *)priv(dev)->plx9080_iobase); + } + if (priv(dev)->hpdi_iobase) + iounmap((void *)priv(dev)->hpdi_iobase); + /* free pci dma buffers */ + for (i = 0; i < NUM_DMA_BUFFERS; i++) { + if (priv(dev)->dio_buffer[i]) pci_free_consistent(priv(dev)->hw_dev, - sizeof(struct plx_dma_desc) - * NUM_DMA_DESCRIPTORS, - priv(dev)->dma_desc, + DMA_BUFFER_SIZE, priv(dev)-> - dma_desc_phys_addr); - if (priv(dev)->hpdi_phys_iobase) { - comedi_pci_disable(priv(dev)->hw_dev); - } - pci_dev_put(priv(dev)->hw_dev); + dio_buffer[i], + priv + (dev)->dio_buffer_phys_addr + [i]); } + /* free dma descriptors */ + if (priv(dev)->dma_desc) + pci_free_consistent(priv(dev)->hw_dev, + sizeof(struct plx_dma_desc) + * NUM_DMA_DESCRIPTORS, + priv(dev)->dma_desc, + priv(dev)-> + dma_desc_phys_addr); + if (priv(dev)->hpdi_phys_iobase) + comedi_pci_disable(priv(dev)->hw_dev); + pci_dev_put(priv(dev)->hw_dev); } return 0; } @@ -810,15 +814,16 @@ if (err) return 4; - if (cmd->chanlist) { - for (i = 1; i < cmd->chanlist_len; i++) { - if (CR_CHAN(cmd->chanlist[i]) != i) { - /* XXX could support 8 channels or 16 channels */ - comedi_error(dev, - "chanlist must be channels 0 to 31 in order"); - err++; - break; - } + if (!cmd->chanlist) + return 0; + + for (i = 1; i < cmd->chanlist_len; i++) { + if (CR_CHAN(cmd->chanlist[i]) != i) { + /* XXX could support 8 or 16 channels */ + comedi_error(dev, + "chanlist must be ch 0 to 31 in order"); + err++; + break; } } @@ -831,9 +836,9 @@ static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - if (priv(dev)->dio_config_output) { + if (priv(dev)->dio_config_output) return -EINVAL; - } else + else return di_cmd_test(dev, s, cmd); } @@ -899,9 +904,9 @@ static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - if (priv(dev)->dio_config_output) { + if (priv(dev)->dio_config_output) return -EINVAL; - } else + else return di_cmd(dev, s); } @@ -963,14 +968,12 @@ uint8_t dma0_status, dma1_status; unsigned long flags; - if (!dev->attached) { + if (!dev->attached) return IRQ_NONE; - } plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG); - if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0) { + if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0) return IRQ_NONE; - } hpdi_intr_status = readl(priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG); hpdi_board_status = readl(priv(dev)->hpdi_iobase + BOARD_STATUS_REG); @@ -990,9 +993,8 @@ priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); DEBUG_PRINT("dma0 status 0x%x\n", dma0_status); - if (dma0_status & PLX_DMA_EN_BIT) { + if (dma0_status & PLX_DMA_EN_BIT) drain_dma_buffers(dev, 0); - } DEBUG_PRINT(" cleared dma ch0 interrupt\n"); } spin_unlock_irqrestore(&dev->spinlock, flags); @@ -1042,7 +1044,7 @@ return IRQ_HANDLED; } -void abort_dma(struct comedi_device *dev, unsigned int channel) +static void abort_dma(struct comedi_device *dev, unsigned int channel) { unsigned long flags; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/icp_multi.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/icp_multi.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/icp_multi.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/icp_multi.c 2009-11-06 20:57:48.000000000 -0800 @@ -46,7 +46,7 @@ Options: [0] - PCI bus number - if bus number and slot number are 0, - then driver search for first unused card + then driver search for first unused card [1] - PCI slot number */ @@ -133,7 +133,7 @@ Data & Structure declarations ============================================================================== */ -static unsigned short pci_list_builded = 0; /*>0 list of card is known */ +static unsigned short pci_list_builded; /*>0 list of card is known */ struct boardtype { const char *name; /* driver name */ @@ -176,13 +176,13 @@ #define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype)) static struct comedi_driver driver_icp_multi = { -driver_name:"icp_multi", -module:THIS_MODULE, -attach:icp_multi_attach, -detach:icp_multi_detach, -num_names:n_boardtypes, -board_name:&boardtypes[0].name, -offset:sizeof(struct boardtype), +driver_name: "icp_multi", +module : THIS_MODULE, +attach : icp_multi_attach, +detach : icp_multi_detach, +num_names : n_boardtypes, +board_name : &boardtypes[0].name, +offset : sizeof(struct boardtype), }; COMEDI_INITCLEANUP(driver_icp_multi); @@ -234,18 +234,18 @@ /* ============================================================================== - Name: icp_multi_insn_read_ai +Name: icp_multi_insn_read_ai - Description: - This function reads a single analogue input. +Description: + This function reads a single analogue input. - Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to analogue input data +Parameters: + struct comedi_device *dev Pointer to current device structure + struct comedi_subdevice *s Pointer to current subdevice structure + struct comedi_insn *insn Pointer to current comedi instruction + unsigned int *data Pointer to analogue input data - Returns:int Nmuber of instructions executed +Returns:int Nmuber of instructions executed ============================================================================== */ @@ -256,7 +256,7 @@ int n, timeout; #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi EDBG: BGN: icp_multi_insn_read_ai(...)\n"); + printk(KERN_DEBUG "icp multi EDBG: BGN: icp_multi_insn_read_ai(...)\n"); #endif /* Disable A/D conversion ready interrupt */ devpriv->IntEnable &= ~ADC_READY; @@ -266,11 +266,11 @@ devpriv->IntStatus |= ADC_READY; writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT); - /* Set up appropriate channel, mode and range data, for specified channel */ + /* Set up appropriate channel, mode and range data, for specified ch */ setup_channel_list(dev, s, &insn->chanspec, 1); #ifdef ICP_MULTI_EXTDEBUG - printk("icp_multi A ST=%4x IO=%p\n", + printk(KERN_DEBUG "icp_multi A ST=%4x IO=%p\n", readw(devpriv->io_addr + ICP_MULTI_ADC_CSR), devpriv->io_addr + ICP_MULTI_ADC_CSR); #endif @@ -283,14 +283,14 @@ devpriv->AdcCmdStatus &= ~ADC_ST; #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi B n=%d ST=%4x\n", n, + printk(KERN_DEBUG "icp multi B n=%d ST=%4x\n", n, readw(devpriv->io_addr + ICP_MULTI_ADC_CSR)); #endif udelay(1); #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi C n=%d ST=%4x\n", n, + printk(KERN_DEBUG "icp multi C n=%d ST=%4x\n", n, readw(devpriv->io_addr + ICP_MULTI_ADC_CSR)); #endif @@ -303,7 +303,8 @@ #ifdef ICP_MULTI_EXTDEBUG if (!(timeout % 10)) - printk("icp multi D n=%d tm=%d ST=%4x\n", n, + printk(KERN_DEBUG + "icp multi D n=%d tm=%d ST=%4x\n", n, timeout, readw(devpriv->io_addr + ICP_MULTI_ADC_CSR)); @@ -328,9 +329,9 @@ data[n] = 0; #ifdef ICP_MULTI_EXTDEBUG - printk - ("icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n", - n); + printk(KERN_DEBUG + "icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n", + n); #endif return -ETIME; @@ -348,7 +349,8 @@ writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT); #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n", n); + printk(KERN_DEBUG + "icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n", n); #endif return n; } @@ -356,18 +358,18 @@ /* ============================================================================== - Name: icp_multi_insn_write_ao +Name: icp_multi_insn_write_ao - Description: - This function writes a single analogue output. +Description: + This function writes a single analogue output. - Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to analogue output data +Parameters: + struct comedi_device *dev Pointer to current device structure + struct comedi_subdevice *s Pointer to current subdevice structure + struct comedi_insn *insn Pointer to current comedi instruction + unsigned int *data Pointer to analogue output data - Returns:int Nmuber of instructions executed +Returns:int Nmuber of instructions executed ============================================================================== */ @@ -378,7 +380,8 @@ int n, chan, range, timeout; #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi EDBG: BGN: icp_multi_insn_write_ao(...)\n"); + printk(KERN_DEBUG + "icp multi EDBG: BGN: icp_multi_insn_write_ao(...)\n"); #endif /* Disable D/A conversion ready interrupt */ devpriv->IntEnable &= ~DAC_READY; @@ -404,7 +407,8 @@ writew(devpriv->DacCmdStatus, devpriv->io_addr + ICP_MULTI_DAC_CSR); for (n = 0; n < insn->n; n++) { - /* Wait for analogue output data register to be ready for new data, or get fed up waiting */ + /* Wait for analogue output data register to be + * ready for new data, or get fed up waiting */ timeout = 100; while (timeout--) { if (!(readw(devpriv->io_addr + @@ -413,7 +417,8 @@ #ifdef ICP_MULTI_EXTDEBUG if (!(timeout % 10)) - printk("icp multi A n=%d tm=%d ST=%4x\n", n, + printk(KERN_DEBUG + "icp multi A n=%d tm=%d ST=%4x\n", n, timeout, readw(devpriv->io_addr + ICP_MULTI_DAC_CSR)); @@ -438,8 +443,8 @@ devpriv->ao_data[chan] = 0; #ifdef ICP_MULTI_EXTDEBUG - printk - ("icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n", + printk(KERN_DEBUG + "icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n", n); #endif return -ETIME; @@ -459,7 +464,8 @@ } #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n", n); + printk(KERN_DEBUG + "icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n", n); #endif return n; } @@ -467,18 +473,18 @@ /* ============================================================================== - Name: icp_multi_insn_read_ao +Name: icp_multi_insn_read_ao - Description: - This function reads a single analogue output. +Description: + This function reads a single analogue output. - Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to analogue output data +Parameters: + struct comedi_device *dev Pointer to current device structure + struct comedi_subdevice *s Pointer to current subdevice structure + struct comedi_insn *insn Pointer to current comedi instruction + unsigned int *data Pointer to analogue output data - Returns:int Nmuber of instructions executed +Returns:int Nmuber of instructions executed ============================================================================== */ @@ -501,18 +507,18 @@ /* ============================================================================== - Name: icp_multi_insn_bits_di +Name: icp_multi_insn_bits_di - Description: - This function reads the digital inputs. +Description: + This function reads the digital inputs. - Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to analogue output data +Parameters: + struct comedi_device *dev Pointer to current device structure + struct comedi_subdevice *s Pointer to current subdevice structure + struct comedi_insn *insn Pointer to current comedi instruction + unsigned int *data Pointer to analogue output data - Returns:int Nmuber of instructions executed +Returns:int Nmuber of instructions executed ============================================================================== */ @@ -528,18 +534,18 @@ /* ============================================================================== - Name: icp_multi_insn_bits_do +Name: icp_multi_insn_bits_do - Description: - This function writes the appropriate digital outputs. +Description: + This function writes the appropriate digital outputs. - Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to analogue output data +Parameters: + struct comedi_device *dev Pointer to current device structure + struct comedi_subdevice *s Pointer to current subdevice structure + struct comedi_insn *insn Pointer to current comedi instruction + unsigned int *data Pointer to analogue output data - Returns:int Nmuber of instructions executed +Returns:int Nmuber of instructions executed ============================================================================== */ @@ -548,14 +554,14 @@ struct comedi_insn *insn, unsigned int *data) { #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi EDBG: BGN: icp_multi_insn_bits_do(...)\n"); + printk(KERN_DEBUG "icp multi EDBG: BGN: icp_multi_insn_bits_do(...)\n"); #endif if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); - printk("Digital outputs = %4x \n", s->state); + printk(KERN_DEBUG "Digital outputs = %4x \n", s->state); writew(s->state, devpriv->io_addr + ICP_MULTI_DO); } @@ -563,7 +569,7 @@ data[1] = readw(devpriv->io_addr + ICP_MULTI_DI); #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi EDBG: END: icp_multi_insn_bits_do(...)\n"); + printk(KERN_DEBUG "icp multi EDBG: END: icp_multi_insn_bits_do(...)\n"); #endif return 2; } @@ -571,18 +577,18 @@ /* ============================================================================== - Name: icp_multi_insn_read_ctr +Name: icp_multi_insn_read_ctr - Description: - This function reads the specified counter. +Description: + This function reads the specified counter. - Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to counter data +Parameters: + struct comedi_device *dev Pointer to current device structure + struct comedi_subdevice *s Pointer to current subdevice structure + struct comedi_insn *insn Pointer to current comedi instruction + unsigned int *data Pointer to counter data - Returns:int Nmuber of instructions executed +Returns:int Nmuber of instructions executed ============================================================================== */ @@ -596,18 +602,18 @@ /* ============================================================================== - Name: icp_multi_insn_write_ctr +Name: icp_multi_insn_write_ctr - Description: - This function write to the specified counter. +Description: + This function write to the specified counter. - Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_subdevice *s Pointer to current subdevice structure - struct comedi_insn *insn Pointer to current comedi instruction - unsigned int *data Pointer to counter data +Parameters: + struct comedi_device *dev Pointer to current device structure + struct comedi_subdevice *s Pointer to current subdevice structure + struct comedi_insn *insn Pointer to current comedi instruction + unsigned int *data Pointer to counter data - Returns:int Nmuber of instructions executed +Returns:int Nmuber of instructions executed ============================================================================== */ @@ -622,15 +628,15 @@ /* ============================================================================== - Name: interrupt_service_icp_multi +Name: interrupt_service_icp_multi - Description: - This function is the interrupt service routine for all - interrupts generated by the icp multi board. - - Parameters: - int irq - void *d Pointer to current device +Description: + This function is the interrupt service routine for all + interrupts generated by the icp multi board. + +Parameters: + int irq + void *d Pointer to current device ============================================================================== */ @@ -640,7 +646,8 @@ int int_no; #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi EDBG: BGN: interrupt_service_icp_multi(%d,...)\n", + printk(KERN_DEBUG + "icp multi EDBG: BGN: interrupt_service_icp_multi(%d,...)\n", irq); #endif @@ -651,7 +658,8 @@ return IRQ_NONE; #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi EDBG: interrupt_service_icp_multi() ST: %4x\n", + printk(KERN_DEBUG + "icp multi EDBG: interrupt_service_icp_multi() ST: %4x\n", readw(devpriv->io_addr + ICP_MULTI_INT_STAT)); #endif @@ -679,7 +687,8 @@ } #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi EDBG: END: interrupt_service_icp_multi(...)\n"); + printk(KERN_DEBUG + "icp multi EDBG: END: interrupt_service_icp_multi(...)\n"); #endif return IRQ_HANDLED; } @@ -688,20 +697,20 @@ /* ============================================================================== - Name: check_channel_list +Name: check_channel_list - Description: - This function checks if the channel list, provided by user - is built correctly - - Parameters: - struct comedi_device *dev Pointer to current sevice structure - struct comedi_subdevice *s Pointer to current subdevice structure - unsigned int *chanlist Pointer to packed channel list - unsigned int n_chan Number of channels to scan +Description: + This function checks if the channel list, provided by user + is built correctly + +Parameters: + struct comedi_device *dev Pointer to current sevice structure + struct comedi_subdevice *s Pointer to current subdevice structure + unsigned int *chanlist Pointer to packed channel list + unsigned int n_chan Number of channels to scan - Returns:int 0 = failure - 1 = success +Returns:int 0 = failure + 1 = success ============================================================================== */ @@ -712,7 +721,8 @@ unsigned int i; #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi EDBG: check_channel_list(...,%d)\n", n_chan); + printk(KERN_DEBUG + "icp multi EDBG: check_channel_list(...,%d)\n", n_chan); #endif /* Check that we at least have one channel to check */ if (n_chan < 1) { @@ -725,7 +735,7 @@ if (CR_AREF(chanlist[i]) == AREF_DIFF) { if (CR_CHAN(chanlist[i]) > this_board->n_aichand) { comedi_error(dev, - "Incorrect differential ai channel number"); + "Incorrect differential ai ch-nr"); return 0; } } else { @@ -743,20 +753,20 @@ /* ============================================================================== - Name: setup_channel_list +Name: setup_channel_list - Description: - This function sets the appropriate channel selection, - differential input mode and range bits in the ADC Command/ - Status register. - - Parameters: - struct comedi_device *dev Pointer to current sevice structure - struct comedi_subdevice *s Pointer to current subdevice structure - unsigned int *chanlist Pointer to packed channel list - unsigned int n_chan Number of channels to scan +Description: + This function sets the appropriate channel selection, + differential input mode and range bits in the ADC Command/ + Status register. + +Parameters: + struct comedi_device *dev Pointer to current sevice structure + struct comedi_subdevice *s Pointer to current subdevice structure + unsigned int *chanlist Pointer to packed channel list + unsigned int n_chan Number of channels to scan - Returns:Void +Returns:Void ============================================================================== */ @@ -768,7 +778,8 @@ unsigned int diff; #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi EDBG: setup_channel_list(...,%d)\n", n_chan); + printk(KERN_DEBUG + "icp multi EDBG: setup_channel_list(...,%d)\n", n_chan); #endif devpriv->act_chanlist_len = n_chan; devpriv->act_chanlist_pos = 0; @@ -786,7 +797,8 @@ chanprog &= 0x000f; } - /* Clear channel, range and input mode bits in A/D command/status register */ + /* Clear channel, range and input mode bits + * in A/D command/status register */ devpriv->AdcCmdStatus &= 0xf00f; /* Set channel number and differential mode status bit */ @@ -808,7 +820,8 @@ devpriv->io_addr + ICP_MULTI_ADC_CSR); #ifdef ICP_MULTI_EXTDEBUG - printk("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range, + printk(KERN_DEBUG + "GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range, devpriv->act_chanlist[i]); #endif } @@ -818,15 +831,15 @@ /* ============================================================================== - Name: icp_multi_reset +Name: icp_multi_reset - Description: - This function resets the icp multi device to a 'safe' state +Description: + This function resets the icp multi device to a 'safe' state - Parameters: - struct comedi_device *dev Pointer to current sevice structure +Parameters: + struct comedi_device *dev Pointer to current sevice structure - Returns:int 0 = success +Returns:int 0 = success ============================================================================== */ @@ -835,7 +848,8 @@ unsigned int i; #ifdef ICP_MULTI_EXTDEBUG - printk("icp_multi EDBG: BGN: icp_multi_reset(...)\n"); + printk(KERN_DEBUG + "icp_multi EDBG: BGN: icp_multi_reset(...)\n"); #endif /* Clear INT enables and requests */ writew(0, devpriv->io_addr + ICP_MULTI_INT_EN); @@ -866,7 +880,8 @@ writew(0, devpriv->io_addr + ICP_MULTI_DO); #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi EDBG: END: icp_multi_reset(...)\n"); + printk(KERN_DEBUG + "icp multi EDBG: END: icp_multi_reset(...)\n"); #endif return 0; } @@ -874,17 +889,17 @@ /* ============================================================================== - Name: icp_multi_attach +Name: icp_multi_attach - Description: - This function sets up all the appropriate data for the current - device. +Description: + This function sets up all the appropriate data for the current + device. - Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_devconfig *it Pointer to current device configuration +Parameters: + struct comedi_device *dev Pointer to current device structure + struct comedi_devconfig *it Pointer to current device configuration - Returns:int 0 = success +Returns:int 0 = success ============================================================================== */ @@ -898,7 +913,8 @@ resource_size_t io_addr[5], iobase; unsigned char pci_bus, pci_slot, pci_func; - printk("icp_multi EDBG: BGN: icp_multi_attach(...)\n"); + printk(KERN_WARNING + "icp_multi EDBG: BGN: icp_multi_attach(...)\n"); /* Alocate private data storage space */ ret = alloc_private(dev, sizeof(struct icp_multi_private)); @@ -916,7 +932,8 @@ ); } - printk("Anne's comedi%d: icp_multi: board=%s", dev->minor, + printk(KERN_WARNING + "Anne's comedi%d: icp_multi: board=%s", dev->minor, this_board->name); card = select_and_alloc_pci_card(PCI_VENDOR_ID_ICP, @@ -930,24 +947,26 @@ if ((pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0], &irq)) < 0) { - printk(" - Can't get configuration data!\n"); + printk(KERN_WARNING " - Can't get configuration data!\n"); return -EIO; } iobase = io_addr[2]; devpriv->phys_iobase = iobase; - printk(", b:s:f=%d:%d:%d, io=0x%8llx \n", pci_bus, pci_slot, pci_func, + printk(KERN_WARNING + ", b:s:f=%d:%d:%d, io=0x%8llx \n", pci_bus, pci_slot, pci_func, (unsigned long long)iobase); devpriv->io_addr = ioremap(iobase, ICP_MULTI_SIZE); if (devpriv->io_addr == NULL) { - printk("ioremap failed.\n"); + printk(KERN_WARNING "ioremap failed.\n"); return -ENOMEM; } #ifdef ICP_MULTI_EXTDEBUG - printk("0x%08llx mapped to %p, ", (unsigned long long)iobase, + printk(KERN_DEBUG + "0x%08llx mapped to %p, ", (unsigned long long)iobase, devpriv->io_addr); #endif @@ -975,20 +994,20 @@ if (irq) { if (request_irq(irq, interrupt_service_icp_multi, IRQF_SHARED, "Inova Icp Multi", dev)) { - printk - (", unable to allocate IRQ %u, DISABLING IT", + printk(KERN_WARNING + "unable to allocate IRQ %u, DISABLING IT", irq); irq = 0; /* Can't use IRQ */ } else - printk(", irq=%u", irq); + printk(KERN_WARNING ", irq=%u", irq); } else - printk(", IRQ disabled"); + printk(KERN_WARNING ", IRQ disabled"); } else irq = 0; dev->irq = irq; - printk(".\n"); + printk(KERN_WARNING ".\n"); subdev = 0; @@ -1063,7 +1082,7 @@ devpriv->valid = 1; #ifdef ICP_MULTI_EXTDEBUG - printk("icp multi EDBG: END: icp_multi_attach(...)\n"); + printk(KERN_DEBUG "icp multi EDBG: END: icp_multi_attach(...)\n"); #endif return 0; @@ -1072,16 +1091,16 @@ /* ============================================================================== - Name: icp_multi_detach +Name: icp_multi_detach - Description: - This function releases all the resources used by the current - device. +Description: + This function releases all the resources used by the current + device. - Parameters: - struct comedi_device *dev Pointer to current device structure +Parameters: + struct comedi_device *dev Pointer to current device structure - Returns:int 0 = success +Returns:int 0 = success ============================================================================== */ diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/ii_pci20kc.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ii_pci20kc.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/ii_pci20kc.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ii_pci20kc.c 2009-11-06 20:57:48.000000000 -0800 @@ -23,7 +23,8 @@ * no extern trigger implemented * * NOT WORKING (but soon) only 4 on-board differential channels supported - * NOT WORKING (but soon) only ONE di-port and ONE do-port supported instead of 4 digital ports + * NOT WORKING (but soon) only ONE di-port and ONE do-port supported + * instead of 4 digital ports * di-port == Port 0 * do-port == Port 1 * @@ -63,17 +64,17 @@ options for PCI-20006M: first: Analog output channel 0 range configuration - 0 bipolar 10 (-10V -- +10V) - 1 unipolar 10 (0V -- +10V) - 2 bipolar 5 (-5V -- 5V) + 0 bipolar 10 (-10V -- +10V) + 1 unipolar 10 (0V -- +10V) + 2 bipolar 5 (-5V -- 5V) second: Analog output channel 1 range configuration options for PCI-20341M: first: Analog input gain configuration - 0 1 - 1 10 - 2 100 - 3 200 + 0 1 + 1 10 + 2 100 + 3 200 */ /* XXX needs to use ioremap() for compatibility with 2.4 kernels. Should also @@ -95,12 +96,12 @@ #define PCI20000_DIO_3 0xc1 #define PCI20000_DIO_CONTROL_01 0x83 /* port 0, 1 control */ #define PCI20000_DIO_CONTROL_23 0xc3 /* port 2, 3 control */ -#define PCI20000_DIO_BUFFER 0x82 /* buffer direction and enable */ +#define PCI20000_DIO_BUFFER 0x82 /* buffer direction & enable */ #define PCI20000_DIO_EOC 0xef /* even port, control output */ #define PCI20000_DIO_OOC 0xfd /* odd port, control output */ #define PCI20000_DIO_EIC 0x90 /* even port, control input */ #define PCI20000_DIO_OIC 0x82 /* odd port, control input */ -#define DIO_CAND 0x12 /* and bit 1, bit 4 of control */ +#define DIO_CAND 0x12 /* and bit 1 & 4 of control */ #define DIO_BE 0x01 /* buffer: port enable */ #define DIO_BO 0x04 /* buffer: output */ #define DIO_BI 0x05 /* buffer: input */ @@ -137,7 +138,8 @@ void *iobase; struct { void *iobase; - const struct comedi_lrange *ao_range_list[2]; /* range of channels of ao module */ + const struct comedi_lrange *ao_range_list[2]; + /* range of channels of ao module */ unsigned int last_data[2]; } pci20006; struct { @@ -224,14 +226,13 @@ /* Check PCI-20001 C-2A Carrier Board ID */ if ((readb(devpriv->ioaddr) & PCI20000_ID) != PCI20000_ID) { - printk("comedi%d: ii_pci20kc", dev->minor); - printk - (" PCI-20001 C-2A Carrier Board at base=0x%p not found !\n", - devpriv->ioaddr); + printk(KERN_WARNING "comedi%d: ii_pci20kc PCI-20001" + " C-2A Carrier Board at base=0x%p not found !\n", + dev->minor, devpriv->ioaddr); return -EINVAL; } - printk("comedi%d:\n", dev->minor); - printk("ii_pci20kc: PCI-20001 C-2A at base=0x%p\n", devpriv->ioaddr); + printk(KERN_INFO "comedi%d: ii_pci20kc: PCI-20001 C-2A at base=0x%p\n", + dev->minor, devpriv->ioaddr); for (i = 0; i < PCI20000_MODULES; i++) { s = dev->subdevices + i; @@ -244,21 +245,23 @@ devpriv->ioaddr + (i + 1) * PCI20000_OFFSET; pci20006_init(dev, s, it->options[2 * i + 2], it->options[2 * i + 3]); - printk("comedi%d: ii_pci20kc", dev->minor); - printk(" PCI-20006 module in slot %d \n", i + 1); + printk(KERN_INFO "comedi%d: " + "ii_pci20kc PCI-20006 module in slot %d \n", + dev->minor, i + 1); break; case PCI20341_ID: sdp->pci20341.iobase = devpriv->ioaddr + (i + 1) * PCI20000_OFFSET; pci20341_init(dev, s, it->options[2 * i + 2], it->options[2 * i + 3]); - printk("comedi%d: ii_pci20kc", dev->minor); - printk(" PCI-20341 module in slot %d \n", i + 1); + printk(KERN_INFO "comedi%d: " + "ii_pci20kc PCI-20341 module in slot %d \n", + dev->minor, i + 1); break; default: - printk - ("ii_pci20kc: unknown module code 0x%02x in slot %d: module disabled\n", - id, i); + printk(KERN_WARNING "ii_pci20kc: unknown module " + "code 0x%02x in slot %d: module disabled\n", + id, i); /* XXX this looks like a bug! i + 1 ?? */ /* fall through */ case PCI20xxx_EMPTY_ID: s->type = COMEDI_SUBD_UNUSED; @@ -274,7 +277,7 @@ static int pci20xxx_detach(struct comedi_device *dev) { - printk("comedi%d: pci20xxx: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: pci20xxx: remove\n", dev->minor); return 0; } @@ -339,7 +342,8 @@ unsigned int boarddata; sdp->pci20006.last_data[CR_CHAN(insn->chanspec)] = data[0]; - boarddata = (((unsigned int)data[0] + 0x8000) & 0xffff); /* comedi-data -> board-data */ + boarddata = (((unsigned int)data[0] + 0x8000) & 0xffff); + /* comedi-data -> board-data */ lo = (boarddata & 0xff); hi = ((boarddata >> 8) & 0xff); @@ -355,7 +359,8 @@ writeb(0x00, sdp->iobase + PCI20006_STROBE1); break; default: - printk(" comedi%d: pci20xxx: ao channel Error!\n", dev->minor); + printk(KERN_WARNING + " comedi%d: pci20xxx: ao channel Error!\n", dev->minor); return -EINVAL; } @@ -373,8 +378,7 @@ static const struct comedi_lrange range_bipolar0_5 = { 1, {BIP_RANGE(0.5)} }; static const struct comedi_lrange range_bipolar0_05 = { 1, {BIP_RANGE(0.05)} }; -static const struct comedi_lrange range_bipolar0_025 = - { 1, {BIP_RANGE(0.025)} }; +static const struct comedi_lrange range_bipolar0_025 = { 1, {BIP_RANGE(0.025)} }; static const struct comedi_lrange *const pci20341_ranges[] = { &range_bipolar5, @@ -447,9 +451,10 @@ eoc = readb(sdp->iobase + PCI20341_STATUS_REG); } if (j >= 100) { - printk - ("comedi%d: pci20xxx: AI interrupt channel %i polling exit !\n", - dev->minor, i); + printk(KERN_WARNING + "comedi%d: pci20xxx: " + "AI interrupt channel %i polling exit !\n", + dev->minor, i); return -EINVAL; } lo = readb(sdp->iobase + PCI20341_LDATA); @@ -502,20 +507,18 @@ int mask, bits; mask = 1 << CR_CHAN(insn->chanspec); - if (mask & 0x000000ff) { + if (mask & 0x000000ff) bits = 0x000000ff; - } else if (mask & 0x0000ff00) { + else if (mask & 0x0000ff00) bits = 0x0000ff00; - } else if (mask & 0x00ff0000) { + else if (mask & 0x00ff0000) bits = 0x00ff0000; - } else { + else bits = 0xff000000; - } - if (data[0]) { + if (data[0]) s->io_bits |= bits; - } else { + else s->io_bits &= ~bits; - } pci20xxx_dio_config(dev, s); return 1; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/ke_counter.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ke_counter.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/ke_counter.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ke_counter.c 2009-11-06 20:57:48.000000000 -0800 @@ -192,12 +192,14 @@ } } } - printk("comedi%d: no supported board found! (req. bus/slot: %d/%d)\n", + printk(KERN_WARNING + "comedi%d: no supported board found! (req. bus/slot: %d/%d)\n", dev->minor, it->options[0], it->options[1]); return -EIO; found: - printk("comedi%d: found %s at PCI bus %d, slot %d\n", dev->minor, + printk(KERN_INFO + "comedi%d: found %s at PCI bus %d, slot %d\n", dev->minor, board->name, pci_device->bus->number, PCI_SLOT(pci_device->devfn)); devpriv->pcidev = pci_device; @@ -206,9 +208,9 @@ /* enable PCI device and request regions */ error = comedi_pci_enable(pci_device, CNT_DRIVER_NAME); if (error < 0) { - printk - ("comedi%d: failed to enable PCI device and request regions!\n", - dev->minor); + printk(KERN_WARNING "comedi%d: " + "failed to enable PCI device and request regions!\n", + dev->minor); return error; } @@ -239,7 +241,8 @@ outb(0, dev->iobase + 0x20); outb(0, dev->iobase + 0x40); - printk("comedi%d: " CNT_DRIVER_NAME " attached.\n", dev->minor); + printk(KERN_INFO "comedi%d: " CNT_DRIVER_NAME " attached.\n", + dev->minor); return 0; } @@ -248,11 +251,11 @@ static int cnt_detach(struct comedi_device *dev) { if (devpriv && devpriv->pcidev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pcidev); - } pci_dev_put(devpriv->pcidev); } - printk("comedi%d: " CNT_DRIVER_NAME " remove\n", dev->minor); + printk(KERN_INFO "comedi%d: " CNT_DRIVER_NAME " remove\n", + dev->minor); return 0; } diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/mite.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/mite.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/mite.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/mite.c 2009-11-06 20:57:47.000000000 -0800 @@ -64,6 +64,7 @@ MODULE_LICENSE("GPL"); struct mite_struct *mite_devices; +EXPORT_SYMBOL(mite_devices); #define TOP_OF_PAGE(x) ((x)|(~(PAGE_MASK))) @@ -80,7 +81,7 @@ mite = kzalloc(sizeof(*mite), GFP_KERNEL); if (!mite) { - printk("mite: allocation failed\n"); + printk(KERN_ERR "mite: allocation failed\n"); pci_dev_put(pcidev); return; } @@ -99,14 +100,14 @@ static void dump_chip_signature(u32 csigr_bits) { - printk - ("mite: version = %i, type = %i, mite mode = %i, interface mode = %i\n", - mite_csigr_version(csigr_bits), mite_csigr_type(csigr_bits), - mite_csigr_mmode(csigr_bits), mite_csigr_imode(csigr_bits)); - printk - ("mite: num channels = %i, write post fifo depth = %i, wins = %i, iowins = %i\n", - mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits), - mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits)); + printk(KERN_INFO "mite: version = %i, type = %i, mite mode = %i," + "interface mode = %i\n", + mite_csigr_version(csigr_bits), mite_csigr_type(csigr_bits), + mite_csigr_mmode(csigr_bits), mite_csigr_imode(csigr_bits)); + printk(KERN_INFO "mite: num channels = %i, write post fifo depth = %i," + "wins = %i, iowins = %i\n", + mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits), + mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits)); } unsigned mite_fifo_size(struct mite_struct *mite, unsigned channel) @@ -126,7 +127,7 @@ unsigned unknown_dma_burst_bits; if (comedi_pci_enable(mite->pcidev, "mite")) { - printk("error enabling mite and requesting io regions\n"); + printk(KERN_ERR "error enabling mite and requesting io regions\n"); return -EIO; } pci_set_master(mite->pcidev); @@ -135,27 +136,30 @@ mite->mite_phys_addr = addr; mite->mite_io_addr = ioremap(addr, PCI_MITE_SIZE); if (!mite->mite_io_addr) { - printk("failed to remap mite io memory address\n"); + printk(KERN_ERR "Failed to remap mite io memory address\n"); return -ENOMEM; } - printk("MITE:0x%08llx mapped to %p ", + printk(KERN_INFO "MITE:0x%08llx mapped to %p ", (unsigned long long)mite->mite_phys_addr, mite->mite_io_addr); addr = pci_resource_start(mite->pcidev, 1); mite->daq_phys_addr = addr; length = pci_resource_len(mite->pcidev, 1); - /* In case of a 660x board, DAQ size is 8k instead of 4k (see as shown by lspci output) */ + /* + * In case of a 660x board, DAQ size is 8k instead of 4k + * (see as shown by lspci output) + */ mite->daq_io_addr = ioremap(mite->daq_phys_addr, length); if (!mite->daq_io_addr) { - printk("failed to remap daq io memory address\n"); + printk(KERN_ERR "Failed to remap daq io memory address\n"); return -ENOMEM; } - printk("DAQ:0x%08llx mapped to %p\n", + printk(KERN_INFO "DAQ:0x%08llx mapped to %p\n", (unsigned long long)mite->daq_phys_addr, mite->daq_io_addr); if (use_iodwbsr_1) { writel(0, mite->mite_io_addr + MITE_IODWBSR); - printk("mite: using I/O Window Base Size register 1\n"); + printk(KERN_INFO "mite: using I/O Window Base Size register 1\n"); writel(mite->daq_phys_addr | WENAB | MITE_IODWBSR_1_WSIZE_bits(length), mite->mite_io_addr + MITE_IODWBSR_1); @@ -164,11 +168,12 @@ writel(mite->daq_phys_addr | WENAB, mite->mite_io_addr + MITE_IODWBSR); } - /* make sure dma bursts work. I got this from running a bus analyzer - on a pxi-6281 and a pxi-6713. 6713 powered up with register value - of 0x61f and bursts worked. 6281 powered up with register value of - 0x1f and bursts didn't work. The NI windows driver reads the register, - then does a bitwise-or of 0x600 with it and writes it back. + /* + * make sure dma bursts work. I got this from running a bus analyzer + * on a pxi-6281 and a pxi-6713. 6713 powered up with register value + * of 0x61f and bursts worked. 6281 powered up with register value of + * 0x1f and bursts didn't work. The NI windows driver reads the + * register, then does a bitwise-or of 0x600 with it and writes it back. */ unknown_dma_burst_bits = readl(mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG); @@ -179,9 +184,9 @@ csigr_bits = readl(mite->mite_io_addr + MITE_CSIGR); mite->num_channels = mite_csigr_dmac(csigr_bits); if (mite->num_channels > MAX_MITE_DMA_CHANNELS) { - printk - ("mite: bug? chip claims to have %i dma channels. Setting to %i.\n", - mite->num_channels, MAX_MITE_DMA_CHANNELS); + printk(KERN_WARNING "mite: bug? chip claims to have %i dma " + "channels. Setting to %i.\n", + mite->num_channels, MAX_MITE_DMA_CHANNELS); mite->num_channels = MAX_MITE_DMA_CHANNELS; } dump_chip_signature(csigr_bits); @@ -194,16 +199,18 @@ mite->mite_io_addr + MITE_CHCR(i)); } mite->fifo_size = mite_fifo_size(mite, 0); - printk("mite: fifo size is %i.\n", mite->fifo_size); + printk(KERN_INFO "mite: fifo size is %i.\n", mite->fifo_size); mite->used = 1; return 0; } +EXPORT_SYMBOL(mite_setup2); int mite_setup(struct mite_struct *mite) { return mite_setup2(mite, 0); } +EXPORT_SYMBOL(mite_setup); void mite_cleanup(void) { @@ -238,22 +245,23 @@ mite->used = 0; } +EXPORT_SYMBOL(mite_unsetup); void mite_list_devices(void) { struct mite_struct *mite, *next; - printk("Available NI device IDs:"); + printk(KERN_INFO "Available NI device IDs:"); if (mite_devices) for (mite = mite_devices; mite; mite = next) { next = mite->next; - printk(" 0x%04x", mite_device_id(mite)); + printk(KERN_INFO " 0x%04x", mite_device_id(mite)); if (mite->used) - printk("(used)"); + printk(KERN_INFO "(used)"); } - printk("\n"); - + printk(KERN_INFO "\n"); } +EXPORT_SYMBOL(mite_list_devices); struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite, struct @@ -265,7 +273,9 @@ unsigned long flags; struct mite_channel *channel = NULL; - /* spin lock so mite_release_channel can be called safely from interrupts */ + /* spin lock so mite_release_channel can be called safely + * from interrupts + */ spin_lock_irqsave(&mite->lock, flags); for (i = min_channel; i <= max_channel; ++i) { if (mite->channel_allocated[i] == 0) { @@ -278,6 +288,7 @@ spin_unlock_irqrestore(&mite->lock, flags); return channel; } +EXPORT_SYMBOL(mite_request_channel_in_range); void mite_release_channel(struct mite_channel *mite_chan) { @@ -289,8 +300,10 @@ if (mite->channel_allocated[mite_chan->channel]) { mite_dma_disarm(mite_chan); mite_dma_reset(mite_chan); -/* disable all channel's interrupts (do it after disarm/reset so -MITE_CHCR reg isn't changed while dma is still active!) */ + /* + * disable all channel's interrupts (do it after disarm/reset so + * MITE_CHCR reg isn't changed while dma is still active!) + */ writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE | CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE | @@ -302,6 +315,7 @@ } spin_unlock_irqrestore(&mite->lock, flags); } +EXPORT_SYMBOL(mite_release_channel); void mite_dma_arm(struct mite_channel *mite_chan) { @@ -310,8 +324,10 @@ unsigned long flags; MDPRINTK("mite_dma_arm ch%i\n", channel); - /* memory barrier is intended to insure any twiddling with the buffer - is done before writing to the mite to arm dma transfer */ + /* + * memory barrier is intended to insure any twiddling with the buffer + * is done before writing to the mite to arm dma transfer + */ smp_mb(); /* arm */ chor = CHOR_START; @@ -322,6 +338,7 @@ spin_unlock_irqrestore(&mite->lock, flags); /* mite_dma_tcr(mite, channel); */ } +EXPORT_SYMBOL(mite_dma_arm); /**************************************/ @@ -354,7 +371,7 @@ n_links * sizeof(struct mite_dma_descriptor), &ring->descriptors_dma_addr, GFP_KERNEL); if (!ring->descriptors) { - printk("mite: ring buffer allocation failed\n"); + printk(KERN_ERR "mite: ring buffer allocation failed\n"); return -ENOMEM; } ring->n_links = n_links; @@ -370,11 +387,14 @@ } ring->descriptors[n_links - 1].next = cpu_to_le32(ring->descriptors_dma_addr); - /* barrier is meant to insure that all the writes to the dma descriptors - have completed before the dma controller is commanded to read them */ + /* + * barrier is meant to insure that all the writes to the dma descriptors + * have completed before the dma controller is commanded to read them + */ smp_wmb(); return 0; } +EXPORT_SYMBOL(mite_buf_change); void mite_prep_dma(struct mite_channel *mite_chan, unsigned int num_device_bits, unsigned int num_memory_bits) @@ -395,16 +415,19 @@ * Link Complete Interrupt: interrupt every time a link * in MITE_RING is completed. This can generate a lot of * extra interrupts, but right now we update the values - * of buf_int_ptr and buf_int_count at each interrupt. A + * of buf_int_ptr and buf_int_count at each interrupt. A * better method is to poll the MITE before each user * "read()" to calculate the number of bytes available. */ chcr |= CHCR_SET_LC_IE; if (num_memory_bits == 32 && num_device_bits == 16) { - /* Doing a combined 32 and 16 bit byteswap gets the 16 bit samples into the fifo in the right order. - Tested doing 32 bit memory to 16 bit device transfers to the analog out of a pxi-6281, - which has mite version = 1, type = 4. This also works for dma reads from the counters - on e-series boards. */ + /* + * Doing a combined 32 and 16 bit byteswap gets the 16 bit + * samples into the fifo in the right order. Tested doing 32 bit + * memory to 16 bit device transfers to the analog out of a + * pxi-6281, which has mite version = 1, type = 4. This also + * works for dma reads from the counters on e-series boards. + */ chcr |= CHCR_BYTE_SWAP_DEVICE | CHCR_BYTE_SWAP_MEMORY; } if (mite_chan->dir == COMEDI_INPUT) @@ -425,7 +448,8 @@ mcr |= CR_PSIZE32; break; default: - printk("mite: bug! invalid mem bit width for dma transfer\n"); + printk(KERN_WARNING "mite: bug! invalid mem bit width for dma " + "transfer\n"); break; } writel(mcr, mite->mite_io_addr + MITE_MCR(mite_chan->channel)); @@ -444,7 +468,8 @@ dcr |= CR_PSIZE32; break; default: - printk("mite: bug! invalid dev bit width for dma transfer\n"); + printk(KERN_WARNING "mite: bug! invalid dev bit width for dma " + "transfer\n"); break; } writel(dcr, mite->mite_io_addr + MITE_DCR(mite_chan->channel)); @@ -462,6 +487,7 @@ MDPRINTK("exit mite_prep_dma\n"); } +EXPORT_SYMBOL(mite_prep_dma); u32 mite_device_bytes_transferred(struct mite_channel *mite_chan) { @@ -469,48 +495,53 @@ return readl(mite->mite_io_addr + MITE_DAR(mite_chan->channel)); } -u32 mite_bytes_in_transit(struct mite_channel * mite_chan) +u32 mite_bytes_in_transit(struct mite_channel *mite_chan) { struct mite_struct *mite = mite_chan->mite; return readl(mite->mite_io_addr + MITE_FCR(mite_chan->channel)) & 0x000000FF; } +EXPORT_SYMBOL(mite_bytes_in_transit); -/* returns lower bound for number of bytes transferred from device to memory */ -u32 mite_bytes_written_to_memory_lb(struct mite_channel * mite_chan) +/* returns lower bound for number of bytes transferred from device to memory */ +u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan) { u32 device_byte_count; device_byte_count = mite_device_bytes_transferred(mite_chan); return device_byte_count - mite_bytes_in_transit(mite_chan); } +EXPORT_SYMBOL(mite_bytes_written_to_memory_lb); -/* returns upper bound for number of bytes transferred from device to memory */ -u32 mite_bytes_written_to_memory_ub(struct mite_channel * mite_chan) +/* returns upper bound for number of bytes transferred from device to memory */ +u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan) { u32 in_transit_count; in_transit_count = mite_bytes_in_transit(mite_chan); return mite_device_bytes_transferred(mite_chan) - in_transit_count; } +EXPORT_SYMBOL(mite_bytes_written_to_memory_ub); -/* returns lower bound for number of bytes read from memory for transfer to device */ -u32 mite_bytes_read_from_memory_lb(struct mite_channel * mite_chan) +/* returns lower bound for number of bytes read from memory to device */ +u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan) { u32 device_byte_count; device_byte_count = mite_device_bytes_transferred(mite_chan); return device_byte_count + mite_bytes_in_transit(mite_chan); } +EXPORT_SYMBOL(mite_bytes_read_from_memory_lb); -/* returns upper bound for number of bytes read from memory for transfer to device */ -u32 mite_bytes_read_from_memory_ub(struct mite_channel * mite_chan) +/* returns upper bound for number of bytes read from memory to device */ +u32 mite_bytes_read_from_memory_ub(struct mite_channel *mite_chan) { u32 in_transit_count; in_transit_count = mite_bytes_in_transit(mite_chan); return mite_device_bytes_transferred(mite_chan) + in_transit_count; } +EXPORT_SYMBOL(mite_bytes_read_from_memory_ub); unsigned mite_dma_tcr(struct mite_channel *mite_chan) { @@ -525,6 +556,7 @@ return tcr; } +EXPORT_SYMBOL(mite_dma_tcr); void mite_dma_disarm(struct mite_channel *mite_chan) { @@ -535,6 +567,7 @@ chor = CHOR_ABORT; writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel)); } +EXPORT_SYMBOL(mite_dma_disarm); int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_async *async) @@ -544,7 +577,7 @@ const unsigned bytes_per_scan = cfc_bytes_per_scan(async->subdevice); old_alloc_count = async->buf_write_alloc_count; - /* write alloc as much as we can */ + /* write alloc as much as we can */ comedi_buf_write_alloc(async, async->prealloc_bufsz); nbytes = mite_bytes_written_to_memory_lb(mite_chan); @@ -571,6 +604,7 @@ async->events |= COMEDI_CB_BLOCK; return 0; } +EXPORT_SYMBOL(mite_sync_input_dma); int mite_sync_output_dma(struct mite_channel *mite_chan, struct comedi_async *async) @@ -593,7 +627,7 @@ (int)(nbytes_ub - stop_count) > 0) nbytes_ub = stop_count; if ((int)(nbytes_ub - old_alloc_count) > 0) { - printk("mite: DMA underrun\n"); + printk(KERN_ERR "mite: DMA underrun\n"); async->events |= COMEDI_CB_OVERFLOW; return -1; } @@ -607,6 +641,7 @@ } return 0; } +EXPORT_SYMBOL(mite_sync_output_dma); unsigned mite_get_status(struct mite_channel *mite_chan) { @@ -625,6 +660,7 @@ spin_unlock_irqrestore(&mite->lock, flags); return status; } +EXPORT_SYMBOL(mite_get_status); int mite_done(struct mite_channel *mite_chan) { @@ -638,6 +674,7 @@ spin_unlock_irqrestore(&mite->lock, flags); return done; } +EXPORT_SYMBOL(mite_done); #ifdef DEBUG_MITE @@ -719,46 +756,51 @@ unsigned long addr = 0; unsigned long temp = 0; - printk("mite_dump_regs ch%i\n", mite_chan->channel); - printk("mite address is =0x%08lx\n", mite_io_addr); + printk(KERN_DEBUG "mite_dump_regs ch%i\n", mite_chan->channel); + printk(KERN_DEBUG "mite address is =0x%08lx\n", mite_io_addr); addr = mite_io_addr + MITE_CHOR(channel); - printk("mite status[CHOR]at 0x%08lx =0x%08lx\n", addr, temp = - readl(addr)); + printk(KERN_DEBUG "mite status[CHOR]at 0x%08lx =0x%08lx\n", addr, + temp = readl(addr)); mite_decode(mite_CHOR_strings, temp); addr = mite_io_addr + MITE_CHCR(channel); - printk("mite status[CHCR]at 0x%08lx =0x%08lx\n", addr, temp = - readl(addr)); + printk(KERN_DEBUG "mite status[CHCR]at 0x%08lx =0x%08lx\n", addr, + temp = readl(addr)); mite_decode(mite_CHCR_strings, temp); addr = mite_io_addr + MITE_TCR(channel); - printk("mite status[TCR] at 0x%08lx =0x%08x\n", addr, readl(addr)); - addr = mite_io_addr + MITE_MCR(channel); - printk("mite status[MCR] at 0x%08lx =0x%08lx\n", addr, temp = + printk(KERN_DEBUG "mite status[TCR] at 0x%08lx =0x%08x\n", addr, readl(addr)); + addr = mite_io_addr + MITE_MCR(channel); + printk(KERN_DEBUG "mite status[MCR] at 0x%08lx =0x%08lx\n", addr, + temp = readl(addr)); mite_decode(mite_MCR_strings, temp); addr = mite_io_addr + MITE_MAR(channel); - printk("mite status[MAR] at 0x%08lx =0x%08x\n", addr, readl(addr)); - addr = mite_io_addr + MITE_DCR(channel); - printk("mite status[DCR] at 0x%08lx =0x%08lx\n", addr, temp = + printk(KERN_DEBUG "mite status[MAR] at 0x%08lx =0x%08x\n", addr, readl(addr)); + addr = mite_io_addr + MITE_DCR(channel); + printk(KERN_DEBUG "mite status[DCR] at 0x%08lx =0x%08lx\n", addr, + temp = readl(addr)); mite_decode(mite_DCR_strings, temp); addr = mite_io_addr + MITE_DAR(channel); - printk("mite status[DAR] at 0x%08lx =0x%08x\n", addr, readl(addr)); - addr = mite_io_addr + MITE_LKCR(channel); - printk("mite status[LKCR]at 0x%08lx =0x%08lx\n", addr, temp = + printk(KERN_DEBUG "mite status[DAR] at 0x%08lx =0x%08x\n", addr, readl(addr)); + addr = mite_io_addr + MITE_LKCR(channel); + printk(KERN_DEBUG "mite status[LKCR]at 0x%08lx =0x%08lx\n", addr, + temp = readl(addr)); mite_decode(mite_LKCR_strings, temp); addr = mite_io_addr + MITE_LKAR(channel); - printk("mite status[LKAR]at 0x%08lx =0x%08x\n", addr, readl(addr)); - - addr = mite_io_addr + MITE_CHSR(channel); - printk("mite status[CHSR]at 0x%08lx =0x%08lx\n", addr, temp = + printk(KERN_DEBUG "mite status[LKAR]at 0x%08lx =0x%08x\n", addr, readl(addr)); + addr = mite_io_addr + MITE_CHSR(channel); + printk(KERN_DEBUG "mite status[CHSR]at 0x%08lx =0x%08lx\n", addr, + temp = readl(addr)); mite_decode(mite_CHSR_strings, temp); addr = mite_io_addr + MITE_FCR(channel); - printk("mite status[FCR] at 0x%08lx =0x%08x\n\n", addr, readl(addr)); + printk(KERN_DEBUG "mite status[FCR] at 0x%08lx =0x%08x\n\n", addr, + readl(addr)); } +EXPORT_SYMBOL(mite_dump_regs); static void mite_decode(char **bit_str, unsigned int bits) { @@ -766,10 +808,11 @@ for (i = 31; i >= 0; i--) { if (bits & (1 << i)) - printk(" %s", bit_str[i]); + printk(KERN_DEBUG " %s", bit_str[i]); } - printk("\n"); + printk(KERN_DEBUG "\n"); } +EXPORT_SYMBOL(mite_decode); #endif #ifdef MODULE @@ -785,36 +828,4 @@ { mite_cleanup(); } - -EXPORT_SYMBOL(mite_dma_tcr); -EXPORT_SYMBOL(mite_dma_arm); -EXPORT_SYMBOL(mite_dma_disarm); -EXPORT_SYMBOL(mite_sync_input_dma); -EXPORT_SYMBOL(mite_sync_output_dma); -EXPORT_SYMBOL(mite_setup); -EXPORT_SYMBOL(mite_setup2); -EXPORT_SYMBOL(mite_unsetup); -#if 0 -EXPORT_SYMBOL(mite_kvmem_segment_load); -EXPORT_SYMBOL(mite_ll_from_kvmem); -EXPORT_SYMBOL(mite_setregs); -#endif -EXPORT_SYMBOL(mite_devices); -EXPORT_SYMBOL(mite_list_devices); -EXPORT_SYMBOL(mite_request_channel_in_range); -EXPORT_SYMBOL(mite_release_channel); -EXPORT_SYMBOL(mite_prep_dma); -EXPORT_SYMBOL(mite_buf_change); -EXPORT_SYMBOL(mite_bytes_written_to_memory_lb); -EXPORT_SYMBOL(mite_bytes_written_to_memory_ub); -EXPORT_SYMBOL(mite_bytes_read_from_memory_lb); -EXPORT_SYMBOL(mite_bytes_read_from_memory_ub); -EXPORT_SYMBOL(mite_bytes_in_transit); -EXPORT_SYMBOL(mite_get_status); -EXPORT_SYMBOL(mite_done); -#ifdef DEBUG_MITE -EXPORT_SYMBOL(mite_decode); -EXPORT_SYMBOL(mite_dump_regs); -#endif - #endif diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/mite.h linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/mite.h --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/mite.h 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/mite.h 2009-11-06 20:57:47.000000000 -0800 @@ -163,13 +163,6 @@ unsigned mite_get_status(struct mite_channel *mite_chan); int mite_done(struct mite_channel *mite_chan); -#if 0 -unsigned long mite_ll_from_kvmem(struct mite_struct *mite, - struct comedi_async *async, int len); -void mite_setregs(struct mite_struct *mite, unsigned long ll_start, int chan, - int dir); -#endif - void mite_prep_dma(struct mite_channel *mite_chan, unsigned int num_device_bits, unsigned int num_memory_bits); int mite_buf_change(struct mite_dma_descriptor_ring *ring, diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/multiq3.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/multiq3.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/multiq3.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/multiq3.c 2009-11-06 20:57:47.000000000 -0800 @@ -144,9 +144,8 @@ int i; int chan = CR_CHAN(insn->chanspec); - for (i = 0; i < insn->n; i++) { + for (i = 0; i < insn->n; i++) data[i] = devpriv->ao_readback[chan]; - } return i; } @@ -253,20 +252,20 @@ struct comedi_subdevice *s; iobase = it->options[0]; - printk("comedi%d: multiq3: 0x%04lx ", dev->minor, iobase); + printk(KERN_INFO "comedi%d: multiq3: 0x%04lx ", dev->minor, iobase); if (!request_region(iobase, MULTIQ3_SIZE, "multiq3")) { - printk("comedi%d: I/O port conflict\n", dev->minor); + printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor); return -EIO; } dev->iobase = iobase; irq = it->options[1]; - if (irq) { - printk("comedi%d: irq = %u ignored\n", dev->minor, irq); - } else { - printk("comedi%d: no irq\n", dev->minor); - } + if (irq) + printk(KERN_WARNING "comedi%d: irq = %u ignored\n", + dev->minor, irq); + else + printk(KERN_WARNING "comedi%d: no irq\n", dev->minor); dev->board_name = "multiq3"; result = alloc_subdevices(dev, 5); if (result < 0) @@ -330,14 +329,12 @@ static int multiq3_detach(struct comedi_device *dev) { - printk("comedi%d: multiq3: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: multiq3: remove\n", dev->minor); - if (dev->iobase) { + if (dev->iobase) release_region(dev->iobase, MULTIQ3_SIZE); - } - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } return 0; } diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_6527.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_6527.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_6527.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_6527.c 2009-11-06 20:57:47.000000000 -0800 @@ -273,7 +273,8 @@ if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* step 2: make sure trigger sources are unique and */ + /* are mutually compatible */ if (err) return 2; @@ -377,7 +378,7 @@ struct comedi_subdevice *s; int ret; - printk("comedi%d: ni6527:", dev->minor); + printk(KERN_INFO "comedi%d: ni6527\n", dev->minor); ret = alloc_private(dev, sizeof(struct ni6527_private)); if (ret < 0) @@ -389,14 +390,13 @@ ret = mite_setup(devpriv->mite); if (ret < 0) { - printk("error setting up mite\n"); + printk(KERN_ERR "comedi: error setting up mite\n"); return ret; } dev->board_name = this_board->name; - printk(" %s", dev->board_name); - - printk(" ID=0x%02x", readb(devpriv->mite->daq_io_addr + ID_Register)); + printk(KERN_INFO "comedi board: %s, ID=0x%02x\n", dev->board_name, + readb(devpriv->mite->daq_io_addr + ID_Register)); ret = alloc_subdevices(dev, 3); if (ret < 0) @@ -415,7 +415,7 @@ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 24; - s->range_table = &range_unknown; /* FIXME: actually conductance */ + s->range_table = &range_unknown; /* FIXME: actually conductance */ s->maxdata = 1; s->insn_bits = ni6527_do_insn_bits; @@ -442,30 +442,25 @@ ret = request_irq(mite_irq(devpriv->mite), ni6527_interrupt, IRQF_SHARED, "ni6527", dev); - if (ret < 0) { - printk(" irq not available"); - } else + if (ret < 0) + printk(KERN_WARNING "comedi i6527 irq not available\n"); + else dev->irq = mite_irq(devpriv->mite); - printk("\n"); - return 0; } static int ni6527_detach(struct comedi_device *dev) { - if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) { + if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control); - } - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } - if (devpriv && devpriv->mite) { + if (devpriv && devpriv->mite) mite_unsetup(devpriv->mite); - } return 0; } @@ -491,7 +486,7 @@ } } } - printk("no device found\n"); + printk(KERN_ERR "comedi 6527: no device found\n"); mite_list_devices(); return -EIO; } diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_at_ao.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_at_ao.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_at_ao.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_at_ao.c 2009-11-06 20:57:47.000000000 -0800 @@ -32,7 +32,8 @@ [0] - I/O port base address [1] - IRQ (unused) [2] - DMA (unused) - [3] - analog output range, set by jumpers on hardware (0 for -10 to 10V bipolar, 1 for 0V to 10V unipolar) + [3] - analog output range, set by jumpers on hardware (0 for -10 to 10V + bipolar, 1 for 0V to 10V unipolar) */ /* @@ -431,9 +432,8 @@ struct comedi_insn *insn, unsigned int *data) { int i; - for (i = 0; i < insn->n; i++) { + for (i = 0; i < insn->n; i++) data[i] = 0; /* XXX */ - } return insn->n; } diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_atmio16d.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_atmio16d.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_atmio16d.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_atmio16d.c 2009-11-06 20:57:47.000000000 -0800 @@ -200,8 +200,8 @@ enum { dac_2comp, dac_straight } dac0_coding, dac1_coding; const struct comedi_lrange *ao_range_type_list[2]; unsigned int ao_readback[2]; - unsigned int com_reg_1_state; /* current state of command register 1 */ - unsigned int com_reg_2_state; /* current state of command register 2 */ + unsigned int com_reg_1_state; /* current state of command register 1 */ + unsigned int com_reg_2_state; /* current state of command register 2 */ }; static void reset_counters(struct comedi_device *dev) @@ -279,7 +279,9 @@ struct comedi_device *dev = d; struct comedi_subdevice *s = dev->subdevices + 0; -/* printk("atmio16d_interrupt!\n"); */ +#ifdef DEBUG1 + printk(KERN_DEBUG "atmio16d_interrupt!\n"); +#endif comedi_buf_put(s->async, inw(dev->iobase + AD_FIFO_REG)); @@ -293,7 +295,7 @@ { int err = 0, tmp; #ifdef DEBUG1 - printk("atmio16d_ai_cmdtest\n"); + printk(KERN_DEBUG "atmio16d_ai_cmdtest\n"); #endif /* make sure triggers are valid */ tmp = cmd->start_src; @@ -324,8 +326,8 @@ if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ - /* note that mutual compatiblity is not an issue here */ + /* step 2: make sure trigger sources are unique & mutually compatible */ + /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->scan_begin_src != TRIG_EXT && cmd->scan_begin_src != TRIG_TIMER) @@ -397,7 +399,7 @@ unsigned int sample_count, tmp, chan, gain; int i; #ifdef DEBUG1 - printk("atmio16d_ai_cmd\n"); + printk(KERN_DEBUG "atmio16d_ai_cmd\n"); #endif /* This is slowly becoming a working command interface. * * It is still uber-experimental */ @@ -436,10 +438,10 @@ } else if (cmd->convert_arg < 655360000) { base_clock = CLOCK_100_KHZ; timer = cmd->convert_arg / 10000; - } else if (cmd->convert_arg <= 0xffffffff /* 6553600000 */ ) { + } else if (cmd->convert_arg <= 0xffffffff /* 6553600000 */) { base_clock = CLOCK_10_KHZ; timer = cmd->convert_arg / 100000; - } else if (cmd->convert_arg <= 0xffffffff /* 65536000000 */ ) { + } else if (cmd->convert_arg <= 0xffffffff /* 65536000000 */) { base_clock = CLOCK_1_KHZ; timer = cmd->convert_arg / 1000000; } @@ -504,10 +506,10 @@ } else if (cmd->scan_begin_arg < 655360000) { base_clock = CLOCK_100_KHZ; timer = cmd->scan_begin_arg / 10000; - } else if (cmd->scan_begin_arg < 0xffffffff /* 6553600000 */ ) { + } else if (cmd->scan_begin_arg < 0xffffffff /* 6553600000 */) { base_clock = CLOCK_10_KHZ; timer = cmd->scan_begin_arg / 100000; - } else if (cmd->scan_begin_arg < 0xffffffff /* 65536000000 */ ) { + } else if (cmd->scan_begin_arg < 0xffffffff /* 65536000000 */) { base_clock = CLOCK_1_KHZ; timer = cmd->scan_begin_arg / 1000000; } @@ -559,7 +561,7 @@ int status; #ifdef DEBUG1 - printk("atmio16d_ai_insn_read\n"); + printk(KERN_DEBUG "atmio16d_ai_insn_read\n"); #endif chan = CR_CHAN(insn->chanspec); gain = CR_RANGE(insn->chanspec); @@ -580,19 +582,18 @@ /* check conversion status */ status = inw(dev->iobase + STAT_REG); #ifdef DEBUG1 - printk("status=%x\n", status); + printk(KERN_DEBUG "status=%x\n", status); #endif if (status & STAT_AD_CONVAVAIL) { /* read the data now */ data[i] = inw(dev->iobase + AD_FIFO_REG); /* change to two's complement if need be */ - if (devpriv->adc_coding == adc_2comp) { + if (devpriv->adc_coding == adc_2comp) data[i] ^= 0x800; - } break; } if (status & STAT_AD_OVERFLOW) { - printk("atmio16d: a/d FIFO overflow\n"); + printk(KERN_INFO "atmio16d: a/d FIFO overflow\n"); outw(0, dev->iobase + AD_CLEAR_REG); return -ETIME; @@ -600,7 +601,7 @@ } /* end waiting, now check if it timed out */ if (t == ATMIO16D_TIMEOUT) { - printk("atmio16d: timeout\n"); + printk(KERN_INFO "atmio16d: timeout\n"); return -ETIME; } @@ -615,13 +616,11 @@ { int i; #ifdef DEBUG1 - printk("atmio16d_ao_insn_read\n"); + printk(KERN_DEBUG "atmio16d_ao_insn_read\n"); #endif - for (i = 0; i < insn->n; i++) { + for (i = 0; i < insn->n; i++) data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)]; - } - return i; } @@ -633,7 +632,7 @@ int chan; int d; #ifdef DEBUG1 - printk("atmio16d_ao_insn_write\n"); + printk(KERN_DEBUG "atmio16d_ao_insn_write\n"); #endif chan = CR_CHAN(insn->chanspec); @@ -642,15 +641,13 @@ d = data[i]; switch (chan) { case 0: - if (devpriv->dac0_coding == dac_2comp) { + if (devpriv->dac0_coding == dac_2comp) d ^= 0x800; - } outw(d, dev->iobase + DAC0_REG); break; case 1: - if (devpriv->dac1_coding == dac_2comp) { + if (devpriv->dac1_coding == dac_2comp) d ^= 0x800; - } outw(d, dev->iobase + DAC1_REG); break; default: @@ -705,29 +702,29 @@ /* options[0] - I/O port options[1] - MIO irq - 0 == no irq - N == irq N {3,4,5,6,7,9,10,11,12,14,15} + 0 == no irq + N == irq N {3,4,5,6,7,9,10,11,12,14,15} options[2] - DIO irq - 0 == no irq - N == irq N {3,4,5,6,7,9} + 0 == no irq + N == irq N {3,4,5,6,7,9} options[3] - DMA1 channel - 0 == no DMA - N == DMA N {5,6,7} + 0 == no DMA + N == DMA N {5,6,7} options[4] - DMA2 channel - 0 == no DMA - N == DMA N {5,6,7} + 0 == no DMA + N == DMA N {5,6,7} options[5] - a/d mux - 0=differential, 1=single + 0=differential, 1=single options[6] - a/d range - 0=bipolar10, 1=bipolar5, 2=unipolar10 + 0=bipolar10, 1=bipolar5, 2=unipolar10 options[7] - dac0 range - 0=bipolar, 1=unipolar + 0=bipolar, 1=unipolar options[8] - dac0 reference - 0=internal, 1=external + 0=internal, 1=external options[9] - dac0 coding - 0=2's comp, 1=straight binary + 0=2's comp, 1=straight binary options[10] - dac1 range options[11] - dac1 reference @@ -745,7 +742,7 @@ /* make sure the address range is free and allocate it */ iobase = it->options[0]; - printk("comedi%d: atmio16d: 0x%04lx ", dev->minor, iobase); + printk(KERN_INFO "comedi%d: atmio16d: 0x%04lx ", dev->minor, iobase); if (!request_region(iobase, ATMIO16D_SIZE, "ni_atmio16d")) { printk("I/O port conflict\n"); return -EIO; @@ -772,13 +769,13 @@ ret = request_irq(irq, atmio16d_interrupt, 0, "atmio16d", dev); if (ret < 0) { - printk("failed to allocate irq %u\n", irq); + printk(KERN_INFO "failed to allocate irq %u\n", irq); return ret; } dev->irq = irq; - printk("( irq = %u )\n", irq); + printk(KERN_INFO "( irq = %u )\n", irq); } else { - printk("( no irq )"); + printk(KERN_INFO "( no irq )"); } /* set device options */ @@ -855,11 +852,10 @@ /* 8255 subdevice */ s++; - if (boardtype->has_8255) { + if (boardtype->has_8255) subdev_8255_init(dev, s, NULL, dev->iobase); - } else { + else s->type = COMEDI_SUBD_UNUSED; - } /* don't yet know how to deal with counter/timers */ #if 0 @@ -876,7 +872,7 @@ static int atmio16d_detach(struct comedi_device *dev) { - printk("comedi%d: atmio16d: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: atmio16d: remove\n", dev->minor); if (dev->subdevices && boardtype->has_8255) subdev_8255_cleanup(dev, dev->subdevices + 3); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_labpc_cs.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_labpc_cs.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_labpc_cs.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_labpc_cs.c 2009-11-06 20:57:47.000000000 -0800 @@ -59,8 +59,7 @@ */ -#undef LABPC_DEBUG - /* #define LABPC_DEBUG *//* enable debugging messages */ +#undef LABPC_DEBUG /* debugging messages */ #include "../comedidev.h" @@ -77,14 +76,15 @@ #include #include -static struct pcmcia_device *pcmcia_cur_dev = NULL; +static struct pcmcia_device *pcmcia_cur_dev; static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it); static const struct labpc_board_struct labpc_cs_boards[] = { { .name = "daqcard-1200", - .device_id = 0x103, /* 0x10b is manufacturer id, 0x103 is device id */ + .device_id = 0x103, /* 0x10b is manufacturer id, + 0x103 is device id */ .ai_speed = 10000, .bustype = pcmcia_bustype, .register_layout = labpc_1200_layout, @@ -163,7 +163,7 @@ #ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; module_param(pc_debug, int, 0644); -#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) +#define DEBUG(n, args...) if (pc_debug > (n)) printk(KERN_DEBUG args) static const char *version = "ni_labpc.c, based on dummy_cs.c 1.31 2001/08/24 12:13:13"; #else @@ -291,9 +291,8 @@ labpc_release(link); } - /* This points to the parent local_info_t struct */ - if (link->priv) - kfree(link->priv); + /* This points to the parent local_info_t struct (may be null) */ + kfree(link->priv); } /* labpc_cs_detach */ @@ -402,7 +401,8 @@ link->io.BasePort2 = io->win[1].base; link->io.NumPorts2 = io->win[1].len; } - /* This reserves IO space but doesn't actually enable it */ + /* This reserves IO space but doesn't + actually enable it */ if (pcmcia_request_io(link, &link->io)) goto next_entry; } diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_labpc.h linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_labpc.h --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_labpc.h 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_labpc.h 2009-11-06 20:57:47.000000000 -0800 @@ -38,19 +38,27 @@ int device_id; /* device id for pci and pcmcia boards */ int ai_speed; /* maximum input speed in nanoseconds */ enum labpc_bustype bustype; /* ISA/PCI/etc. */ - enum labpc_register_layout register_layout; /* 1200 has extra registers compared to pc+ */ + + /* 1200 has extra registers compared to pc+ */ + enum labpc_register_layout register_layout; int has_ao; /* has analog output true/false */ const struct comedi_lrange *ai_range_table; const int *ai_range_code; const int *ai_range_is_unipolar; - unsigned ai_scan_up:1; /* board can auto scan up in ai channels, not just down */ - unsigned memory_mapped_io:1; /* uses memory mapped io instead of ioports */ + + /* board can auto scan up in ai channels, not just down */ + unsigned ai_scan_up:1; + + /* uses memory mapped io instead of ioports */ + unsigned memory_mapped_io:1; }; struct labpc_private { struct mite_struct *mite; /* for mite chip on pci-1200 */ - volatile unsigned long long count; /* number of data points left to be taken */ - unsigned int ao_value[NUM_AO_CHAN]; /* software copy of analog output values */ + /* number of data points left to be taken */ + volatile unsigned long long count; + /* software copy of analog output values */ + unsigned int ao_value[NUM_AO_CHAN]; /* software copys of bits written to command registers */ volatile unsigned int command1_bits; volatile unsigned int command2_bits; @@ -61,16 +69,34 @@ /* store last read of board status registers */ volatile unsigned int status1_bits; volatile unsigned int status2_bits; - unsigned int divisor_a0; /* value to load into board's counter a0 (conversion pacing) for timed conversions */ - unsigned int divisor_b0; /* value to load into board's counter b0 (master) for timed conversions */ - unsigned int divisor_b1; /* value to load into board's counter b1 (scan pacing) for timed conversions */ + /* + * value to load into board's counter a0 (conversion pacing) for timed + * conversions + */ + unsigned int divisor_a0; + /* + * value to load into board's counter b0 (master) for timed conversions + */ + unsigned int divisor_b0; + /* + * value to load into board's counter b1 (scan pacing) for timed + * conversions + */ + unsigned int divisor_b1; unsigned int dma_chan; /* dma channel to use */ u16 *dma_buffer; /* buffer ai will dma into */ - unsigned int dma_transfer_size; /* transfer size in bytes for current transfer */ - enum transfer_type current_transfer; /* we are using dma/fifo-half-full/etc. */ - unsigned int eeprom_data[EEPROM_SIZE]; /* stores contents of board's eeprom */ - unsigned int caldac[16]; /* stores settings of calibration dacs */ - /* function pointers so we can use inb/outb or readb/writeb as appropriate */ + /* transfer size in bytes for current transfer */ + unsigned int dma_transfer_size; + /* we are using dma/fifo-half-full/etc. */ + enum transfer_type current_transfer; + /* stores contents of board's eeprom */ + unsigned int eeprom_data[EEPROM_SIZE]; + /* stores settings of calibration dacs */ + unsigned int caldac[16]; + /* + * function pointers so we can use inb/outb or readb/writeb as + * appropriate + */ unsigned int (*read_byte) (unsigned long address); void (*write_byte) (unsigned int byte, unsigned long address); }; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_mio_common.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_mio_common.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_mio_common.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_mio_common.c 2009-11-06 20:57:47.000000000 -0800 @@ -2207,7 +2207,7 @@ /* step 2: make sure trigger sources are unique and mutually compatible */ - /* note that mutual compatiblity is not an issue here */ + /* note that mutual compatibility is not an issue here */ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) err++; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_mio_cs.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_mio_cs.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_mio_cs.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_mio_cs.c 2009-11-06 20:57:47.000000000 -0800 @@ -250,9 +250,8 @@ /* PCMCIA layer frees the IO region */ - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } return 0; } @@ -294,9 +293,8 @@ { DPRINTK("cs_detach(link=%p)\n", link); - if (link->dev_node) { + if (link->dev_node) cs_release(link); - } } static int mio_cs_suspend(struct pcmcia_device *link) @@ -393,9 +391,8 @@ link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1; link->irq.IRQInfo2 = parse.cftable_entry.irq.IRQInfo2; ret = pcmcia_request_irq(link, &link->irq); - if (ret) { + if (ret) printk("pcmcia_request_irq() returned error: %i\n", ret); - } /* printk("RequestIRQ 0x%02x\n",ret); */ link->conf.ConfigIndex = 1; @@ -437,9 +434,8 @@ } printk("\n"); printk(" board fingerprint (windowed):"); - for (i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) printk(" 0x%04x", win_in(i)); - } printk("\n"); } #endif @@ -503,9 +499,8 @@ id = get_prodid(dev, link); for (i = 0; i < n_ni_boards; i++) { - if (ni_boards[i].device_id == id) { + if (ni_boards[i].device_id == id) return i; - } } printk("unknown board 0x%04x -- pretend it is a ", id); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_pcidio.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_pcidio.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/ni_pcidio.c 2009-11-04 15:20:35.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/ni_pcidio.c 2009-11-06 20:57:47.000000000 -0800 @@ -795,7 +795,7 @@ /* step 2: make sure trigger sources are unique and mutually compatible */ - /* note that mutual compatiblity is not an issue here */ + /* note that mutual compatibility is not an issue here */ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT) err++; if (cmd->scan_begin_src != TRIG_TIMER && diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/pcl726.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/pcl726.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/pcl726.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/pcl726.c 2009-11-06 20:57:47.000000000 -0800 @@ -39,27 +39,27 @@ Options for PCL-726: [0] - IO Base [2]...[7] - D/A output range for channel 1-6: - 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, - 4: 4-20mA, 5: unknown (external reference) + 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, + 4: 4-20mA, 5: unknown (external reference) Options for PCL-727: [0] - IO Base [2]...[13] - D/A output range for channel 1-12: - 0: 0-5V, 1: 0-10V, 2: +/-5V, - 3: 4-20mA + 0: 0-5V, 1: 0-10V, 2: +/-5V, + 3: 4-20mA Options for PCL-728 and ACL-6128: [0] - IO Base [2], [3] - D/A output range for channel 1 and 2: - 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, - 4: 4-20mA, 5: 0-20mA + 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, + 4: 4-20mA, 5: 0-20mA Options for ACL-6126: [0] - IO Base [1] - IRQ (0=disable, 3, 5, 6, 7, 9, 10, 11, 12, 15) (currently ignored) [2]...[7] - D/A output range for channel 1-6: - 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, - 4: 4-20mA + 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, + 4: 4-20mA */ /* @@ -127,7 +127,8 @@ int di_lo; int do_hi; int do_lo; - const struct comedi_lrange *const *range_type_list; /* list of supported ranges */ + const struct comedi_lrange *const *range_type_list; + /* list of supported ranges */ }; static const struct pcl726_board boardtypes[] = { @@ -204,9 +205,8 @@ int chan = CR_CHAN(insn->chanspec); int n; - for (n = 0; n < insn->n; n++) { + for (n = 0; n < insn->n; n++) data[n] = devpriv->ao_readback[chan]; - } return n; } @@ -256,10 +256,10 @@ iobase = it->options[0]; iorange = this_board->io_range; - printk("comedi%d: pcl726: board=%s, 0x%03lx ", dev->minor, + printk(KERN_WARNING "comedi%d: pcl726: board=%s, 0x%03lx ", dev->minor, this_board->name, iobase); if (!request_region(iobase, iorange, "pcl726")) { - printk("I/O port conflict\n"); + printk(KERN_WARNING "I/O port conflict\n"); return -EIO; } @@ -283,16 +283,16 @@ devpriv->first_chan = 2; if (irq) { /* we want to use IRQ */ if (((1 << irq) & boardtypes[board].IRQbits) == 0) { - printk - (", IRQ %d is out of allowed range, DISABLING IT", - irq); + printk(KERN_WARNING + ", IRQ %d is out of allowed range," + " DISABLING IT", irq); irq = 0; /* Bad IRQ */ } else { if (request_irq(irq, interrupt_pcl818, 0, "pcl726", dev)) { - printk - (", unable to allocate IRQ %d, DISABLING IT", - irq); + printk(KERN_WARNING + ", unable to allocate IRQ %d," + " DISABLING IT", irq); irq = 0; /* Can't use IRQ */ } else { printk(", irq=%d", irq); @@ -372,9 +372,8 @@ /* printk("comedi%d: pcl726: remove\n",dev->minor); */ #ifdef ACL6126_IRQ - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } #endif if (dev->iobase) diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/pcm_common.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/pcm_common.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/pcm_common.c 2009-10-05 16:45:22.000000000 -0700 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/pcm_common.c 2009-11-06 20:57:47.000000000 -0800 @@ -41,7 +41,8 @@ if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* step 2: make sure trigger sources are unique and + * mutually compatible */ /* these tests are true if more than one _src bit is set */ if ((cmd->start_src & (cmd->start_src - 1)) != 0) @@ -107,5 +108,4 @@ return 0; } - EXPORT_SYMBOL(comedi_pcm_cmdtest); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/pcmmio.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/pcmmio.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/pcmmio.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/pcmmio.c 2009-11-06 20:57:47.000000000 -0800 @@ -32,8 +32,10 @@ four subdevices: subdevice 0 - 16 channels of 16-bit AI subdevice 1 - 8 channels of 16-bit AO - subdevice 2 - first 24 channels of the 48 channel of DIO (with edge-triggered interrupt support) - subdevice 3 - last 24 channels of the 48 channel DIO (no interrupt support for this bank of channels) + subdevice 2 - first 24 channels of the 48 channel of DIO + (with edge-triggered interrupt support) + subdevice 3 - last 24 channels of the 48 channel DIO + (no interrupt support for this bank of channels) Some notes: @@ -70,7 +72,8 @@ Configuration Options: [0] - I/O port base address - [1] - IRQ (optional -- for edge-detect interrupt support only, leave out if you don't need this feature) + [1] - IRQ (optional -- for edge-detect interrupt support only, + leave out if you don't need this feature) */ #include @@ -115,9 +118,11 @@ #define REG_PORT4 0x4 #define REG_PORT5 0x5 #define REG_INT_PENDING 0x6 -#define REG_PAGELOCK 0x7 /* page selector register, upper 2 bits select a page - and bits 0-5 are used to 'lock down' a particular - port above to make it readonly. */ +#define REG_PAGELOCK 0x7 /* + * page selector register, upper 2 bits select + * a page and bits 0-5 are used to 'lock down' + * a particular port above to make it readonly. + */ #define REG_POL0 0x8 #define REG_POL1 0x9 #define REG_POL2 0xA @@ -134,7 +139,7 @@ #define REG_PAGE_BITOFFSET 6 #define REG_LOCK_BITOFFSET 0 #define REG_PAGE_MASK (~((0x1<asics[asic].num = asic; devpriv->asics[asic].iobase = dev->iobase + 16 + asic * ASIC_IOSIZE; - devpriv->asics[asic].irq = 0; /* this gets actually set at the end of - this function when we - request_irqs */ + /* + * this gets actually set at the end of this function when we + * request_irqs + */ + devpriv->asics[asic].irq = 0; spin_lock_init(&devpriv->asics[asic].spinlock); } @@ -463,7 +492,10 @@ if (thisasic_chanct < CHANS_PER_PORT * INTR_PORTS_PER_ASIC && subpriv->dio.intr.asic < 0) { - /* this is an interrupt subdevice, so setup the struct */ + /* + * this is an interrupt subdevice, + * so setup the struct + */ subpriv->dio.intr.asic = asic; subpriv->dio.intr.active = 0; subpriv->dio.intr.stop_count = 0; @@ -484,7 +516,11 @@ chans_left -= s->n_chan; if (!chans_left) { - asic = 0; /* reset the asic to our first asic, to do intr subdevs */ + /* + * reset the asic to our first asic, + * to do intr subdevs + */ + asic = 0; port = 0; } @@ -507,8 +543,10 @@ devpriv->asics[asic].irq = irq[asic]; } - dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple - irqs.. */ + dev->irq = irq[0]; /* + * grr.. wish comedi dev struct supported + * multiple irqs.. + */ if (irq[0]) { printk("irq: %u ", irq[0]); @@ -604,9 +642,14 @@ #endif if (write_mask_byte) { - /* this byte has some write_bits -- so set the output lines */ - byte &= ~write_mask_byte; /* clear bits for write mask */ - byte |= ~data_byte & write_mask_byte; /* set to inverted data_byte */ + /* + * this byte has some write_bits + * -- so set the output lines + */ + /* clear bits for write mask */ + byte &= ~write_mask_byte; + /* set to inverted data_byte */ + byte |= ~data_byte & write_mask_byte; /* Write out the new digital output state */ outb(byte, ioaddr); } @@ -670,9 +713,11 @@ byte &= ~(1 << bit_no); /**< set input channel to '0' */ - /* write out byte -- this is the only time we actually affect the - hardware as all channels are implicitly output -- but input - channels are set to float-high */ + /* + * write out byte -- this is the only time we actually affect + * the hardware as all channels are implicitly output + * -- but input channels are set to float-high + */ outb(byte, ioaddr); /* save to io_bits */ @@ -726,8 +771,8 @@ outb(0xff, baseaddr + REG_ENAB0); */ /* END DEBUG */ - switch_page(dev, asic, 0); /* switch back to default page 0 */ - + /* switch back to default page 0 */ + switch_page(dev, asic, 0); } } @@ -806,7 +851,10 @@ REG_INT_ID0 + port); if (io_lines_with_edges) - /* clear pending interrupt */ + /* + * clear pending + * interrupt + */ outb(0, iobase + REG_INT_ID0 + port); @@ -825,14 +873,21 @@ if (triggered) { struct comedi_subdevice *s; - /* TODO here: dispatch io lines to subdevs with commands.. */ + /* + * TODO here: dispatch io lines to subdevs + * with commands.. + */ printk ("PCMMIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n", irq, asic, triggered); for (s = dev->subdevices + 2; s < dev->subdevices + dev->n_subdevices; ++s) { - if (subpriv->dio.intr.asic == asic) { /* this is an interrupt subdev, and it matches this asic! */ + /* + * this is an interrupt subdev, + * and it matches this asic! + */ + if (subpriv->dio.intr.asic == asic) { unsigned long flags; unsigned oldevents; @@ -867,9 +922,8 @@ n < len; n++) { ch = CR_CHAN(s->async->cmd.chanlist[n]); - if (mytrig & (1U << ch)) { + if (mytrig & (1U << ch)) val |= (1U << n); - } } /* Write the scan to the buffer. */ if (comedi_buf_put(s->async, ((short *)&val)[0]) @@ -877,8 +931,7 @@ comedi_buf_put (s->async, ((short *) - &val)[1])) - { + &val)[1])) { s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); } else { /* Overflow! Stop acquisition!! */ @@ -981,9 +1034,16 @@ 1) << subpriv->dio.intr.first_chan; subpriv->dio.intr.enabled_mask = bits; - { /* the below code configures the board to use a specific IRQ from 0-15. */ + { + /* + * the below code configures the board + * to use a specific IRQ from 0-15. + */ unsigned char b; - /* set resource enable register to enable IRQ operation */ + /* + * set resource enable register + * to enable IRQ operation + */ outb(1 << 4, dev->iobase + 3); /* set bits 0-3 of b to the irq number from 0-15 */ b = dev->irq & ((1 << 4) - 1); @@ -1037,14 +1097,12 @@ spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags); s->async->inttrig = 0; - if (subpriv->dio.intr.active) { + if (subpriv->dio.intr.active) event = pcmmio_start_intr(dev, s); - } spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags); - if (event) { + if (event) comedi_event(dev, s); - } return 1; } @@ -1086,9 +1144,8 @@ } spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags); - if (event) { + if (event) comedi_event(dev, s); - } return 0; } @@ -1136,17 +1193,32 @@ short sample, adc_adjust = 0; if (chan > 7) - chan -= 8, iooffset = 4; /* use the second dword for channels > 7 */ + chan -= 8, iooffset = 4; /* + * use the second dword + * for channels > 7 + */ if (aref != AREF_DIFF) { aref = AREF_GROUND; - command_byte |= 1 << 7; /* set bit 7 to indicate single-ended */ + command_byte |= 1 << 7; /* + * set bit 7 to indicate + * single-ended + */ } if (range < 2) - adc_adjust = 0x8000; /* bipolar ranges (-5,5 .. -10,10 need to be adjusted -- that is.. they need to wrap around by adding 0x8000 */ + adc_adjust = 0x8000; /* + * bipolar ranges + * (-5,5 .. -10,10 need to be + * adjusted -- that is.. they + * need to wrap around by + * adding 0x8000 + */ if (chan % 2) { - command_byte |= 1 << 6; /* odd-numbered channels have bit 6 set */ + command_byte |= 1 << 6; /* + * odd-numbered channels + * have bit 6 set + */ } /* select the channel, bits 4-5 == chan/2 */ @@ -1156,16 +1228,22 @@ command_byte |= (range & 0x3) << 2; /* need to do this twice to make sure mux settled */ - outb(command_byte, iobase + iooffset + 2); /* chan/range/aref select */ + /* chan/range/aref select */ + outb(command_byte, iobase + iooffset + 2); - adc_wait_ready(iobase + iooffset); /* wait for the adc to say it finised the conversion */ + /* wait for the adc to say it finised the conversion */ + adc_wait_ready(iobase + iooffset); - outb(command_byte, iobase + iooffset + 2); /* select the chan/range/aref AGAIN */ + /* select the chan/range/aref AGAIN */ + outb(command_byte, iobase + iooffset + 2); adc_wait_ready(iobase + iooffset); - sample = inb(iobase + iooffset + 0); /* read data lo byte */ - sample |= inb(iobase + iooffset + 1) << 8; /* read data hi byte */ + /* read data lo byte */ + sample = inb(iobase + iooffset + 0); + + /* read data hi byte */ + sample |= inb(iobase + iooffset + 1) << 8; sample += adc_adjust; /* adjustment .. munge data */ data[n] = sample; } @@ -1227,15 +1305,24 @@ wait_dac_ready(iobase + iooffset); - outb(data[n] & 0xff, iobase + iooffset + 0); /* low order byte */ - outb((data[n] >> 8) & 0xff, iobase + iooffset + 1); /* high order byte */ - command_byte = 0x70 | (chan << 1); /* set bit 4 of command byte to indicate data is loaded and trigger conversion */ + /* low order byte */ + outb(data[n] & 0xff, iobase + iooffset + 0); + + /* high order byte */ + outb((data[n] >> 8) & 0xff, iobase + iooffset + 1); + + /* + * set bit 4 of command byte to indicate + * data is loaded and trigger conversion + */ + command_byte = 0x70 | (chan << 1); /* trigger converion */ outb(command_byte, iobase + iooffset + 2); wait_dac_ready(iobase + iooffset); - subpriv->ao.shadow_samples[chan] = data[n]; /* save to shadow register for ao_rinsn */ + /* save to shadow register for ao_rinsn */ + subpriv->ao.shadow_samples[chan] = data[n]; } } return n; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/quatech_daqp_cs.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/quatech_daqp_cs.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/quatech_daqp_cs.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/quatech_daqp_cs.c 2009-11-06 20:57:47.000000000 -0800 @@ -506,7 +506,7 @@ /* step 2: make sure trigger sources are unique and mutually compatible */ - /* note that mutual compatiblity is not an issue here */ + /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_TIMER && cmd->scan_begin_src != TRIG_FOLLOW) err++; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/rtd520.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/rtd520.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/rtd520.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/rtd520.c 2009-11-06 20:57:47.000000000 -0800 @@ -1768,7 +1768,7 @@ /* step 2: make sure trigger sources are unique and mutually compatible */ - /* note that mutual compatiblity is not an issue here */ + /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_TIMER && cmd->scan_begin_src != TRIG_EXT) { err++; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/s626.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/s626.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/s626.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/s626.c 2009-11-06 20:57:47.000000000 -0800 @@ -1926,7 +1926,7 @@ /* step 2: make sure trigger sources are unique and mutually compatible */ - /* note that mutual compatiblity is not an issue here */ + /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_TIMER && cmd->scan_begin_src != TRIG_EXT && cmd->scan_begin_src != TRIG_FOLLOW) diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/s626.h linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/s626.h --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/s626.h 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/s626.h 2009-11-06 20:57:47.000000000 -0800 @@ -76,14 +76,6 @@ #define FALSE (0) #endif -#if !defined(EXTERN) -#if defined(__cplusplus) -#define EXTERN extern "C" -#else -#define EXTERN extern -#endif -#endif - #if !defined(INLINE) #define INLINE static __inline #endif diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/serial2002.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/serial2002.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/serial2002.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/serial2002.c 2009-11-06 20:57:47.000000000 -0800 @@ -125,14 +125,9 @@ static long tty_ioctl(struct file *f, unsigned op, unsigned long param) { -#ifdef HAVE_UNLOCKED_IOCTL - if (f->f_op->unlocked_ioctl) { + if (f->f_op->unlocked_ioctl) return f->f_op->unlocked_ioctl(f, op, param); - } -#endif - if (f->f_op->ioctl) { - return f->f_op->ioctl(f->f_dentry->d_inode, f, op, param); - } + return -ENOSYS; } diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/skel.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/skel.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/skel.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/skel.c 2009-11-06 20:57:47.000000000 -0800 @@ -399,7 +399,7 @@ /* step 2: make sure trigger sources are unique and mutually compatible */ - /* note that mutual compatiblity is not an issue here */ + /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_TIMER && cmd->scan_begin_src != TRIG_EXT) err++; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/usbdux.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/usbdux.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/usbdux.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/usbdux.c 2009-11-06 20:57:47.000000000 -0800 @@ -979,7 +979,7 @@ /* * step 2: make sure trigger sources are unique and mutually compatible - * note that mutual compatiblity is not an issue here + * note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->scan_begin_src != TRIG_EXT && @@ -1557,7 +1557,7 @@ /* * step 2: make sure trigger sources are unique and mutually compatible - * note that mutual compatiblity is not an issue here + * note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->scan_begin_src != TRIG_EXT && @@ -2327,9 +2327,11 @@ if (ret) { dev_err(&usbdev->dev, "Could not upload firmware (err=%d)\n", ret); - return; + goto out; } comedi_usb_auto_config(usbdev, BOARDNAME); + out: + release_firmware(fw); } /* allocate memory for the urbs and initialise them */ @@ -2580,6 +2582,7 @@ FW_ACTION_HOTPLUG, "usbdux_firmware.bin", &udev->dev, + GFP_KERNEL, usbduxsub + index, usbdux_firmware_request_complete_handler); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/usbduxfast.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/usbduxfast.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/usbduxfast.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/usbduxfast.c 2009-11-06 20:57:04.000000000 -0800 @@ -1451,10 +1451,12 @@ if (ret) { dev_err(&usbdev->dev, "Could not upload firmware (err=%d)\n", ret); - return; + goto out; } comedi_usb_auto_config(usbdev, BOARDNAME); + out: + release_firmware(fw); } /* @@ -1569,6 +1571,7 @@ FW_ACTION_HOTPLUG, "usbduxfast_firmware.bin", &udev->dev, + GFP_KERNEL, usbduxfastsub + index, usbduxfast_firmware_request_complete_handler); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers/vmk80xx.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/vmk80xx.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers/vmk80xx.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers/vmk80xx.c 2009-11-06 20:57:47.000000000 -0800 @@ -76,18 +76,18 @@ }; static struct usb_device_id vmk80xx_id_table[] = { - {USB_DEVICE(0x10cf, 0x5500),.driver_info = DEVICE_VMK8055}, - {USB_DEVICE(0x10cf, 0x5501),.driver_info = DEVICE_VMK8055}, - {USB_DEVICE(0x10cf, 0x5502),.driver_info = DEVICE_VMK8055}, - {USB_DEVICE(0x10cf, 0x5503),.driver_info = DEVICE_VMK8055}, - {USB_DEVICE(0x10cf, 0x8061),.driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8062),.driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8063),.driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8064),.driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8065),.driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8066),.driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8067),.driver_info = DEVICE_VMK8061}, - {USB_DEVICE(0x10cf, 0x8068),.driver_info = DEVICE_VMK8061}, + {USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055}, + {USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055}, + {USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055}, + {USB_DEVICE(0x10cf, 0x5503), .driver_info = DEVICE_VMK8055}, + {USB_DEVICE(0x10cf, 0x8061), .driver_info = DEVICE_VMK8061}, + {USB_DEVICE(0x10cf, 0x8062), .driver_info = DEVICE_VMK8061}, + {USB_DEVICE(0x10cf, 0x8063), .driver_info = DEVICE_VMK8061}, + {USB_DEVICE(0x10cf, 0x8064), .driver_info = DEVICE_VMK8061}, + {USB_DEVICE(0x10cf, 0x8065), .driver_info = DEVICE_VMK8061}, + {USB_DEVICE(0x10cf, 0x8066), .driver_info = DEVICE_VMK8061}, + {USB_DEVICE(0x10cf, 0x8067), .driver_info = DEVICE_VMK8061}, + {USB_DEVICE(0x10cf, 0x8068), .driver_info = DEVICE_VMK8061}, {} /* terminating entry */ }; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/comedi/drivers.c linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers.c --- linux-2.6.32-rc6/drivers/staging/comedi/drivers.c 2009-11-04 15:20:34.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/comedi/drivers.c 2009-11-06 20:57:47.000000000 -0800 @@ -387,7 +387,7 @@ return 1; } -static inline unsigned long uvirt_to_kva(pgd_t * pgd, unsigned long adr) +static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) { unsigned long ret = 0UL; pmd_t *pmd; diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/cx25821/cx25821-core.c linux-2.6.32-rc6-staging/drivers/staging/cx25821/cx25821-core.c --- linux-2.6.32-rc6/drivers/staging/cx25821/cx25821-core.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/cx25821/cx25821-core.c 2009-11-06 20:57:48.000000000 -0800 @@ -1521,7 +1521,7 @@ .resume = NULL, }; -static int cx25821_init(void) +static int __init cx25821_init(void) { INIT_LIST_HEAD(&cx25821_devlist); printk(KERN_INFO "cx25821 driver version %d.%d.%d loaded\n", @@ -1530,7 +1530,7 @@ return pci_register_driver(&cx25821_pci_driver); } -static void cx25821_fini(void) +static void __exit cx25821_fini(void) { pci_unregister_driver(&cx25821_pci_driver); } diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/dream/camera/Kconfig linux-2.6.32-rc6-staging/drivers/staging/dream/camera/Kconfig --- linux-2.6.32-rc6/drivers/staging/dream/camera/Kconfig 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/dream/camera/Kconfig 1969-12-31 16:00:00.000000000 -0800 @@ -1,46 +0,0 @@ -comment "Qualcomm MSM Camera And Video" - -menuconfig MSM_CAMERA - bool "Qualcomm MSM camera and video capture support" - depends on ARCH_MSM && VIDEO_V4L2_COMMON - help - Say Y here to enable selecting the video adapters for - Qualcomm msm camera and video encoding - -config MSM_CAMERA_DEBUG - bool "Qualcomm MSM camera debugging with printk" - depends on MSM_CAMERA - help - Enable printk() debug for msm camera - -config MSM_CAMERA_FLASH - bool "Qualcomm MSM camera flash support" - depends on MSM_CAMERA - ---help--- - Enable support for LED flash for msm camera - - -comment "Camera Sensor Selection" -config MT9T013 - bool "Sensor mt9t013 (BAYER 3M)" - depends on MSM_CAMERA - ---help--- - MICRON 3M Bayer Sensor with AutoFocus - -config MT9D112 - bool "Sensor mt9d112 (YUV 2M)" - depends on MSM_CAMERA - ---help--- - MICRON 2M YUV Sensor - -config MT9P012 - bool "Sensor mt9p012 (BAYER 5M)" - depends on MSM_CAMERA - ---help--- - MICRON 5M Bayer Sensor with Autofocus - -config S5K3E2FX - bool "Sensor s5k3e2fx (Samsung 5M)" - depends on MSM_CAMERA - ---help--- - Samsung 5M with Autofocus diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/dream/camera/Makefile linux-2.6.32-rc6-staging/drivers/staging/dream/camera/Makefile --- linux-2.6.32-rc6/drivers/staging/dream/camera/Makefile 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/dream/camera/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,7 +0,0 @@ -obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o -obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o -obj-$(CONFIG_MT9P012) += mt9p012_fox.o mt9p012_reg.o -obj-$(CONFIG_MSM_CAMERA) += msm_camera.o msm_v4l2.o -obj-$(CONFIG_S5K3E2FX) += s5k3e2fx.o -obj-$(CONFIG_ARCH_MSM) += msm_vfe7x.o msm_io7x.o -obj-$(CONFIG_ARCH_QSD) += msm_vfe8x.o msm_vfe8x_proc.o msm_io8x.o diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/dream/camera/msm_camera.c linux-2.6.32-rc6-staging/drivers/staging/dream/camera/msm_camera.c --- linux-2.6.32-rc6/drivers/staging/dream/camera/msm_camera.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/dream/camera/msm_camera.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,2181 +0,0 @@ -/* - * Copyright (C) 2008-2009 QUALCOMM Incorporated. - */ - -//FIXME: most allocations need not be GFP_ATOMIC -/* FIXME: management of mutexes */ -/* FIXME: msm_pmem_region_lookup return values */ -/* FIXME: way too many copy to/from user */ -/* FIXME: does region->active mean free */ -/* FIXME: check limits on command lenghts passed from userspace */ -/* FIXME: __msm_release: which queues should we flush when opencnt != 0 */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define MSM_MAX_CAMERA_SENSORS 5 - -#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \ - __func__, __LINE__, ((to) ? "to" : "from")) -#define ERR_COPY_FROM_USER() ERR_USER_COPY(0) -#define ERR_COPY_TO_USER() ERR_USER_COPY(1) - -static struct class *msm_class; -static dev_t msm_devno; -static LIST_HEAD(msm_sensors); - -#define __CONTAINS(r, v, l, field) ({ \ - typeof(r) __r = r; \ - typeof(v) __v = v; \ - typeof(v) __e = __v + l; \ - int res = __v >= __r->field && \ - __e <= __r->field + __r->len; \ - res; \ -}) - -#define CONTAINS(r1, r2, field) ({ \ - typeof(r2) __r2 = r2; \ - __CONTAINS(r1, __r2->field, __r2->len, field); \ -}) - -#define IN_RANGE(r, v, field) ({ \ - typeof(r) __r = r; \ - typeof(v) __vv = v; \ - int res = ((__vv >= __r->field) && \ - (__vv < (__r->field + __r->len))); \ - res; \ -}) - -#define OVERLAPS(r1, r2, field) ({ \ - typeof(r1) __r1 = r1; \ - typeof(r2) __r2 = r2; \ - typeof(__r2->field) __v = __r2->field; \ - typeof(__v) __e = __v + __r2->len - 1; \ - int res = (IN_RANGE(__r1, __v, field) || \ - IN_RANGE(__r1, __e, field)); \ - res; \ -}) - -#define MSM_DRAIN_QUEUE_NOSYNC(sync, name) do { \ - struct msm_queue_cmd *qcmd = NULL; \ - CDBG("%s: draining queue "#name"\n", __func__); \ - while (!list_empty(&(sync)->name)) { \ - qcmd = list_first_entry(&(sync)->name, \ - struct msm_queue_cmd, list); \ - list_del_init(&qcmd->list); \ - kfree(qcmd); \ - }; \ -} while(0) - -#define MSM_DRAIN_QUEUE(sync, name) do { \ - unsigned long flags; \ - spin_lock_irqsave(&(sync)->name##_lock, flags); \ - MSM_DRAIN_QUEUE_NOSYNC(sync, name); \ - spin_unlock_irqrestore(&(sync)->name##_lock, flags); \ -} while(0) - -static int check_overlap(struct hlist_head *ptype, - unsigned long paddr, - unsigned long len) -{ - struct msm_pmem_region *region; - struct msm_pmem_region t = { .paddr = paddr, .len = len }; - struct hlist_node *node; - - hlist_for_each_entry(region, node, ptype, list) { - if (CONTAINS(region, &t, paddr) || - CONTAINS(&t, region, paddr) || - OVERLAPS(region, &t, paddr)) { - printk(KERN_ERR - " region (PHYS %p len %ld)" - " clashes with registered region" - " (paddr %p len %ld)\n", - (void *)t.paddr, t.len, - (void *)region->paddr, region->len); - return -1; - } - } - - return 0; -} - -static int msm_pmem_table_add(struct hlist_head *ptype, - struct msm_pmem_info *info) -{ - struct file *file; - unsigned long paddr; - unsigned long vstart; - unsigned long len; - int rc; - struct msm_pmem_region *region; - - rc = get_pmem_file(info->fd, &paddr, &vstart, &len, &file); - if (rc < 0) { - pr_err("msm_pmem_table_add: get_pmem_file fd %d error %d\n", - info->fd, rc); - return rc; - } - - if (check_overlap(ptype, paddr, len) < 0) - return -EINVAL; - - CDBG("%s: type = %d, paddr = 0x%lx, vaddr = 0x%lx\n", - __func__, - info->type, paddr, (unsigned long)info->vaddr); - - region = kmalloc(sizeof(*region), GFP_KERNEL); - if (!region) - return -ENOMEM; - - INIT_HLIST_NODE(®ion->list); - - region->type = info->type; - region->vaddr = info->vaddr; - region->paddr = paddr; - region->len = len; - region->file = file; - region->y_off = info->y_off; - region->cbcr_off = info->cbcr_off; - region->fd = info->fd; - region->active = info->active; - - hlist_add_head(&(region->list), ptype); - - return 0; -} - -/* return of 0 means failure */ -static uint8_t msm_pmem_region_lookup(struct hlist_head *ptype, - int pmem_type, struct msm_pmem_region *reg, uint8_t maxcount) -{ - struct msm_pmem_region *region; - struct msm_pmem_region *regptr; - struct hlist_node *node, *n; - - uint8_t rc = 0; - - regptr = reg; - - hlist_for_each_entry_safe(region, node, n, ptype, list) { - if (region->type == pmem_type && region->active) { - *regptr = *region; - rc += 1; - if (rc >= maxcount) - break; - regptr++; - } - } - - return rc; -} - -static unsigned long msm_pmem_frame_ptov_lookup(struct msm_sync *sync, - unsigned long pyaddr, - unsigned long pcbcraddr, - uint32_t *yoff, uint32_t *cbcroff, int *fd) -{ - struct msm_pmem_region *region; - struct hlist_node *node, *n; - - hlist_for_each_entry_safe(region, node, n, &sync->frame, list) { - if (pyaddr == (region->paddr + region->y_off) && - pcbcraddr == (region->paddr + - region->cbcr_off) && - region->active) { - /* offset since we could pass vaddr inside - * a registerd pmem buffer - */ - *yoff = region->y_off; - *cbcroff = region->cbcr_off; - *fd = region->fd; - region->active = 0; - return (unsigned long)(region->vaddr); - } - } - - return 0; -} - -static unsigned long msm_pmem_stats_ptov_lookup(struct msm_sync *sync, - unsigned long addr, int *fd) -{ - struct msm_pmem_region *region; - struct hlist_node *node, *n; - - hlist_for_each_entry_safe(region, node, n, &sync->stats, list) { - if (addr == region->paddr && region->active) { - /* offset since we could pass vaddr inside a - * registered pmem buffer */ - *fd = region->fd; - region->active = 0; - return (unsigned long)(region->vaddr); - } - } - - return 0; -} - -static unsigned long msm_pmem_frame_vtop_lookup(struct msm_sync *sync, - unsigned long buffer, - uint32_t yoff, uint32_t cbcroff, int fd) -{ - struct msm_pmem_region *region; - struct hlist_node *node, *n; - - hlist_for_each_entry_safe(region, - node, n, &sync->frame, list) { - if (((unsigned long)(region->vaddr) == buffer) && - (region->y_off == yoff) && - (region->cbcr_off == cbcroff) && - (region->fd == fd) && - (region->active == 0)) { - - region->active = 1; - return region->paddr; - } - } - - return 0; -} - -static unsigned long msm_pmem_stats_vtop_lookup( - struct msm_sync *sync, - unsigned long buffer, - int fd) -{ - struct msm_pmem_region *region; - struct hlist_node *node, *n; - - hlist_for_each_entry_safe(region, node, n, &sync->stats, list) { - if (((unsigned long)(region->vaddr) == buffer) && - (region->fd == fd) && region->active == 0) { - region->active = 1; - return region->paddr; - } - } - - return 0; -} - -static int __msm_pmem_table_del(struct msm_sync *sync, - struct msm_pmem_info *pinfo) -{ - int rc = 0; - struct msm_pmem_region *region; - struct hlist_node *node, *n; - - switch (pinfo->type) { - case MSM_PMEM_OUTPUT1: - case MSM_PMEM_OUTPUT2: - case MSM_PMEM_THUMBAIL: - case MSM_PMEM_MAINIMG: - case MSM_PMEM_RAW_MAINIMG: - hlist_for_each_entry_safe(region, node, n, - &sync->frame, list) { - - if (pinfo->type == region->type && - pinfo->vaddr == region->vaddr && - pinfo->fd == region->fd) { - hlist_del(node); - put_pmem_file(region->file); - kfree(region); - } - } - break; - - case MSM_PMEM_AEC_AWB: - case MSM_PMEM_AF: - hlist_for_each_entry_safe(region, node, n, - &sync->stats, list) { - - if (pinfo->type == region->type && - pinfo->vaddr == region->vaddr && - pinfo->fd == region->fd) { - hlist_del(node); - put_pmem_file(region->file); - kfree(region); - } - } - break; - - default: - rc = -EINVAL; - break; - } - - return rc; -} - -static int msm_pmem_table_del(struct msm_sync *sync, void __user *arg) -{ - struct msm_pmem_info info; - - if (copy_from_user(&info, arg, sizeof(info))) { - ERR_COPY_FROM_USER(); - return -EFAULT; - } - - return __msm_pmem_table_del(sync, &info); -} - -static int __msm_get_frame(struct msm_sync *sync, - struct msm_frame *frame) -{ - unsigned long flags; - int rc = 0; - - struct msm_queue_cmd *qcmd = NULL; - struct msm_vfe_phy_info *pphy; - - spin_lock_irqsave(&sync->prev_frame_q_lock, flags); - if (!list_empty(&sync->prev_frame_q)) { - qcmd = list_first_entry(&sync->prev_frame_q, - struct msm_queue_cmd, list); - list_del_init(&qcmd->list); - } - spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags); - - if (!qcmd) { - pr_err("%s: no preview frame.\n", __func__); - return -EAGAIN; - } - - pphy = (struct msm_vfe_phy_info *)(qcmd->command); - - frame->buffer = - msm_pmem_frame_ptov_lookup(sync, - pphy->y_phy, - pphy->cbcr_phy, &(frame->y_off), - &(frame->cbcr_off), &(frame->fd)); - if (!frame->buffer) { - pr_err("%s: cannot get frame, invalid lookup address " - "y=%x cbcr=%x offset=%d\n", - __FUNCTION__, - pphy->y_phy, - pphy->cbcr_phy, - frame->y_off); - rc = -EINVAL; - } - - CDBG("__msm_get_frame: y=0x%x, cbcr=0x%x, qcmd=0x%x, virt_addr=0x%x\n", - pphy->y_phy, pphy->cbcr_phy, (int) qcmd, (int) frame->buffer); - - kfree(qcmd); - return rc; -} - -static int msm_get_frame(struct msm_sync *sync, void __user *arg) -{ - int rc = 0; - struct msm_frame frame; - - if (copy_from_user(&frame, - arg, - sizeof(struct msm_frame))) { - ERR_COPY_FROM_USER(); - return -EFAULT; - } - - rc = __msm_get_frame(sync, &frame); - if (rc < 0) - return rc; - - if (sync->croplen) { - if (frame.croplen > sync->croplen) { - pr_err("msm_get_frame: invalid frame croplen %d\n", - frame.croplen); - return -EINVAL; - } - - if (copy_to_user((void *)frame.cropinfo, - sync->cropinfo, - sync->croplen)) { - ERR_COPY_TO_USER(); - return -EFAULT; - } - } - - if (copy_to_user((void *)arg, - &frame, sizeof(struct msm_frame))) { - ERR_COPY_TO_USER(); - rc = -EFAULT; - } - - CDBG("Got frame!!!\n"); - - return rc; -} - -static int msm_enable_vfe(struct msm_sync *sync, void __user *arg) -{ - int rc = -EIO; - struct camera_enable_cmd cfg; - - if (copy_from_user(&cfg, - arg, - sizeof(struct camera_enable_cmd))) { - ERR_COPY_FROM_USER(); - return -EFAULT; - } - - if (sync->vfefn.vfe_enable) - rc = sync->vfefn.vfe_enable(&cfg); - - CDBG("msm_enable_vfe: returned rc = %d\n", rc); - return rc; -} - -static int msm_disable_vfe(struct msm_sync *sync, void __user *arg) -{ - int rc = -EIO; - struct camera_enable_cmd cfg; - - if (copy_from_user(&cfg, - arg, - sizeof(struct camera_enable_cmd))) { - ERR_COPY_FROM_USER(); - return -EFAULT; - } - - if (sync->vfefn.vfe_disable) - rc = sync->vfefn.vfe_disable(&cfg, NULL); - - CDBG("msm_disable_vfe: returned rc = %d\n", rc); - return rc; -} - -static struct msm_queue_cmd* __msm_control(struct msm_sync *sync, - struct msm_control_device_queue *queue, - struct msm_queue_cmd *qcmd, - int timeout) -{ - unsigned long flags; - int rc; - - spin_lock_irqsave(&sync->msg_event_q_lock, flags); - list_add_tail(&qcmd->list, &sync->msg_event_q); - /* wake up config thread */ - wake_up(&sync->msg_event_wait); - spin_unlock_irqrestore(&sync->msg_event_q_lock, flags); - - if (!queue) - return NULL; - - /* wait for config status */ - rc = wait_event_interruptible_timeout( - queue->ctrl_status_wait, - !list_empty_careful(&queue->ctrl_status_q), - timeout); - if (list_empty_careful(&queue->ctrl_status_q)) { - if (!rc) - rc = -ETIMEDOUT; - if (rc < 0) { - pr_err("msm_control: wait_event error %d\n", rc); -#if 0 - /* This is a bit scary. If we time out too early, we - * will free qcmd at the end of this function, and the - * dsp may do the same when it does respond, so we - * remove the message from the source queue. - */ - pr_err("%s: error waiting for ctrl_status_q: %d\n", - __func__, rc); - spin_lock_irqsave(&sync->msg_event_q_lock, flags); - list_del_init(&qcmd->list); - spin_unlock_irqrestore(&sync->msg_event_q_lock, flags); -#endif - return ERR_PTR(rc); - } - } - - /* control command status is ready */ - spin_lock_irqsave(&queue->ctrl_status_q_lock, flags); - BUG_ON(list_empty(&queue->ctrl_status_q)); - qcmd = list_first_entry(&queue->ctrl_status_q, - struct msm_queue_cmd, list); - list_del_init(&qcmd->list); - spin_unlock_irqrestore(&queue->ctrl_status_q_lock, flags); - - return qcmd; -} - -static int msm_control(struct msm_control_device *ctrl_pmsm, - int block, - void __user *arg) -{ - int rc = 0; - - struct msm_sync *sync = ctrl_pmsm->pmsm->sync; - struct msm_ctrl_cmd udata, *ctrlcmd; - struct msm_queue_cmd *qcmd = NULL, *qcmd_temp; - - if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) { - ERR_COPY_FROM_USER(); - rc = -EFAULT; - goto end; - } - - qcmd = kmalloc(sizeof(struct msm_queue_cmd) + - sizeof(struct msm_ctrl_cmd) + udata.length, - GFP_KERNEL); - if (!qcmd) { - pr_err("msm_control: cannot allocate buffer\n"); - rc = -ENOMEM; - goto end; - } - - qcmd->type = MSM_CAM_Q_CTRL; - qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1); - *ctrlcmd = udata; - ctrlcmd->value = ctrlcmd + 1; - - if (udata.length) { - if (copy_from_user(ctrlcmd->value, - udata.value, udata.length)) { - ERR_COPY_FROM_USER(); - rc = -EFAULT; - goto end; - } - } - - if (!block) { - /* qcmd will be set to NULL */ - qcmd = __msm_control(sync, NULL, qcmd, 0); - goto end; - } - - qcmd_temp = __msm_control(sync, - &ctrl_pmsm->ctrl_q, - qcmd, MAX_SCHEDULE_TIMEOUT); - - if (IS_ERR(qcmd_temp)) { - rc = PTR_ERR(qcmd_temp); - goto end; - } - qcmd = qcmd_temp; - - if (qcmd->command) { - void __user *to = udata.value; - udata = *(struct msm_ctrl_cmd *)qcmd->command; - if (udata.length > 0) { - if (copy_to_user(to, - udata.value, - udata.length)) { - ERR_COPY_TO_USER(); - rc = -EFAULT; - goto end; - } - } - udata.value = to; - - if (copy_to_user((void *)arg, &udata, - sizeof(struct msm_ctrl_cmd))) { - ERR_COPY_TO_USER(); - rc = -EFAULT; - goto end; - } - } - -end: - /* Note: if we get here as a result of an error, we will free the - * qcmd that we kmalloc() in this function. When we come here as - * a result of a successful completion, we are freeing the qcmd that - * we dequeued from queue->ctrl_status_q. - */ - if (qcmd) - kfree(qcmd); - - CDBG("msm_control: end rc = %d\n", rc); - return rc; -} - -static int msm_get_stats(struct msm_sync *sync, void __user *arg) -{ - unsigned long flags; - int timeout; - int rc = 0; - - struct msm_stats_event_ctrl se; - - struct msm_queue_cmd *qcmd = NULL; - struct msm_ctrl_cmd *ctrl = NULL; - struct msm_vfe_resp *data = NULL; - struct msm_stats_buf stats; - - if (copy_from_user(&se, arg, - sizeof(struct msm_stats_event_ctrl))) { - ERR_COPY_FROM_USER(); - return -EFAULT; - } - - timeout = (int)se.timeout_ms; - - CDBG("msm_get_stats timeout %d\n", timeout); - rc = wait_event_interruptible_timeout( - sync->msg_event_wait, - !list_empty_careful(&sync->msg_event_q), - msecs_to_jiffies(timeout)); - if (list_empty_careful(&sync->msg_event_q)) { - if (rc == 0) - rc = -ETIMEDOUT; - if (rc < 0) { - pr_err("msm_get_stats error %d\n", rc); - return rc; - } - } - CDBG("msm_get_stats returned from wait: %d\n", rc); - - spin_lock_irqsave(&sync->msg_event_q_lock, flags); - BUG_ON(list_empty(&sync->msg_event_q)); - qcmd = list_first_entry(&sync->msg_event_q, - struct msm_queue_cmd, list); - list_del_init(&qcmd->list); - spin_unlock_irqrestore(&sync->msg_event_q_lock, flags); - - CDBG("=== received from DSP === %d\n", qcmd->type); - - switch (qcmd->type) { - case MSM_CAM_Q_VFE_EVT: - case MSM_CAM_Q_VFE_MSG: - data = (struct msm_vfe_resp *)(qcmd->command); - - /* adsp event and message */ - se.resptype = MSM_CAM_RESP_STAT_EVT_MSG; - - /* 0 - msg from aDSP, 1 - event from mARM */ - se.stats_event.type = data->evt_msg.type; - se.stats_event.msg_id = data->evt_msg.msg_id; - se.stats_event.len = data->evt_msg.len; - - CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type); - CDBG("length = %d\n", se.stats_event.len); - CDBG("msg_id = %d\n", se.stats_event.msg_id); - - if ((data->type == VFE_MSG_STATS_AF) || - (data->type == VFE_MSG_STATS_WE)) { - - stats.buffer = - msm_pmem_stats_ptov_lookup(sync, - data->phy.sbuf_phy, - &(stats.fd)); - if (!stats.buffer) { - pr_err("%s: msm_pmem_stats_ptov_lookup error\n", - __FUNCTION__); - rc = -EINVAL; - goto failure; - } - - if (copy_to_user((void *)(se.stats_event.data), - &stats, - sizeof(struct msm_stats_buf))) { - ERR_COPY_TO_USER(); - rc = -EFAULT; - goto failure; - } - } else if ((data->evt_msg.len > 0) && - (data->type == VFE_MSG_GENERAL)) { - if (copy_to_user((void *)(se.stats_event.data), - data->evt_msg.data, - data->evt_msg.len)) { - ERR_COPY_TO_USER(); - rc = -EFAULT; - } - } else if (data->type == VFE_MSG_OUTPUT1 || - data->type == VFE_MSG_OUTPUT2) { - if (copy_to_user((void *)(se.stats_event.data), - data->extdata, - data->extlen)) { - ERR_COPY_TO_USER(); - rc = -EFAULT; - } - } else if (data->type == VFE_MSG_SNAPSHOT && sync->pict_pp) { - struct msm_postproc buf; - struct msm_pmem_region region; - buf.fmnum = msm_pmem_region_lookup(&sync->frame, - MSM_PMEM_MAINIMG, - ®ion, 1); - if (buf.fmnum == 1) { - buf.fmain.buffer = (unsigned long)region.vaddr; - buf.fmain.y_off = region.y_off; - buf.fmain.cbcr_off = region.cbcr_off; - buf.fmain.fd = region.fd; - } else { - buf.fmnum = msm_pmem_region_lookup(&sync->frame, - MSM_PMEM_RAW_MAINIMG, - ®ion, 1); - if (buf.fmnum == 1) { - buf.fmain.path = MSM_FRAME_PREV_2; - buf.fmain.buffer = - (unsigned long)region.vaddr; - buf.fmain.fd = region.fd; - } - else { - pr_err("%s: pmem lookup failed\n", - __func__); - rc = -EINVAL; - } - } - - if (copy_to_user((void *)(se.stats_event.data), &buf, - sizeof(buf))) { - ERR_COPY_TO_USER(); - rc = -EFAULT; - goto failure; - } - CDBG("snapshot copy_to_user!\n"); - } - break; - - case MSM_CAM_Q_CTRL: - /* control command from control thread */ - ctrl = (struct msm_ctrl_cmd *)(qcmd->command); - - CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type); - CDBG("length = %d\n", ctrl->length); - - if (ctrl->length > 0) { - if (copy_to_user((void *)(se.ctrl_cmd.value), - ctrl->value, - ctrl->length)) { - ERR_COPY_TO_USER(); - rc = -EFAULT; - goto failure; - } - } - - se.resptype = MSM_CAM_RESP_CTRL; - - /* what to control */ - se.ctrl_cmd.type = ctrl->type; - se.ctrl_cmd.length = ctrl->length; - se.ctrl_cmd.resp_fd = ctrl->resp_fd; - break; - - case MSM_CAM_Q_V4L2_REQ: - /* control command from v4l2 client */ - ctrl = (struct msm_ctrl_cmd *)(qcmd->command); - - CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type); - CDBG("length = %d\n", ctrl->length); - - if (ctrl->length > 0) { - if (copy_to_user((void *)(se.ctrl_cmd.value), - ctrl->value, ctrl->length)) { - ERR_COPY_TO_USER(); - rc = -EFAULT; - goto failure; - } - } - - /* 2 tells config thread this is v4l2 request */ - se.resptype = MSM_CAM_RESP_V4L2; - - /* what to control */ - se.ctrl_cmd.type = ctrl->type; - se.ctrl_cmd.length = ctrl->length; - break; - - default: - rc = -EFAULT; - goto failure; - } /* switch qcmd->type */ - - if (copy_to_user((void *)arg, &se, sizeof(se))) { - ERR_COPY_TO_USER(); - rc = -EFAULT; - } - -failure: - if (qcmd) - kfree(qcmd); - - CDBG("msm_get_stats: %d\n", rc); - return rc; -} - -static int msm_ctrl_cmd_done(struct msm_control_device *ctrl_pmsm, - void __user *arg) -{ - unsigned long flags; - int rc = 0; - - struct msm_ctrl_cmd udata, *ctrlcmd; - struct msm_queue_cmd *qcmd = NULL; - - if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) { - ERR_COPY_FROM_USER(); - rc = -EFAULT; - goto end; - } - - qcmd = kmalloc(sizeof(struct msm_queue_cmd) + - sizeof(struct msm_ctrl_cmd) + udata.length, - GFP_KERNEL); - if (!qcmd) { - rc = -ENOMEM; - goto end; - } - - qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1); - *ctrlcmd = udata; - if (udata.length > 0) { - ctrlcmd->value = ctrlcmd + 1; - if (copy_from_user(ctrlcmd->value, - (void *)udata.value, - udata.length)) { - ERR_COPY_FROM_USER(); - rc = -EFAULT; - kfree(qcmd); - goto end; - } - } - else ctrlcmd->value = NULL; - -end: - CDBG("msm_ctrl_cmd_done: end rc = %d\n", rc); - if (rc == 0) { - /* wake up control thread */ - spin_lock_irqsave(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock, flags); - list_add_tail(&qcmd->list, &ctrl_pmsm->ctrl_q.ctrl_status_q); - wake_up(&ctrl_pmsm->ctrl_q.ctrl_status_wait); - spin_unlock_irqrestore(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock, flags); - } - - return rc; -} - -static int msm_config_vfe(struct msm_sync *sync, void __user *arg) -{ - struct msm_vfe_cfg_cmd cfgcmd; - struct msm_pmem_region region[8]; - struct axidata axi_data; - void *data = NULL; - int rc = -EIO; - - memset(&axi_data, 0, sizeof(axi_data)); - - if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) { - ERR_COPY_FROM_USER(); - return -EFAULT; - } - - switch(cfgcmd.cmd_type) { - case CMD_STATS_ENABLE: - axi_data.bufnum1 = - msm_pmem_region_lookup(&sync->stats, - MSM_PMEM_AEC_AWB, ®ion[0], - NUM_WB_EXP_STAT_OUTPUT_BUFFERS); - if (!axi_data.bufnum1) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); - return -EINVAL; - } - axi_data.region = ®ion[0]; - data = &axi_data; - break; - case CMD_STATS_AF_ENABLE: - axi_data.bufnum1 = - msm_pmem_region_lookup(&sync->stats, - MSM_PMEM_AF, ®ion[0], - NUM_AF_STAT_OUTPUT_BUFFERS); - if (!axi_data.bufnum1) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); - return -EINVAL; - } - axi_data.region = ®ion[0]; - data = &axi_data; - break; - case CMD_GENERAL: - case CMD_STATS_DISABLE: - break; - default: - pr_err("%s: unknown command type %d\n", - __FUNCTION__, cfgcmd.cmd_type); - return -EINVAL; - } - - - if (sync->vfefn.vfe_config) - rc = sync->vfefn.vfe_config(&cfgcmd, data); - - return rc; -} - -static int msm_frame_axi_cfg(struct msm_sync *sync, - struct msm_vfe_cfg_cmd *cfgcmd) -{ - int rc = -EIO; - struct axidata axi_data; - void *data = &axi_data; - struct msm_pmem_region region[8]; - int pmem_type; - - memset(&axi_data, 0, sizeof(axi_data)); - - switch (cfgcmd->cmd_type) { - case CMD_AXI_CFG_OUT1: - pmem_type = MSM_PMEM_OUTPUT1; - axi_data.bufnum1 = - msm_pmem_region_lookup(&sync->frame, pmem_type, - ®ion[0], 8); - if (!axi_data.bufnum1) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); - return -EINVAL; - } - break; - - case CMD_AXI_CFG_OUT2: - pmem_type = MSM_PMEM_OUTPUT2; - axi_data.bufnum2 = - msm_pmem_region_lookup(&sync->frame, pmem_type, - ®ion[0], 8); - if (!axi_data.bufnum2) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); - return -EINVAL; - } - break; - - case CMD_AXI_CFG_SNAP_O1_AND_O2: - pmem_type = MSM_PMEM_THUMBAIL; - axi_data.bufnum1 = - msm_pmem_region_lookup(&sync->frame, pmem_type, - ®ion[0], 8); - if (!axi_data.bufnum1) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); - return -EINVAL; - } - - pmem_type = MSM_PMEM_MAINIMG; - axi_data.bufnum2 = - msm_pmem_region_lookup(&sync->frame, pmem_type, - ®ion[axi_data.bufnum1], 8); - if (!axi_data.bufnum2) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); - return -EINVAL; - } - break; - - case CMD_RAW_PICT_AXI_CFG: - pmem_type = MSM_PMEM_RAW_MAINIMG; - axi_data.bufnum2 = - msm_pmem_region_lookup(&sync->frame, pmem_type, - ®ion[0], 8); - if (!axi_data.bufnum2) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); - return -EINVAL; - } - break; - - case CMD_GENERAL: - data = NULL; - break; - - default: - pr_err("%s: unknown command type %d\n", - __FUNCTION__, cfgcmd->cmd_type); - return -EINVAL; - } - - axi_data.region = ®ion[0]; - - /* send the AXI configuration command to driver */ - if (sync->vfefn.vfe_config) - rc = sync->vfefn.vfe_config(cfgcmd, data); - - return rc; -} - -static int msm_get_sensor_info(struct msm_sync *sync, void __user *arg) -{ - int rc = 0; - struct msm_camsensor_info info; - struct msm_camera_sensor_info *sdata; - - if (copy_from_user(&info, - arg, - sizeof(struct msm_camsensor_info))) { - ERR_COPY_FROM_USER(); - return -EFAULT; - } - - sdata = sync->pdev->dev.platform_data; - CDBG("sensor_name %s\n", sdata->sensor_name); - - memcpy(&info.name[0], - sdata->sensor_name, - MAX_SENSOR_NAME); - info.flash_enabled = sdata->flash_type != MSM_CAMERA_FLASH_NONE; - - /* copy back to user space */ - if (copy_to_user((void *)arg, - &info, - sizeof(struct msm_camsensor_info))) { - ERR_COPY_TO_USER(); - rc = -EFAULT; - } - - return rc; -} - -static int __msm_put_frame_buf(struct msm_sync *sync, - struct msm_frame *pb) -{ - unsigned long pphy; - struct msm_vfe_cfg_cmd cfgcmd; - - int rc = -EIO; - - pphy = msm_pmem_frame_vtop_lookup(sync, - pb->buffer, - pb->y_off, pb->cbcr_off, pb->fd); - - if (pphy != 0) { - CDBG("rel: vaddr = 0x%lx, paddr = 0x%lx\n", - pb->buffer, pphy); - cfgcmd.cmd_type = CMD_FRAME_BUF_RELEASE; - cfgcmd.value = (void *)pb; - if (sync->vfefn.vfe_config) - rc = sync->vfefn.vfe_config(&cfgcmd, &pphy); - } else { - pr_err("%s: msm_pmem_frame_vtop_lookup failed\n", - __FUNCTION__); - rc = -EINVAL; - } - - return rc; -} - -static int msm_put_frame_buffer(struct msm_sync *sync, void __user *arg) -{ - struct msm_frame buf_t; - - if (copy_from_user(&buf_t, - arg, - sizeof(struct msm_frame))) { - ERR_COPY_FROM_USER(); - return -EFAULT; - } - - return __msm_put_frame_buf(sync, &buf_t); -} - -static int __msm_register_pmem(struct msm_sync *sync, - struct msm_pmem_info *pinfo) -{ - int rc = 0; - - switch (pinfo->type) { - case MSM_PMEM_OUTPUT1: - case MSM_PMEM_OUTPUT2: - case MSM_PMEM_THUMBAIL: - case MSM_PMEM_MAINIMG: - case MSM_PMEM_RAW_MAINIMG: - rc = msm_pmem_table_add(&sync->frame, pinfo); - break; - - case MSM_PMEM_AEC_AWB: - case MSM_PMEM_AF: - rc = msm_pmem_table_add(&sync->stats, pinfo); - break; - - default: - rc = -EINVAL; - break; - } - - return rc; -} - -static int msm_register_pmem(struct msm_sync *sync, void __user *arg) -{ - struct msm_pmem_info info; - - if (copy_from_user(&info, arg, sizeof(info))) { - ERR_COPY_FROM_USER(); - return -EFAULT; - } - - return __msm_register_pmem(sync, &info); -} - -static int msm_stats_axi_cfg(struct msm_sync *sync, - struct msm_vfe_cfg_cmd *cfgcmd) -{ - int rc = -EIO; - struct axidata axi_data; - void *data = &axi_data; - - struct msm_pmem_region region[3]; - int pmem_type = MSM_PMEM_MAX; - - memset(&axi_data, 0, sizeof(axi_data)); - - switch (cfgcmd->cmd_type) { - case CMD_STATS_AXI_CFG: - pmem_type = MSM_PMEM_AEC_AWB; - break; - case CMD_STATS_AF_AXI_CFG: - pmem_type = MSM_PMEM_AF; - break; - case CMD_GENERAL: - data = NULL; - break; - default: - pr_err("%s: unknown command type %d\n", - __FUNCTION__, cfgcmd->cmd_type); - return -EINVAL; - } - - if (cfgcmd->cmd_type != CMD_GENERAL) { - axi_data.bufnum1 = - msm_pmem_region_lookup(&sync->stats, pmem_type, - ®ion[0], NUM_WB_EXP_STAT_OUTPUT_BUFFERS); - if (!axi_data.bufnum1) { - pr_err("%s: pmem region lookup error\n", __FUNCTION__); - return -EINVAL; - } - axi_data.region = ®ion[0]; - } - - /* send the AEC/AWB STATS configuration command to driver */ - if (sync->vfefn.vfe_config) - rc = sync->vfefn.vfe_config(cfgcmd, &axi_data); - - return rc; -} - -static int msm_put_stats_buffer(struct msm_sync *sync, void __user *arg) -{ - int rc = -EIO; - - struct msm_stats_buf buf; - unsigned long pphy; - struct msm_vfe_cfg_cmd cfgcmd; - - if (copy_from_user(&buf, arg, - sizeof(struct msm_stats_buf))) { - ERR_COPY_FROM_USER(); - return -EFAULT; - } - - CDBG("msm_put_stats_buffer\n"); - pphy = msm_pmem_stats_vtop_lookup(sync, buf.buffer, buf.fd); - - if (pphy != 0) { - if (buf.type == STAT_AEAW) - cfgcmd.cmd_type = CMD_STATS_BUF_RELEASE; - else if (buf.type == STAT_AF) - cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE; - else { - pr_err("%s: invalid buf type %d\n", - __FUNCTION__, - buf.type); - rc = -EINVAL; - goto put_done; - } - - cfgcmd.value = (void *)&buf; - - if (sync->vfefn.vfe_config) { - rc = sync->vfefn.vfe_config(&cfgcmd, &pphy); - if (rc < 0) - pr_err("msm_put_stats_buffer: "\ - "vfe_config err %d\n", rc); - } else - pr_err("msm_put_stats_buffer: vfe_config is NULL\n"); - } else { - pr_err("msm_put_stats_buffer: NULL physical address\n"); - rc = -EINVAL; - } - -put_done: - return rc; -} - -static int msm_axi_config(struct msm_sync *sync, void __user *arg) -{ - struct msm_vfe_cfg_cmd cfgcmd; - - if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) { - ERR_COPY_FROM_USER(); - return -EFAULT; - } - - switch (cfgcmd.cmd_type) { - case CMD_AXI_CFG_OUT1: - case CMD_AXI_CFG_OUT2: - case CMD_AXI_CFG_SNAP_O1_AND_O2: - case CMD_RAW_PICT_AXI_CFG: - return msm_frame_axi_cfg(sync, &cfgcmd); - - case CMD_STATS_AXI_CFG: - case CMD_STATS_AF_AXI_CFG: - return msm_stats_axi_cfg(sync, &cfgcmd); - - default: - pr_err("%s: unknown command type %d\n", - __FUNCTION__, - cfgcmd.cmd_type); - return -EINVAL; - } - - return 0; -} - -static int __msm_get_pic(struct msm_sync *sync, struct msm_ctrl_cmd *ctrl) -{ - unsigned long flags; - int rc = 0; - int tm; - - struct msm_queue_cmd *qcmd = NULL; - - tm = (int)ctrl->timeout_ms; - - rc = wait_event_interruptible_timeout( - sync->pict_frame_wait, - !list_empty_careful(&sync->pict_frame_q), - msecs_to_jiffies(tm)); - if (list_empty_careful(&sync->pict_frame_q)) { - if (rc == 0) - return -ETIMEDOUT; - if (rc < 0) { - pr_err("msm_camera_get_picture, rc = %d\n", rc); - return rc; - } - } - - spin_lock_irqsave(&sync->pict_frame_q_lock, flags); - BUG_ON(list_empty(&sync->pict_frame_q)); - qcmd = list_first_entry(&sync->pict_frame_q, - struct msm_queue_cmd, list); - list_del_init(&qcmd->list); - spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags); - - if (qcmd->command != NULL) { - struct msm_ctrl_cmd *q = - (struct msm_ctrl_cmd *)qcmd->command; - ctrl->type = q->type; - ctrl->status = q->status; - } else { - ctrl->type = -1; - ctrl->status = -1; - } - - kfree(qcmd); - return rc; -} - -static int msm_get_pic(struct msm_sync *sync, void __user *arg) -{ - struct msm_ctrl_cmd ctrlcmd_t; - int rc; - - if (copy_from_user(&ctrlcmd_t, - arg, - sizeof(struct msm_ctrl_cmd))) { - ERR_COPY_FROM_USER(); - return -EFAULT; - } - - rc = __msm_get_pic(sync, &ctrlcmd_t); - if (rc < 0) - return rc; - - if (sync->croplen) { - if (ctrlcmd_t.length < sync->croplen) { - pr_err("msm_get_pic: invalid len %d\n", - ctrlcmd_t.length); - return -EINVAL; - } - if (copy_to_user(ctrlcmd_t.value, - sync->cropinfo, - sync->croplen)) { - ERR_COPY_TO_USER(); - return -EFAULT; - } - } - - if (copy_to_user((void *)arg, - &ctrlcmd_t, - sizeof(struct msm_ctrl_cmd))) { - ERR_COPY_TO_USER(); - return -EFAULT; - } - return 0; -} - -static int msm_set_crop(struct msm_sync *sync, void __user *arg) -{ - struct crop_info crop; - - if (copy_from_user(&crop, - arg, - sizeof(struct crop_info))) { - ERR_COPY_FROM_USER(); - return -EFAULT; - } - - if (!sync->croplen) { - sync->cropinfo = kmalloc(crop.len, GFP_KERNEL); - if (!sync->cropinfo) - return -ENOMEM; - } else if (sync->croplen < crop.len) - return -EINVAL; - - if (copy_from_user(sync->cropinfo, - crop.info, - crop.len)) { - ERR_COPY_FROM_USER(); - kfree(sync->cropinfo); - return -EFAULT; - } - - sync->croplen = crop.len; - - return 0; -} - -static int msm_pict_pp_done(struct msm_sync *sync, void __user *arg) -{ - struct msm_ctrl_cmd udata; - struct msm_ctrl_cmd *ctrlcmd = NULL; - struct msm_queue_cmd *qcmd = NULL; - unsigned long flags; - int rc = 0; - - if (!sync->pict_pp) - return -EINVAL; - - if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) { - ERR_COPY_FROM_USER(); - rc = -EFAULT; - goto pp_fail; - } - - qcmd = kmalloc(sizeof(struct msm_queue_cmd) + - sizeof(struct msm_ctrl_cmd), - GFP_KERNEL); - if (!qcmd) { - rc = -ENOMEM; - goto pp_fail; - } - - qcmd->type = MSM_CAM_Q_VFE_MSG; - qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1); - memset(ctrlcmd, 0, sizeof(struct msm_ctrl_cmd)); - ctrlcmd->type = udata.type; - ctrlcmd->status = udata.status; - - spin_lock_irqsave(&sync->pict_frame_q_lock, flags); - list_add_tail(&qcmd->list, &sync->pict_frame_q); - spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags); - wake_up(&sync->pict_frame_wait); - -pp_fail: - return rc; -} - -static long msm_ioctl_common(struct msm_device *pmsm, - unsigned int cmd, - void __user *argp) -{ - CDBG("msm_ioctl_common\n"); - switch (cmd) { - case MSM_CAM_IOCTL_REGISTER_PMEM: - return msm_register_pmem(pmsm->sync, argp); - case MSM_CAM_IOCTL_UNREGISTER_PMEM: - return msm_pmem_table_del(pmsm->sync, argp); - default: - return -EINVAL; - } -} - -static long msm_ioctl_config(struct file *filep, unsigned int cmd, - unsigned long arg) -{ - int rc = -EINVAL; - void __user *argp = (void __user *)arg; - struct msm_device *pmsm = filep->private_data; - - CDBG("msm_ioctl_config cmd = %d\n", _IOC_NR(cmd)); - - switch (cmd) { - case MSM_CAM_IOCTL_GET_SENSOR_INFO: - rc = msm_get_sensor_info(pmsm->sync, argp); - break; - - case MSM_CAM_IOCTL_CONFIG_VFE: - /* Coming from config thread for update */ - rc = msm_config_vfe(pmsm->sync, argp); - break; - - case MSM_CAM_IOCTL_GET_STATS: - /* Coming from config thread wait - * for vfe statistics and control requests */ - rc = msm_get_stats(pmsm->sync, argp); - break; - - case MSM_CAM_IOCTL_ENABLE_VFE: - /* This request comes from control thread: - * enable either QCAMTASK or VFETASK */ - rc = msm_enable_vfe(pmsm->sync, argp); - break; - - case MSM_CAM_IOCTL_DISABLE_VFE: - /* This request comes from control thread: - * disable either QCAMTASK or VFETASK */ - rc = msm_disable_vfe(pmsm->sync, argp); - break; - - case MSM_CAM_IOCTL_VFE_APPS_RESET: - msm_camio_vfe_blk_reset(); - rc = 0; - break; - - case MSM_CAM_IOCTL_RELEASE_STATS_BUFFER: - rc = msm_put_stats_buffer(pmsm->sync, argp); - break; - - case MSM_CAM_IOCTL_AXI_CONFIG: - rc = msm_axi_config(pmsm->sync, argp); - break; - - case MSM_CAM_IOCTL_SET_CROP: - rc = msm_set_crop(pmsm->sync, argp); - break; - - case MSM_CAM_IOCTL_PICT_PP: { - uint8_t enable; - if (copy_from_user(&enable, argp, sizeof(enable))) { - ERR_COPY_FROM_USER(); - rc = -EFAULT; - } else { - pmsm->sync->pict_pp = enable; - rc = 0; - } - break; - } - - case MSM_CAM_IOCTL_PICT_PP_DONE: - rc = msm_pict_pp_done(pmsm->sync, argp); - break; - - case MSM_CAM_IOCTL_SENSOR_IO_CFG: - rc = pmsm->sync->sctrl.s_config(argp); - break; - - case MSM_CAM_IOCTL_FLASH_LED_CFG: { - uint32_t led_state; - if (copy_from_user(&led_state, argp, sizeof(led_state))) { - ERR_COPY_FROM_USER(); - rc = -EFAULT; - } else - rc = msm_camera_flash_set_led_state(led_state); - break; - } - - default: - rc = msm_ioctl_common(pmsm, cmd, argp); - break; - } - - CDBG("msm_ioctl_config cmd = %d DONE\n", _IOC_NR(cmd)); - return rc; -} - -static int msm_unblock_poll_frame(struct msm_sync *); - -static long msm_ioctl_frame(struct file *filep, unsigned int cmd, - unsigned long arg) -{ - int rc = -EINVAL; - void __user *argp = (void __user *)arg; - struct msm_device *pmsm = filep->private_data; - - - switch (cmd) { - case MSM_CAM_IOCTL_GETFRAME: - /* Coming from frame thread to get frame - * after SELECT is done */ - rc = msm_get_frame(pmsm->sync, argp); - break; - case MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER: - rc = msm_put_frame_buffer(pmsm->sync, argp); - break; - case MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME: - rc = msm_unblock_poll_frame(pmsm->sync); - break; - default: - break; - } - - return rc; -} - - -static long msm_ioctl_control(struct file *filep, unsigned int cmd, - unsigned long arg) -{ - int rc = -EINVAL; - void __user *argp = (void __user *)arg; - struct msm_control_device *ctrl_pmsm = filep->private_data; - struct msm_device *pmsm = ctrl_pmsm->pmsm; - - switch (cmd) { - case MSM_CAM_IOCTL_CTRL_COMMAND: - /* Coming from control thread, may need to wait for - * command status */ - rc = msm_control(ctrl_pmsm, 1, argp); - break; - case MSM_CAM_IOCTL_CTRL_COMMAND_2: - /* Sends a message, returns immediately */ - rc = msm_control(ctrl_pmsm, 0, argp); - break; - case MSM_CAM_IOCTL_CTRL_CMD_DONE: - /* Config thread calls the control thread to notify it - * of the result of a MSM_CAM_IOCTL_CTRL_COMMAND. - */ - rc = msm_ctrl_cmd_done(ctrl_pmsm, argp); - break; - case MSM_CAM_IOCTL_GET_PICTURE: - rc = msm_get_pic(pmsm->sync, argp); - break; - default: - rc = msm_ioctl_common(pmsm, cmd, argp); - break; - } - - return rc; -} - -static int __msm_release(struct msm_sync *sync) -{ - struct msm_pmem_region *region; - struct hlist_node *hnode; - struct hlist_node *n; - - mutex_lock(&sync->lock); - if (sync->opencnt) - sync->opencnt--; - - if (!sync->opencnt) { - /* need to clean up system resource */ - if (sync->vfefn.vfe_release) - sync->vfefn.vfe_release(sync->pdev); - - if (sync->cropinfo) { - kfree(sync->cropinfo); - sync->cropinfo = NULL; - sync->croplen = 0; - } - - hlist_for_each_entry_safe(region, hnode, n, - &sync->frame, list) { - hlist_del(hnode); - put_pmem_file(region->file); - kfree(region); - } - - hlist_for_each_entry_safe(region, hnode, n, - &sync->stats, list) { - hlist_del(hnode); - put_pmem_file(region->file); - kfree(region); - } - - MSM_DRAIN_QUEUE(sync, msg_event_q); - MSM_DRAIN_QUEUE(sync, prev_frame_q); - MSM_DRAIN_QUEUE(sync, pict_frame_q); - - sync->sctrl.s_release(); - wake_unlock(&sync->wake_lock); - - sync->apps_id = NULL; - CDBG("msm_release completed!\n"); - } - mutex_unlock(&sync->lock); - - return 0; -} - -static int msm_release_config(struct inode *node, struct file *filep) -{ - int rc; - struct msm_device *pmsm = filep->private_data; - printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name); - rc = __msm_release(pmsm->sync); - atomic_set(&pmsm->opened, 0); - return rc; -} - -static int msm_release_control(struct inode *node, struct file *filep) -{ - int rc; - struct msm_control_device *ctrl_pmsm = filep->private_data; - struct msm_device *pmsm = ctrl_pmsm->pmsm; - printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name); - rc = __msm_release(pmsm->sync); - if (!rc) { - MSM_DRAIN_QUEUE(&ctrl_pmsm->ctrl_q, ctrl_status_q); - MSM_DRAIN_QUEUE(pmsm->sync, pict_frame_q); - } - kfree(ctrl_pmsm); - return rc; -} - -static int msm_release_frame(struct inode *node, struct file *filep) -{ - int rc; - struct msm_device *pmsm = filep->private_data; - printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name); - rc = __msm_release(pmsm->sync); - if (!rc) { - MSM_DRAIN_QUEUE(pmsm->sync, prev_frame_q); - atomic_set(&pmsm->opened, 0); - } - return rc; -} - -static int msm_unblock_poll_frame(struct msm_sync *sync) -{ - unsigned long flags; - CDBG("msm_unblock_poll_frame\n"); - spin_lock_irqsave(&sync->prev_frame_q_lock, flags); - sync->unblock_poll_frame = 1; - wake_up(&sync->prev_frame_wait); - spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags); - return 0; -} - -static unsigned int __msm_poll_frame(struct msm_sync *sync, - struct file *filep, - struct poll_table_struct *pll_table) -{ - int rc = 0; - unsigned long flags; - - poll_wait(filep, &sync->prev_frame_wait, pll_table); - - spin_lock_irqsave(&sync->prev_frame_q_lock, flags); - if (!list_empty_careful(&sync->prev_frame_q)) - /* frame ready */ - rc = POLLIN | POLLRDNORM; - if (sync->unblock_poll_frame) { - CDBG("%s: sync->unblock_poll_frame is true\n", __func__); - rc |= POLLPRI; - sync->unblock_poll_frame = 0; - } - spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags); - - return rc; -} - -static unsigned int msm_poll_frame(struct file *filep, - struct poll_table_struct *pll_table) -{ - struct msm_device *pmsm = filep->private_data; - return __msm_poll_frame(pmsm->sync, filep, pll_table); -} - -/* - * This function executes in interrupt context. - */ - -static void *msm_vfe_sync_alloc(int size, - void *syncdata __attribute__((unused))) -{ - struct msm_queue_cmd *qcmd = - kmalloc(sizeof(struct msm_queue_cmd) + size, GFP_ATOMIC); - return qcmd ? qcmd + 1 : NULL; -} - -/* - * This function executes in interrupt context. - */ - -static void msm_vfe_sync(struct msm_vfe_resp *vdata, - enum msm_queue qtype, void *syncdata) -{ - struct msm_queue_cmd *qcmd = NULL; - struct msm_queue_cmd *qcmd_frame = NULL; - struct msm_vfe_phy_info *fphy; - - unsigned long flags; - struct msm_sync *sync = (struct msm_sync *)syncdata; - if (!sync) { - pr_err("msm_camera: no context in dsp callback.\n"); - return; - } - - qcmd = ((struct msm_queue_cmd *)vdata) - 1; - qcmd->type = qtype; - - if (qtype == MSM_CAM_Q_VFE_MSG) { - switch(vdata->type) { - case VFE_MSG_OUTPUT1: - case VFE_MSG_OUTPUT2: - qcmd_frame = - kmalloc(sizeof(struct msm_queue_cmd) + - sizeof(struct msm_vfe_phy_info), - GFP_ATOMIC); - if (!qcmd_frame) - goto mem_fail; - fphy = (struct msm_vfe_phy_info *)(qcmd_frame + 1); - *fphy = vdata->phy; - - qcmd_frame->type = MSM_CAM_Q_VFE_MSG; - qcmd_frame->command = fphy; - - CDBG("qcmd_frame= 0x%x phy_y= 0x%x, phy_cbcr= 0x%x\n", - (int) qcmd_frame, fphy->y_phy, fphy->cbcr_phy); - - spin_lock_irqsave(&sync->prev_frame_q_lock, flags); - list_add_tail(&qcmd_frame->list, &sync->prev_frame_q); - wake_up(&sync->prev_frame_wait); - spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags); - CDBG("woke up frame thread\n"); - break; - case VFE_MSG_SNAPSHOT: - if (sync->pict_pp) - break; - - CDBG("snapshot pp = %d\n", sync->pict_pp); - qcmd_frame = - kmalloc(sizeof(struct msm_queue_cmd), - GFP_ATOMIC); - if (!qcmd_frame) - goto mem_fail; - qcmd_frame->type = MSM_CAM_Q_VFE_MSG; - qcmd_frame->command = NULL; - spin_lock_irqsave(&sync->pict_frame_q_lock, - flags); - list_add_tail(&qcmd_frame->list, &sync->pict_frame_q); - wake_up(&sync->pict_frame_wait); - spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags); - CDBG("woke up picture thread\n"); - break; - default: - CDBG("%s: qtype = %d not handled\n", - __func__, vdata->type); - break; - } - } - - qcmd->command = (void *)vdata; - CDBG("vdata->type = %d\n", vdata->type); - - spin_lock_irqsave(&sync->msg_event_q_lock, flags); - list_add_tail(&qcmd->list, &sync->msg_event_q); - wake_up(&sync->msg_event_wait); - spin_unlock_irqrestore(&sync->msg_event_q_lock, flags); - CDBG("woke up config thread\n"); - return; - -mem_fail: - kfree(qcmd); -} - -static struct msm_vfe_callback msm_vfe_s = { - .vfe_resp = msm_vfe_sync, - .vfe_alloc = msm_vfe_sync_alloc, -}; - -static int __msm_open(struct msm_sync *sync, const char *const apps_id) -{ - int rc = 0; - - mutex_lock(&sync->lock); - if (sync->apps_id && strcmp(sync->apps_id, apps_id)) { - pr_err("msm_camera(%s): sensor %s is already opened for %s\n", - apps_id, - sync->sdata->sensor_name, - sync->apps_id); - rc = -EBUSY; - goto msm_open_done; - } - - sync->apps_id = apps_id; - - if (!sync->opencnt) { - wake_lock(&sync->wake_lock); - - msm_camvfe_fn_init(&sync->vfefn, sync); - if (sync->vfefn.vfe_init) { - rc = sync->vfefn.vfe_init(&msm_vfe_s, - sync->pdev); - if (rc < 0) { - pr_err("vfe_init failed at %d\n", rc); - goto msm_open_done; - } - rc = sync->sctrl.s_init(sync->sdata); - if (rc < 0) { - pr_err("sensor init failed: %d\n", rc); - goto msm_open_done; - } - } else { - pr_err("no sensor init func\n"); - rc = -ENODEV; - goto msm_open_done; - } - - if (rc >= 0) { - INIT_HLIST_HEAD(&sync->frame); - INIT_HLIST_HEAD(&sync->stats); - sync->unblock_poll_frame = 0; - } - } - sync->opencnt++; - -msm_open_done: - mutex_unlock(&sync->lock); - return rc; -} - -static int msm_open_common(struct inode *inode, struct file *filep, - int once) -{ - int rc; - struct msm_device *pmsm = - container_of(inode->i_cdev, struct msm_device, cdev); - - CDBG("msm_camera: open %s\n", filep->f_path.dentry->d_name.name); - - if (atomic_cmpxchg(&pmsm->opened, 0, 1) && once) { - pr_err("msm_camera: %s is already opened.\n", - filep->f_path.dentry->d_name.name); - return -EBUSY; - } - - rc = nonseekable_open(inode, filep); - if (rc < 0) { - pr_err("msm_open: nonseekable_open error %d\n", rc); - return rc; - } - - rc = __msm_open(pmsm->sync, MSM_APPS_ID_PROP); - if (rc < 0) - return rc; - - filep->private_data = pmsm; - - CDBG("msm_open() open: rc = %d\n", rc); - return rc; -} - -static int msm_open(struct inode *inode, struct file *filep) -{ - return msm_open_common(inode, filep, 1); -} - -static int msm_open_control(struct inode *inode, struct file *filep) -{ - int rc; - - struct msm_control_device *ctrl_pmsm = - kmalloc(sizeof(struct msm_control_device), GFP_KERNEL); - if (!ctrl_pmsm) - return -ENOMEM; - - rc = msm_open_common(inode, filep, 0); - if (rc < 0) - return rc; - - ctrl_pmsm->pmsm = filep->private_data; - filep->private_data = ctrl_pmsm; - spin_lock_init(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock); - INIT_LIST_HEAD(&ctrl_pmsm->ctrl_q.ctrl_status_q); - init_waitqueue_head(&ctrl_pmsm->ctrl_q.ctrl_status_wait); - - CDBG("msm_open() open: rc = %d\n", rc); - return rc; -} - -static int __msm_v4l2_control(struct msm_sync *sync, - struct msm_ctrl_cmd *out) -{ - int rc = 0; - - struct msm_queue_cmd *qcmd = NULL, *rcmd = NULL; - struct msm_ctrl_cmd *ctrl; - struct msm_control_device_queue FIXME; - - /* wake up config thread, 4 is for V4L2 application */ - qcmd = kmalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL); - if (!qcmd) { - pr_err("msm_control: cannot allocate buffer\n"); - rc = -ENOMEM; - goto end; - } - qcmd->type = MSM_CAM_Q_V4L2_REQ; - qcmd->command = out; - - rcmd = __msm_control(sync, &FIXME, qcmd, out->timeout_ms); - if (IS_ERR(rcmd)) { - rc = PTR_ERR(rcmd); - goto end; - } - - ctrl = (struct msm_ctrl_cmd *)(rcmd->command); - /* FIXME: we should just set out->length = ctrl->length; */ - BUG_ON(out->length < ctrl->length); - memcpy(out->value, ctrl->value, ctrl->length); - -end: - if (rcmd) kfree(rcmd); - CDBG("__msm_v4l2_control: end rc = %d\n", rc); - return rc; -} - -static const struct file_operations msm_fops_config = { - .owner = THIS_MODULE, - .open = msm_open, - .unlocked_ioctl = msm_ioctl_config, - .release = msm_release_config, -}; - -static const struct file_operations msm_fops_control = { - .owner = THIS_MODULE, - .open = msm_open_control, - .unlocked_ioctl = msm_ioctl_control, - .release = msm_release_control, -}; - -static const struct file_operations msm_fops_frame = { - .owner = THIS_MODULE, - .open = msm_open, - .unlocked_ioctl = msm_ioctl_frame, - .release = msm_release_frame, - .poll = msm_poll_frame, -}; - -static int msm_setup_cdev(struct msm_device *msm, - int node, - dev_t devno, - const char *suffix, - const struct file_operations *fops) -{ - int rc = -ENODEV; - - struct device *device = - device_create(msm_class, NULL, - devno, NULL, - "%s%d", suffix, node); - - if (IS_ERR(device)) { - rc = PTR_ERR(device); - pr_err("msm_camera: error creating device: %d\n", rc); - return rc; - } - - cdev_init(&msm->cdev, fops); - msm->cdev.owner = THIS_MODULE; - - rc = cdev_add(&msm->cdev, devno, 1); - if (rc < 0) { - pr_err("msm_camera: error adding cdev: %d\n", rc); - device_destroy(msm_class, devno); - return rc; - } - - return rc; -} - -static int msm_tear_down_cdev(struct msm_device *msm, dev_t devno) -{ - cdev_del(&msm->cdev); - device_destroy(msm_class, devno); - return 0; -} - -int msm_v4l2_register(struct msm_v4l2_driver *drv) -{ - /* FIXME: support multiple sensors */ - if (list_empty(&msm_sensors)) - return -ENODEV; - - drv->sync = list_first_entry(&msm_sensors, struct msm_sync, list); - drv->open = __msm_open; - drv->release = __msm_release; - drv->ctrl = __msm_v4l2_control; - drv->reg_pmem = __msm_register_pmem; - drv->get_frame = __msm_get_frame; - drv->put_frame = __msm_put_frame_buf; - drv->get_pict = __msm_get_pic; - drv->drv_poll = __msm_poll_frame; - - return 0; -} -EXPORT_SYMBOL(msm_v4l2_register); - -int msm_v4l2_unregister(struct msm_v4l2_driver *drv) -{ - drv->sync = NULL; - return 0; -} -EXPORT_SYMBOL(msm_v4l2_unregister); - -static int msm_sync_init(struct msm_sync *sync, - struct platform_device *pdev, - int (*sensor_probe)(const struct msm_camera_sensor_info *, - struct msm_sensor_ctrl *)) -{ - int rc = 0; - struct msm_sensor_ctrl sctrl; - sync->sdata = pdev->dev.platform_data; - - spin_lock_init(&sync->msg_event_q_lock); - INIT_LIST_HEAD(&sync->msg_event_q); - init_waitqueue_head(&sync->msg_event_wait); - - spin_lock_init(&sync->prev_frame_q_lock); - INIT_LIST_HEAD(&sync->prev_frame_q); - init_waitqueue_head(&sync->prev_frame_wait); - - spin_lock_init(&sync->pict_frame_q_lock); - INIT_LIST_HEAD(&sync->pict_frame_q); - init_waitqueue_head(&sync->pict_frame_wait); - - wake_lock_init(&sync->wake_lock, WAKE_LOCK_IDLE, "msm_camera"); - - rc = msm_camio_probe_on(pdev); - if (rc < 0) - return rc; - rc = sensor_probe(sync->sdata, &sctrl); - if (rc >= 0) { - sync->pdev = pdev; - sync->sctrl = sctrl; - } - msm_camio_probe_off(pdev); - if (rc < 0) { - pr_err("msm_camera: failed to initialize %s\n", - sync->sdata->sensor_name); - wake_lock_destroy(&sync->wake_lock); - return rc; - } - - sync->opencnt = 0; - mutex_init(&sync->lock); - CDBG("initialized %s\n", sync->sdata->sensor_name); - return rc; -} - -static int msm_sync_destroy(struct msm_sync *sync) -{ - wake_lock_destroy(&sync->wake_lock); - return 0; -} - -static int msm_device_init(struct msm_device *pmsm, - struct msm_sync *sync, - int node) -{ - int dev_num = 3 * node; - int rc = msm_setup_cdev(pmsm, node, - MKDEV(MAJOR(msm_devno), dev_num), - "control", &msm_fops_control); - if (rc < 0) { - pr_err("error creating control node: %d\n", rc); - return rc; - } - - rc = msm_setup_cdev(pmsm + 1, node, - MKDEV(MAJOR(msm_devno), dev_num + 1), - "config", &msm_fops_config); - if (rc < 0) { - pr_err("error creating config node: %d\n", rc); - msm_tear_down_cdev(pmsm, MKDEV(MAJOR(msm_devno), - dev_num)); - return rc; - } - - rc = msm_setup_cdev(pmsm + 2, node, - MKDEV(MAJOR(msm_devno), dev_num + 2), - "frame", &msm_fops_frame); - if (rc < 0) { - pr_err("error creating frame node: %d\n", rc); - msm_tear_down_cdev(pmsm, - MKDEV(MAJOR(msm_devno), dev_num)); - msm_tear_down_cdev(pmsm + 1, - MKDEV(MAJOR(msm_devno), dev_num + 1)); - return rc; - } - - atomic_set(&pmsm[0].opened, 0); - atomic_set(&pmsm[1].opened, 0); - atomic_set(&pmsm[2].opened, 0); - - pmsm[0].sync = sync; - pmsm[1].sync = sync; - pmsm[2].sync = sync; - - return rc; -} - -int msm_camera_drv_start(struct platform_device *dev, - int (*sensor_probe)(const struct msm_camera_sensor_info *, - struct msm_sensor_ctrl *)) -{ - struct msm_device *pmsm = NULL; - struct msm_sync *sync; - int rc = -ENODEV; - static int camera_node; - - if (camera_node >= MSM_MAX_CAMERA_SENSORS) { - pr_err("msm_camera: too many camera sensors\n"); - return rc; - } - - if (!msm_class) { - /* There are three device nodes per sensor */ - rc = alloc_chrdev_region(&msm_devno, 0, - 3 * MSM_MAX_CAMERA_SENSORS, - "msm_camera"); - if (rc < 0) { - pr_err("msm_camera: failed to allocate chrdev: %d\n", - rc); - return rc; - } - - msm_class = class_create(THIS_MODULE, "msm_camera"); - if (IS_ERR(msm_class)) { - rc = PTR_ERR(msm_class); - pr_err("msm_camera: create device class failed: %d\n", - rc); - return rc; - } - } - - pmsm = kzalloc(sizeof(struct msm_device) * 3 + - sizeof(struct msm_sync), GFP_ATOMIC); - if (!pmsm) - return -ENOMEM; - sync = (struct msm_sync *)(pmsm + 3); - - rc = msm_sync_init(sync, dev, sensor_probe); - if (rc < 0) { - kfree(pmsm); - return rc; - } - - CDBG("setting camera node %d\n", camera_node); - rc = msm_device_init(pmsm, sync, camera_node); - if (rc < 0) { - msm_sync_destroy(sync); - kfree(pmsm); - return rc; - } - - camera_node++; - list_add(&sync->list, &msm_sensors); - return rc; -} -EXPORT_SYMBOL(msm_camera_drv_start); diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/dream/camera/msm_io7x.c linux-2.6.32-rc6-staging/drivers/staging/dream/camera/msm_io7x.c --- linux-2.6.32-rc6/drivers/staging/dream/camera/msm_io7x.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/dream/camera/msm_io7x.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,291 +0,0 @@ -/* - * Copyright (c) 2008-2009 QUALCOMM Incorporated - */ - -#include -#include -#include -#include -#include -#include - -#define CAMIF_CFG_RMSK 0x1fffff -#define CAM_SEL_BMSK 0x2 -#define CAM_PCLK_SRC_SEL_BMSK 0x60000 -#define CAM_PCLK_INVERT_BMSK 0x80000 -#define CAM_PAD_REG_SW_RESET_BMSK 0x100000 - -#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000 -#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000 -#define MDDI_CLK_CHICKEN_BIT_BMSK 0x80 - -#define CAM_SEL_SHFT 0x1 -#define CAM_PCLK_SRC_SEL_SHFT 0x11 -#define CAM_PCLK_INVERT_SHFT 0x13 -#define CAM_PAD_REG_SW_RESET_SHFT 0x14 - -#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10 -#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF -#define MDDI_CLK_CHICKEN_BIT_SHFT 0x7 -#define APPS_RESET_OFFSET 0x00000210 - -static struct clk *camio_vfe_mdc_clk; -static struct clk *camio_mdc_clk; -static struct clk *camio_vfe_clk; - -static struct msm_camera_io_ext camio_ext; -static struct resource *appio, *mdcio; -void __iomem *appbase, *mdcbase; - -static struct msm_camera_io_ext camio_ext; -static struct resource *appio, *mdcio; -void __iomem *appbase, *mdcbase; - -extern int clk_set_flags(struct clk *clk, unsigned long flags); - -int msm_camio_clk_enable(enum msm_camio_clk_type clktype) -{ - int rc = -1; - struct clk *clk = NULL; - - switch (clktype) { - case CAMIO_VFE_MDC_CLK: - clk = camio_vfe_mdc_clk = clk_get(NULL, "vfe_mdc_clk"); - break; - - case CAMIO_MDC_CLK: - clk = camio_mdc_clk = clk_get(NULL, "mdc_clk"); - break; - - case CAMIO_VFE_CLK: - clk = camio_vfe_clk = clk_get(NULL, "vfe_clk"); - break; - - default: - break; - } - - if (!IS_ERR(clk)) { - clk_enable(clk); - rc = 0; - } - - return rc; -} - -int msm_camio_clk_disable(enum msm_camio_clk_type clktype) -{ - int rc = -1; - struct clk *clk = NULL; - - switch (clktype) { - case CAMIO_VFE_MDC_CLK: - clk = camio_vfe_mdc_clk; - break; - - case CAMIO_MDC_CLK: - clk = camio_mdc_clk; - break; - - case CAMIO_VFE_CLK: - clk = camio_vfe_clk; - break; - - default: - break; - } - - if (!IS_ERR(clk)) { - clk_disable(clk); - clk_put(clk); - rc = 0; - } - - return rc; -} - -void msm_camio_clk_rate_set(int rate) -{ - struct clk *clk = camio_vfe_clk; - - if (clk != ERR_PTR(-ENOENT)) - clk_set_rate(clk, rate); -} - -int msm_camio_enable(struct platform_device *pdev) -{ - int rc = 0; - struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; - struct msm_camera_device_platform_data *camdev = sinfo->pdata; - - camio_ext = camdev->ioext; - - appio = request_mem_region(camio_ext.appphy, - camio_ext.appsz, pdev->name); - if (!appio) { - rc = -EBUSY; - goto enable_fail; - } - - appbase = ioremap(camio_ext.appphy, - camio_ext.appsz); - if (!appbase) { - rc = -ENOMEM; - goto apps_no_mem; - } - - mdcio = request_mem_region(camio_ext.mdcphy, - camio_ext.mdcsz, pdev->name); - if (!mdcio) { - rc = -EBUSY; - goto mdc_busy; - } - - mdcbase = ioremap(camio_ext.mdcphy, - camio_ext.mdcsz); - if (!mdcbase) { - rc = -ENOMEM; - goto mdc_no_mem; - } - - camdev->camera_gpio_on(); - - msm_camio_clk_enable(CAMIO_VFE_CLK); - msm_camio_clk_enable(CAMIO_MDC_CLK); - msm_camio_clk_enable(CAMIO_VFE_MDC_CLK); - return 0; - -mdc_no_mem: - release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz); -mdc_busy: - iounmap(appbase); -apps_no_mem: - release_mem_region(camio_ext.appphy, camio_ext.appsz); -enable_fail: - return rc; -} - -void msm_camio_disable(struct platform_device *pdev) -{ - struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; - struct msm_camera_device_platform_data *camdev = sinfo->pdata; - - iounmap(mdcbase); - release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz); - iounmap(appbase); - release_mem_region(camio_ext.appphy, camio_ext.appsz); - - camdev->camera_gpio_off(); - - msm_camio_clk_disable(CAMIO_VFE_CLK); - msm_camio_clk_disable(CAMIO_MDC_CLK); - msm_camio_clk_disable(CAMIO_VFE_MDC_CLK); -} - -void msm_camio_camif_pad_reg_reset(void) -{ - uint32_t reg; - uint32_t mask, value; - - /* select CLKRGM_VFE_SRC_CAM_VFE_SRC: internal source */ - msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL); - - reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; - - mask = CAM_SEL_BMSK | - CAM_PCLK_SRC_SEL_BMSK | - CAM_PCLK_INVERT_BMSK; - - value = 1 << CAM_SEL_SHFT | - 3 << CAM_PCLK_SRC_SEL_SHFT | - 0 << CAM_PCLK_INVERT_SHFT; - - writel((reg & (~mask)) | (value & mask), mdcbase); - mdelay(10); - - reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; - mask = CAM_PAD_REG_SW_RESET_BMSK; - value = 1 << CAM_PAD_REG_SW_RESET_SHFT; - writel((reg & (~mask)) | (value & mask), mdcbase); - mdelay(10); - - reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; - mask = CAM_PAD_REG_SW_RESET_BMSK; - value = 0 << CAM_PAD_REG_SW_RESET_SHFT; - writel((reg & (~mask)) | (value & mask), mdcbase); - mdelay(10); - - msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL); - mdelay(10); -} - -void msm_camio_vfe_blk_reset(void) -{ - uint32_t val; - - val = readl(appbase + 0x00000210); - val |= 0x1; - writel(val, appbase + 0x00000210); - mdelay(10); - - val = readl(appbase + 0x00000210); - val &= ~0x1; - writel(val, appbase + 0x00000210); - mdelay(10); -} - -void msm_camio_camif_pad_reg_reset_2(void) -{ - uint32_t reg; - uint32_t mask, value; - - reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; - mask = CAM_PAD_REG_SW_RESET_BMSK; - value = 1 << CAM_PAD_REG_SW_RESET_SHFT; - writel((reg & (~mask)) | (value & mask), mdcbase); - mdelay(10); - - reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; - mask = CAM_PAD_REG_SW_RESET_BMSK; - value = 0 << CAM_PAD_REG_SW_RESET_SHFT; - writel((reg & (~mask)) | (value & mask), mdcbase); - mdelay(10); -} - -void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype) -{ - struct clk *clk = NULL; - - clk = camio_vfe_clk; - - if (clk != NULL && clk != ERR_PTR(-ENOENT)) { - switch (srctype) { - case MSM_CAMIO_CLK_SRC_INTERNAL: - clk_set_flags(clk, 0x00000100 << 1); - break; - - case MSM_CAMIO_CLK_SRC_EXTERNAL: - clk_set_flags(clk, 0x00000100); - break; - - default: - break; - } - } -} - -int msm_camio_probe_on(struct platform_device *pdev) -{ - struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; - struct msm_camera_device_platform_data *camdev = sinfo->pdata; - camdev->camera_gpio_on(); - return msm_camio_clk_enable(CAMIO_VFE_CLK); -} - -int msm_camio_probe_off(struct platform_device *pdev) -{ - struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; - struct msm_camera_device_platform_data *camdev = sinfo->pdata; - camdev->camera_gpio_off(); - return msm_camio_clk_disable(CAMIO_VFE_CLK); -} diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/dream/camera/msm_io8x.c linux-2.6.32-rc6-staging/drivers/staging/dream/camera/msm_io8x.c --- linux-2.6.32-rc6/drivers/staging/dream/camera/msm_io8x.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/dream/camera/msm_io8x.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,320 +0,0 @@ -/* - * Copyright (c) 2008-2009 QUALCOMM Incorporated - */ - -#include -#include -#include -#include -#include -#include - -#define CAMIF_CFG_RMSK 0x1fffff -#define CAM_SEL_BMSK 0x2 -#define CAM_PCLK_SRC_SEL_BMSK 0x60000 -#define CAM_PCLK_INVERT_BMSK 0x80000 -#define CAM_PAD_REG_SW_RESET_BMSK 0x100000 - -#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000 -#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000 -#define MDDI_CLK_CHICKEN_BIT_BMSK 0x80 - -#define CAM_SEL_SHFT 0x1 -#define CAM_PCLK_SRC_SEL_SHFT 0x11 -#define CAM_PCLK_INVERT_SHFT 0x13 -#define CAM_PAD_REG_SW_RESET_SHFT 0x14 - -#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10 -#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF -#define MDDI_CLK_CHICKEN_BIT_SHFT 0x7 -#define APPS_RESET_OFFSET 0x00000210 - -static struct clk *camio_vfe_mdc_clk; -static struct clk *camio_mdc_clk; -static struct clk *camio_vfe_clk; -static struct clk *camio_vfe_axi_clk; -static struct msm_camera_io_ext camio_ext; -static struct resource *appio, *mdcio; -void __iomem *appbase, *mdcbase; - -extern int clk_set_flags(struct clk *clk, unsigned long flags); - -int msm_camio_clk_enable(enum msm_camio_clk_type clktype) -{ - int rc = 0; - struct clk *clk = NULL; - - switch (clktype) { - case CAMIO_VFE_MDC_CLK: - camio_vfe_mdc_clk = - clk = clk_get(NULL, "vfe_mdc_clk"); - break; - - case CAMIO_MDC_CLK: - camio_mdc_clk = - clk = clk_get(NULL, "mdc_clk"); - break; - - case CAMIO_VFE_CLK: - camio_vfe_clk = - clk = clk_get(NULL, "vfe_clk"); - break; - - case CAMIO_VFE_AXI_CLK: - camio_vfe_axi_clk = - clk = clk_get(NULL, "vfe_axi_clk"); - break; - - default: - break; - } - - if (!IS_ERR(clk)) - clk_enable(clk); - else - rc = -1; - - return rc; -} - -int msm_camio_clk_disable(enum msm_camio_clk_type clktype) -{ - int rc = 0; - struct clk *clk = NULL; - - switch (clktype) { - case CAMIO_VFE_MDC_CLK: - clk = camio_vfe_mdc_clk; - break; - - case CAMIO_MDC_CLK: - clk = camio_mdc_clk; - break; - - case CAMIO_VFE_CLK: - clk = camio_vfe_clk; - break; - - case CAMIO_VFE_AXI_CLK: - clk = camio_vfe_axi_clk; - break; - - default: - break; - } - - if (!IS_ERR(clk)) { - clk_disable(clk); - clk_put(clk); - } else - rc = -1; - - return rc; -} - -void msm_camio_clk_rate_set(int rate) -{ - struct clk *clk = camio_vfe_mdc_clk; - - /* TODO: check return */ - clk_set_rate(clk, rate); -} - -int msm_camio_enable(struct platform_device *pdev) -{ - int rc = 0; - struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; - struct msm_camera_device_platform_data *camdev = sinfo->pdata; - - camio_ext = camdev->ioext; - - appio = request_mem_region(camio_ext.appphy, - camio_ext.appsz, pdev->name); - if (!appio) { - rc = -EBUSY; - goto enable_fail; - } - - appbase = ioremap(camio_ext.appphy, - camio_ext.appsz); - if (!appbase) { - rc = -ENOMEM; - goto apps_no_mem; - } - - mdcio = request_mem_region(camio_ext.mdcphy, - camio_ext.mdcsz, pdev->name); - if (!mdcio) { - rc = -EBUSY; - goto mdc_busy; - } - - mdcbase = ioremap(camio_ext.mdcphy, - camio_ext.mdcsz); - if (!mdcbase) { - rc = -ENOMEM; - goto mdc_no_mem; - } - - camdev->camera_gpio_on(); - - msm_camio_clk_enable(CAMIO_VFE_CLK); - msm_camio_clk_enable(CAMIO_MDC_CLK); - msm_camio_clk_enable(CAMIO_VFE_MDC_CLK); - msm_camio_clk_enable(CAMIO_VFE_AXI_CLK); - return 0; - -mdc_no_mem: - release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz); -mdc_busy: - iounmap(appbase); -apps_no_mem: - release_mem_region(camio_ext.appphy, camio_ext.appsz); -enable_fail: - return rc; -} - -void msm_camio_disable(struct platform_device *pdev) -{ - struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; - struct msm_camera_device_platform_data *camdev = sinfo->pdata; - - iounmap(mdcbase); - release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz); - iounmap(appbase); - release_mem_region(camio_ext.appphy, camio_ext.appsz); - - camdev->camera_gpio_off(); - - msm_camio_clk_disable(CAMIO_VFE_MDC_CLK); - msm_camio_clk_disable(CAMIO_MDC_CLK); - msm_camio_clk_disable(CAMIO_VFE_CLK); - msm_camio_clk_disable(CAMIO_VFE_AXI_CLK); -} - -void msm_camio_camif_pad_reg_reset(void) -{ - uint32_t reg; - uint32_t mask, value; - - /* select CLKRGM_VFE_SRC_CAM_VFE_SRC: internal source */ - msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL); - - reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; - - mask = CAM_SEL_BMSK | - CAM_PCLK_SRC_SEL_BMSK | - CAM_PCLK_INVERT_BMSK | - EXT_CAM_HSYNC_POL_SEL_BMSK | - EXT_CAM_VSYNC_POL_SEL_BMSK | - MDDI_CLK_CHICKEN_BIT_BMSK; - - value = 1 << CAM_SEL_SHFT | - 3 << CAM_PCLK_SRC_SEL_SHFT | - 0 << CAM_PCLK_INVERT_SHFT | - 0 << EXT_CAM_HSYNC_POL_SEL_SHFT | - 0 << EXT_CAM_VSYNC_POL_SEL_SHFT | - 0 << MDDI_CLK_CHICKEN_BIT_SHFT; - writel((reg & (~mask)) | (value & mask), mdcbase); - mdelay(10); - - reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; - mask = CAM_PAD_REG_SW_RESET_BMSK; - value = 1 << CAM_PAD_REG_SW_RESET_SHFT; - writel((reg & (~mask)) | (value & mask), mdcbase); - mdelay(10); - - reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; - mask = CAM_PAD_REG_SW_RESET_BMSK; - value = 0 << CAM_PAD_REG_SW_RESET_SHFT; - writel((reg & (~mask)) | (value & mask), mdcbase); - mdelay(10); - - msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL); - - mdelay(10); - - /* todo: check return */ - if (camio_vfe_clk) - clk_set_rate(camio_vfe_clk, 96000000); -} - -void msm_camio_vfe_blk_reset(void) -{ - uint32_t val; - - val = readl(appbase + 0x00000210); - val |= 0x1; - writel(val, appbase + 0x00000210); - mdelay(10); - - val = readl(appbase + 0x00000210); - val &= ~0x1; - writel(val, appbase + 0x00000210); - mdelay(10); -} - -void msm_camio_camif_pad_reg_reset_2(void) -{ - uint32_t reg; - uint32_t mask, value; - - reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; - mask = CAM_PAD_REG_SW_RESET_BMSK; - value = 1 << CAM_PAD_REG_SW_RESET_SHFT; - writel((reg & (~mask)) | (value & mask), mdcbase); - mdelay(10); - - reg = (readl(mdcbase)) & CAMIF_CFG_RMSK; - mask = CAM_PAD_REG_SW_RESET_BMSK; - value = 0 << CAM_PAD_REG_SW_RESET_SHFT; - writel((reg & (~mask)) | (value & mask), mdcbase); - mdelay(10); -} - -void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype) -{ - struct clk *clk = NULL; - - clk = camio_vfe_clk; - - if (clk != NULL) { - switch (srctype) { - case MSM_CAMIO_CLK_SRC_INTERNAL: - clk_set_flags(clk, 0x00000100 << 1); - break; - - case MSM_CAMIO_CLK_SRC_EXTERNAL: - clk_set_flags(clk, 0x00000100); - break; - - default: - break; - } - } -} - -void msm_camio_clk_axi_rate_set(int rate) -{ - struct clk *clk = camio_vfe_axi_clk; - /* todo: check return */ - clk_set_rate(clk, rate); -} - -int msm_camio_probe_on(struct platform_device *pdev) -{ - struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; - struct msm_camera_device_platform_data *camdev = sinfo->pdata; - - camdev->camera_gpio_on(); - return msm_camio_clk_enable(CAMIO_VFE_MDC_CLK); -} - -int msm_camio_probe_off(struct platform_device *pdev) -{ - struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data; - struct msm_camera_device_platform_data *camdev = sinfo->pdata; - - camdev->camera_gpio_off(); - return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK); -} diff -Naur -X linux-2.6.32-rc6/Documentation/dontdiff linux-2.6.32-rc6/drivers/staging/dream/camera/msm_v4l2.c linux-2.6.32-rc6-staging/drivers/staging/dream/camera/msm_v4l2.c --- linux-2.6.32-rc6/drivers/staging/dream/camera/msm_v4l2.c 2009-11-04 15:20:36.000000000 -0800 +++ linux-2.6.32-rc6-staging/drivers/staging/dream/camera/msm_v4l2.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,797 +0,0 @@ -/* - * - * Copyright (C) 2008-2009 QUALCOMM Incorporated. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/*#include */ - -#define MSM_V4L2_START_SNAPSHOT _IOWR('V', BASE_VIDIOC_PRIVATE+1, \ - struct v4l2_buffer) - -#define MSM_V4L2_GET_PICTURE _IOWR('V', BASE_VIDIOC_PRIVATE+2, \ - struct v4l2_buffer) - -#define MSM_V4L2_DEVICE_NAME "msm_v4l2" - -#define MSM_V4L2_PROC_NAME "msm_v4l2" - -#define MSM_V4L2_DEVNUM_MPEG2 0 -#define MSM_V4L2_DEVNUM_YUV 20 - -/* HVGA-P (portrait) and HVGA-L (landscape) */ -#define MSM_V4L2_WIDTH 480 -#define MSM_V4L2_HEIGHT 320 - -#if 1 -#define D(fmt, args...) printk(KERN_INFO "msm_v4l2: " fmt, ##args) -#else -#define D(fmt, args...) do {} while (0) -#endif - -#define PREVIEW_FRAMES_NUM 4 - -struct msm_v4l2_device { - struct list_head read_queue; - struct v4l2_format current_cap_format; - struct v4l2_format current_pix_format; - struct video_device *pvdev; - struct msm_v4l2_driver *drv; - uint8_t opencnt; - - spinlock_t read_queue_lock; -}; - -static struct msm_v4l2_device *g_pmsm_v4l2_dev; - - -static DEFINE_MUTEX(msm_v4l2_opencnt_lock); - -static int msm_v4l2_open(struct file *f) -{ - int rc = 0; - D("%s\n", __func__); - mutex_lock(&msm_v4l2_opencnt_lock); - if (!g_pmsm_v4l2_dev->opencnt) { - rc = g_pmsm_v4l2_dev->drv->open( - g_pmsm_v4l2_dev->drv->sync, - MSM_APPS_ID_V4L2); - } - g_pmsm_v4l2_dev->opencnt++; - mutex_unlock(&msm_v4l2_opencnt_lock); - return rc; -} - -static int msm_v4l2_release(struct file *f) -{ - int rc = 0; - D("%s\n", __func__); - mutex_lock(&msm_v4l2_opencnt_lock); - if (!g_pmsm_v4l2_dev->opencnt) { - g_pmsm_v4l2_dev->opencnt--; - if (!g_pmsm_v4l2_dev->opencnt) { - rc = g_pmsm_v4l2_dev->drv->release( - g_pmsm_v4l2_dev->drv->sync); - } - } - mutex_unlock(&msm_v4l2_opencnt_lock); - return rc; -} - -static unsigned int msm_v4l2_poll(struct file *f, struct poll_table_struct *w) -{ - return g_pmsm_v4l2_dev->drv->drv_poll(g_pmsm_v4l2_dev->drv->sync, f, w); -} - -static long msm_v4l2_ioctl(struct file *filep, - unsigned int cmd, unsigned long arg) -{ - struct msm_ctrl_cmd *ctrlcmd; - - D("msm_v4l2_ioctl, cmd = %d, %d\n", cmd, __LINE__); - - switch (cmd) { - case MSM_V4L2_START_SNAPSHOT: - - ctrlc