diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2010-02-17 15:17:35 -0800 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-02-17 15:17:35 -0800 |
| commit | 613f3b6cf3cb68645b8fef3c35a7efd11a5a4cc1 (patch) | |
| tree | 4b5723c461a83dcf620c5416652bce1a50e15756 | |
| parent | 7a8fe70fb029ecb97eeb2d304e8d805947cbba85 (diff) | |
| download | patches-613f3b6cf3cb68645b8fef3c35a7efd11a5a4cc1.tar.gz | |
more patches
20 files changed, 5138 insertions, 0 deletions
diff --git a/driver-core/sysfs-differentiate-between-locking-links-and-non-links.patch b/driver-core/sysfs-differentiate-between-locking-links-and-non-links.patch new file mode 100644 index 00000000000000..8f4db1516eae61 --- /dev/null +++ b/driver-core/sysfs-differentiate-between-locking-links-and-non-links.patch @@ -0,0 +1,62 @@ +From neilb@suse.de Wed Feb 17 14:37:21 2010 +From: Neil Brown <neilb@suse.de> +Date: Wed, 10 Feb 2010 12:09:33 +1100 +Subject: sysfs: differentiate between locking links and non-links +To: Eric W Biederman <ebiederm@xmission.com> +Cc: Tejun Heo <tj@kernel.org>, Greg Kroah-Hartman <gregkh@suse.de> +Message-ID: <19314.1869.847327.15190@notabene.brown> + +sysfs: differentiate between locking links and non-links for sysfs + +symlinks and non-symlink is sysfs are very different. +A symlink can never be locked (active) while an attribute +modification routine is running. So removing symlink from an +attribute 'store' routine should be permitted without any lockdep +warnings. + +So split the lockdep context for 's_active' in two, one for symlinks +and other for everything else. + +Signed-off-by: NeilBrown <neilb@suse.de> +Cc: Eric Biederman <ebiederm@xmission.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + fs/sysfs/dir.c | 5 ++++- + fs/sysfs/sysfs.h | 6 +++--- + 2 files changed, 7 insertions(+), 4 deletions(-) + +--- a/fs/sysfs/dir.c ++++ b/fs/sysfs/dir.c +@@ -354,7 +354,10 @@ struct sysfs_dirent *sysfs_new_dirent(co + + atomic_set(&sd->s_count, 1); + atomic_set(&sd->s_active, 0); +- sysfs_dirent_init_lockdep(sd); ++ if (type & SYSFS_KOBJ_LINK) ++ sysfs_dirent_init_lockdep(sd, "link"); ++ else ++ sysfs_dirent_init_lockdep(sd, "non_link"); + + sd->s_name = name; + sd->s_mode = mode; +--- a/fs/sysfs/sysfs.h ++++ b/fs/sysfs/sysfs.h +@@ -89,14 +89,14 @@ static inline unsigned int sysfs_type(st + } + + #ifdef CONFIG_DEBUG_LOCK_ALLOC +-#define sysfs_dirent_init_lockdep(sd) \ ++#define sysfs_dirent_init_lockdep(sd, type) \ + do { \ + static struct lock_class_key __key; \ + \ +- lockdep_init_map(&sd->dep_map, "s_active", &__key, 0); \ ++ lockdep_init_map(&sd->dep_map, "s_active_" type, &__key, 0); \ + } while(0) + #else +-#define sysfs_dirent_init_lockdep(sd) do {} while(0) ++#define sysfs_dirent_init_lockdep(sd, type) do {} while(0) + #endif + + /* @@ -68,6 +68,7 @@ driver-core/w1-move-omap_hdq-s-probe-function-to-.devinit.text.patch driver-core/media-move-omap24xxcam-s-probe-function-to-.devinit.text.patch driver-core/auxdisplay-move-cfag12864bfb-s-probe-function-to-.devinit.text.patch driver-core/net-move-am79c961-s-probe-function-to-.devinit.text.patch +driver-core/sysfs-differentiate-between-locking-links-and-non-links.patch driver-core/driver-core-create-lock-unlock-functions-for-struct-device.patch driver-core/drivers-base-convert-sema.patch @@ -108,6 +109,12 @@ tty/serial-bfin_5xx-kgdboc-should-accept-gdb-break-only-when-it-is-active.patch tty/serial-bfin_5xx-pull-in-linux-io.h-for-ioremap-prototypes.patch tty/serial-bcm63xx_uart-don-t-use-kfree-on-non-kmalloced-area.patch tty/serial-bcm63xx_uart-allow-more-than-one-uart-to-be-registered.patch +tty/sdio_uart-use-kfifo-instead-of-the-messy-circ-stuff.patch +tty/nozomi-add-tty_port-usage.patch +tty/nozomi-fix-mutex-handling.patch +tty/nozomi-tidy-up-the-pci-table.patch +tty/serial-timberdale-remove-dependancies.patch +tty/tty-fix-the-ldisc-hangup-race.patch ################################### @@ -297,6 +304,12 @@ usb/usb-f_mass_storage-fix-crash-on-bind-error.patch usb/usb-remove-unsupported-usb-gadget-drivers.patch usb/usb-atmel-uaba-adding-invert-vbus_pin.patch usb/usb-serial-add-support-for-vivotech-vivopay-devices.patch +usb/usb-ehci-dbgp-split-pid-register-updates-for-in-and-out-pipes.patch +usb/usb-serial-remove-unnecessary-n-s-from-dbg-uses.patch +usb/usb-convert-concatenated-__file__-to-s-__file__.patch +usb/usb-extend-and-neaten-dbg-macros.patch +usb/usb-cp210x-add-81e8-zephyr-bioharness.patch +usb/tty-fix-various-bogus-warn-checks-in-the-usb-serial-layer.patch ####################################### @@ -558,6 +571,13 @@ staging/staging-dt3155-fix-coding-style-issues-in-dt3155_io.c.patch staging/staging-mimio-remove-the-mimio-driver.patch +staging/staging-rar_register-renaming-driver-to-rar_register.patch +staging/staging-rar_register-renaming-directory-to-rar_register.patch +staging/staging-rar_register-provide-better-explanation-in-kconfig.patch +staging/staging-rar_register-fix-checkpatch-errors-and-debug-header-file.patch +staging/staging-rar_register-fix-checkpatch-errors-and-debug-program-file.patch +staging/staging-rar_register-add-suspend-and-resume-functions.patch + dvb-l64781.ko-broken-with-gcc-4.5.patch diff --git a/staging/staging-rar_register-add-suspend-and-resume-functions.patch b/staging/staging-rar_register-add-suspend-and-resume-functions.patch new file mode 100644 index 00000000000000..55c2a4855c5a14 --- /dev/null +++ b/staging/staging-rar_register-add-suspend-and-resume-functions.patch @@ -0,0 +1,50 @@ +From mark.a.allyn@intel.com Wed Feb 17 14:48:36 2010 +From: Mark Allyn <mark.a.allyn@intel.com> +Date: Fri, 5 Feb 2010 10:53:34 -0800 +Subject: Staging: rar_register: add suspend and resume functions +To: linux-kernel@vger.kernel.org, alan@linux.intel.com, charles.f.johnson@intel.com, greg@kroah.com +Cc: Mark Allyn <mark.a.allyn@intel.com> +Message-ID: <1265396014-16107-1-git-send-email-mark.a.allyn@intel.com> + + +Add suspend and resume functions (which are currently stubs +returning -ENOSYS) + +Signed-off-by: Mark Allyn <mark.a.allyn@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/rar_register/rar_register.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +--- a/drivers/staging/rar_register/rar_register.c ++++ b/drivers/staging/rar_register/rar_register.c +@@ -506,6 +506,17 @@ int register_rar(int (*callback)(void *y + } + EXPORT_SYMBOL(register_rar); + ++/* Suspend - returns -ENOSYS */ ++static int rar_suspend(struct pci_dev *dev, pm_message_t state) ++{ ++ return -ENOSYS; ++} ++ ++static int rar_resume(struct pci_dev *dev) ++{ ++ return -ENOSYS; ++} ++ + /* + * This function registers the driver with the device subsystem ( + * either PCI, USB, etc). +@@ -582,7 +593,9 @@ const struct pci_device_id *my_id_table + static struct pci_driver rar_pci_driver = { + .name = "rar_register_driver", + .id_table = rar_pci_id_tbl, +- .probe = rar_probe ++ .probe = rar_probe, ++ .suspend = rar_suspend, ++ .resume = rar_resume + }; + + static int __init rar_init_handler(void) diff --git a/staging/staging-rar_register-fix-checkpatch-errors-and-debug-header-file.patch b/staging/staging-rar_register-fix-checkpatch-errors-and-debug-header-file.patch new file mode 100644 index 00000000000000..00cbb8151b6deb --- /dev/null +++ b/staging/staging-rar_register-fix-checkpatch-errors-and-debug-header-file.patch @@ -0,0 +1,152 @@ +From mark.a.allyn@intel.com Wed Feb 17 14:47:53 2010 +From: Mark Allyn <mark.a.allyn@intel.com> +Date: Fri, 5 Feb 2010 10:53:00 -0800 +Subject: Staging: rar_register: fix checkpatch errors and debug header file +To: linux-kernel@vger.kernel.org, alan@linux.intel.com, charles.f.johnson@intel.com, greg@kroah.com +Cc: Mark Allyn <mark.a.allyn@intel.com> +Message-ID: <1265395980-16029-1-git-send-email-mark.a.allyn@intel.com> + + +Signed-off-by: Mark Allyn <mark.a.allyn@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/rar_register/rar_register.h | 115 +++++++++++++--------------- + 1 file changed, 55 insertions(+), 60 deletions(-) + +--- a/drivers/staging/rar_register/rar_register.h ++++ b/drivers/staging/rar_register/rar_register.h +@@ -1,9 +1,53 @@ +-/* === RAR Physical Addresses === */ +-struct RAR_address_struct { +- u32 low; +- u32 high; ++/* ++ * Copyright (C) 2010 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of version 2 of the GNU General ++ * Public License as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be ++ * useful, but WITHOUT ANY WARRANTY; without even the implied ++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ++ * PURPOSE. See the GNU General Public License for more details. ++ * You should have received a copy of the GNU General Public ++ * License along with this program; if not, write to the Free ++ * Software Foundation, Inc., 59 Temple Place - Suite 330, ++ * Boston, MA 02111-1307, USA. ++ * The full GNU General Public License is included in this ++ * distribution in the file called COPYING. ++ */ ++ ++ ++#ifndef _RAR_REGISTER_H ++#define _RAR_REGISTER_H ++ ++# include <linux/types.h> ++ ++/* following are used both in drivers as well as user space apps */ ++enum RAR_type { ++ RAR_TYPE_VIDEO = 0, ++ RAR_TYPE_AUDIO, ++ RAR_TYPE_IMAGE, ++ RAR_TYPE_DATA + }; + ++#ifdef __KERNEL__ ++ ++/* PCI device id for controller */ ++#define PCI_RAR_DEVICE_ID 0x4110 ++ ++/* The register_rar function is to used by other device drivers ++ * to ensure that this driver is ready. As we cannot be sure of ++ * the compile/execute order of dirvers in ther kernel, it is ++ * best to give this driver a callback function to call when ++ * it is ready to give out addresses. The callback function ++ * would have those steps that continue the initialization of ++ * a driver that do require a valid RAR address. One of those ++ * steps would be to call get_rar_address() ++ * This function return 0 on success an -1 on failure. ++ */ ++int register_rar(int (*callback)(void *yourparameter), void *yourparameter); ++ + /* The get_rar_address function is used by other device drivers + * to obtain RAR address information on a RAR. It takes two + * parameter: +@@ -19,10 +63,11 @@ struct RAR_address_struct { + * The function returns a 0 upon success or a -1 if there is no RAR + * facility on this system. + */ +-int get_rar_address(int rar_index, struct RAR_address_struct *addresses); +- ++int rar_get_address(int rar_index, ++ dma_addr_t *start_address, ++ dma_addr_t *end_address); + +-/* The lock_rar function is used by other device drivers to lock an RAR. ++/* The lock_rar function is ued by other device drivers to lock an RAR. + * once an RAR is locked, it stays locked until the next system reboot. + * The function takes one parameter: + * +@@ -33,57 +78,7 @@ int get_rar_address(int rar_index, struc + * The function returns a 0 upon success or a -1 if there is no RAR + * facility on this system. + */ +-int lock_rar(int rar_index); +- +- +-/* DEBUG LEVEL MASKS */ +-#define RAR_DEBUG_LEVEL_BASIC 0x1 +- +-#define RAR_DEBUG_LEVEL_REGISTERS 0x2 +- +-#define RAR_DEBUG_LEVEL_EXTENDED 0x4 +- +-#define DEBUG_LEVEL 0x7 +- +-/* FUNCTIONAL MACROS */ +- +-/* debug macro without paramaters */ +-#define DEBUG_PRINT_0(DEBUG_LEVEL , info) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info); \ +- } \ +-} while (0) +- +-/* debug macro with 1 paramater */ +-#define DEBUG_PRINT_1(DEBUG_LEVEL , info , param1) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info , param1); \ +- } \ +-} while (0) +- +-/* debug macro with 2 paramaters */ +-#define DEBUG_PRINT_2(DEBUG_LEVEL , info , param1, param2) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info , param1, param2); \ +- } \ +-} while (0) +- +-/* debug macro with 3 paramaters */ +-#define DEBUG_PRINT_3(DEBUG_LEVEL , info , param1, param2 , param3) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info , param1, param2 , param3); \ +- } \ +-} while (0) +- +-/* debug macro with 4 paramaters */ +-#define DEBUG_PRINT_4(DEBUG_LEVEL , info , param1, param2 , param3 , param4) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info , param1, param2 , param3 , param4); \ +- } \ +-} while (0) ++int rar_lock(int rar_index); + ++#endif /* __KERNEL__ */ ++#endif /* _RAR_REGISTER_H */ diff --git a/staging/staging-rar_register-fix-checkpatch-errors-and-debug-program-file.patch b/staging/staging-rar_register-fix-checkpatch-errors-and-debug-program-file.patch new file mode 100644 index 00000000000000..c10cf839eaf2af --- /dev/null +++ b/staging/staging-rar_register-fix-checkpatch-errors-and-debug-program-file.patch @@ -0,0 +1,871 @@ +From mark.a.allyn@intel.com Wed Feb 17 14:48:15 2010 +From: Mark Allyn <mark.a.allyn@intel.com> +Date: Fri, 5 Feb 2010 10:53:18 -0800 +Subject: Staging: rar_register: fix checkpatch errors and debug program file +To: linux-kernel@vger.kernel.org, alan@linux.intel.com, charles.f.johnson@intel.com, greg@kroah.com +Cc: Mark Allyn <mark.a.allyn@intel.com> +Message-ID: <1265395998-16080-1-git-send-email-mark.a.allyn@intel.com> + + +Signed-off-by: Mark Allyn <mark.a.allyn@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/rar_register/rar_register.c | 748 +++++++++++++++++----------- + 1 file changed, 455 insertions(+), 293 deletions(-) + +--- a/drivers/staging/rar_register/rar_register.c ++++ b/drivers/staging/rar_register/rar_register.c +@@ -1,33 +1,67 @@ +-#include <linux/init.h> +-#include <linux/module.h> +-#include <linux/fs.h> +-#include <linux/cdev.h> +-#include <linux/kdev_t.h> +-#include <linux/semaphore.h> +-#include <linux/mm.h> +-#include <linux/poll.h> +-#include <linux/wait.h> +-#include <linux/ioctl.h> +-#include <linux/ioport.h> +-#include <linux/io.h> +-#include <linux/interrupt.h> +-#include <linux/pagemap.h> +-#include <linux/pci.h> +-#include <linux/firmware.h> +-#include <linux/sched.h> ++/* ++ * rar_register.c - An Intel Restricted Access Region register driver ++ * ++ * Copyright(c) 2009 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ++ * 02111-1307, USA. ++ * ++ * ------------------------------------------------------------------- ++ * 20091204 Mark Allyn <mark.a.allyn@intel.com> ++ * Ossama Othman <ossama.othman@intel.com> ++ * Cleanup per feedback from Alan Cox and Arjan Van De Ven ++ * ++ * 20090806 Ossama Othman <ossama.othman@intel.com> ++ * Return zero high address if upper 22 bits is zero. ++ * Cleaned up checkpatch errors. ++ * Clarified that driver is dealing with bus addresses. ++ * ++ * 20090702 Ossama Othman <ossama.othman@intel.com> ++ * Removed unnecessary include directives ++ * Cleaned up spinlocks. ++ * Cleaned up logging. ++ * Improved invalid parameter checks. ++ * Fixed and simplified RAR address retrieval and RAR locking ++ * code. ++ * ++ * 20090626 Mark Allyn <mark.a.allyn@intel.com> ++ * Initial publish ++ */ ++ ++#define DEBUG 1 ++ + #include "rar_register.h" + +-/* The following defines are for the IPC process to retrieve RAR in */ ++#include <linux/module.h> ++#include <linux/pci.h> ++#include <linux/spinlock.h> ++#include <linux/device.h> ++#include <linux/kernel.h> + + /* === Lincroft Message Bus Interface === */ + /* Message Control Register */ + #define LNC_MCR_OFFSET 0xD0 + ++/* Maximum number of clients (other drivers using this driver) */ ++#define MAX_RAR_CLIENTS 10 ++ + /* Message Data Register */ + #define LNC_MDR_OFFSET 0xD4 + + /* Message Opcodes */ +-#define LNC_MESSAGE_READ_OPCODE 0xD0 ++#define LNC_MESSAGE_READ_OPCODE 0xD0 + #define LNC_MESSAGE_WRITE_OPCODE 0xE0 + + /* Message Write Byte Enables */ +@@ -37,59 +71,73 @@ + #define LNC_BUNIT_PORT 0x3 + + /* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */ +-#define LNC_BRAR0L 0x10 +-#define LNC_BRAR0H 0x11 +-#define LNC_BRAR1L 0x12 +-#define LNC_BRAR1H 0x13 ++#define LNC_BRAR0L 0x10 ++#define LNC_BRAR0H 0x11 ++#define LNC_BRAR1L 0x12 ++#define LNC_BRAR1H 0x13 + + /* Reserved for SeP */ +-#define LNC_BRAR2L 0x14 +-#define LNC_BRAR2H 0x15 ++#define LNC_BRAR2L 0x14 ++#define LNC_BRAR2H 0x15 ++ ++/* Moorestown supports three restricted access regions. */ ++#define MRST_NUM_RAR 3 + + +-/* This structure is only used during module initialization. */ +-struct RAR_offsets { +- int low; /* Register offset for low RAR physical address. */ +- int high; /* Register offset for high RAR physical address. */ ++/* RAR Bus Address Range */ ++struct RAR_address_range { ++ dma_addr_t low; ++ dma_addr_t high; + }; + +-struct pci_dev *rar_dev; +-static uint32_t registered; +- +-/* Moorestown supports three restricted access regions. */ +-#define MRST_NUM_RAR 3 ++/* Structure containing low and high RAR register offsets. */ ++struct RAR_offsets { ++ u32 low; /* Register offset for low RAR bus address. */ ++ u32 high; /* Register offset for high RAR bus address. */ ++}; + +-struct RAR_address_struct rar_addr[MRST_NUM_RAR]; ++struct client { ++ int (*client_callback)(void *client_data); ++ void *customer_data; ++ int client_called; ++ }; + +-/* prototype for init */ +-static int __init rar_init_handler(void); +-static void __exit rar_exit_handler(void); ++static DEFINE_MUTEX(rar_mutex); ++static DEFINE_MUTEX(lnc_reg_mutex); + +-/* +- function that is activated on the successfull probe of the RAR device +-*/ +-static int __devinit rar_probe(struct pci_dev *pdev, +- const struct pci_device_id *ent); ++struct RAR_device { ++ struct RAR_offsets const rar_offsets[MRST_NUM_RAR]; ++ struct RAR_address_range rar_addr[MRST_NUM_RAR]; ++ struct pci_dev *rar_dev; ++ bool registered; ++ }; + +-static const struct pci_device_id rar_pci_id_tbl[] = { +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4110) }, +- { 0 } ++/* this platform has only one rar_device for 3 rar regions */ ++static struct RAR_device my_rar_device = { ++ .rar_offsets = { ++ [0].low = LNC_BRAR0L, ++ [0].high = LNC_BRAR0H, ++ [1].low = LNC_BRAR1L, ++ [1].high = LNC_BRAR1H, ++ [2].low = LNC_BRAR2L, ++ [2].high = LNC_BRAR2H ++ } + }; + +-MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl); ++/* this data is for handling requests from other drivers which arrive ++ * prior to this driver initializing ++ */ + +-/* field for registering driver to PCI device */ +-static struct pci_driver rar_pci_driver = { +- .name = "rar_driver", +- .id_table = rar_pci_id_tbl, +- .probe = rar_probe +-}; ++static struct client clients[MAX_RAR_CLIENTS]; ++static int num_clients; + +-/* This function is used to retrieved RAR info using the IPC message +- bus interface */ +-static int memrar_get_rar_addr(struct pci_dev *pdev, +- int offset, +- u32 *addr) ++/* ++ * This function is used to retrieved RAR info using the Lincroft ++ * message bus interface. ++ */ ++static int retrieve_rar_addr(struct pci_dev *pdev, ++ int offset, ++ dma_addr_t *addr) + { + /* + * ======== The Lincroft Message Bus Interface ======== +@@ -131,243 +179,412 @@ static int memrar_get_rar_addr(struct pc + * Data being written to this register must be written before + * writing the appropriate control message to the MCR + * register. +- */ ++ */ ++ ++ int result; + +- int result = 0; /* result */ + /* Construct control message */ + u32 const message = +- (LNC_MESSAGE_READ_OPCODE << 24) +- | (LNC_BUNIT_PORT << 16) +- | (offset << 8) +- | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); ++ (LNC_MESSAGE_READ_OPCODE << 24) ++ | (LNC_BUNIT_PORT << 16) ++ | (offset << 8) ++ | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); + +- printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset); ++ dev_dbg(&pdev->dev, "Offset for 'get' LNC MSG is %x\n", offset); + +- if (addr == 0) ++ if (addr == 0) { ++ WARN_ON(1); + return -EINVAL; ++ } ++ ++ /* ++ * We synchronize access to the Lincroft MCR and MDR registers ++ * until BOTH the command is issued through the MCR register ++ * and the corresponding data is read from the MDR register. ++ * Otherwise a race condition would exist between accesses to ++ * both registers. ++ */ ++ ++ mutex_lock(&lnc_reg_mutex); + + /* Send the control message */ +- result = pci_write_config_dword(pdev, +- LNC_MCR_OFFSET, +- message); +- +- printk(KERN_WARNING "rar- result from send ctl register is %x\n", +- result); +- +- if (!result) +- result = pci_read_config_dword(pdev, +- LNC_MDR_OFFSET, +- addr); +- +- printk(KERN_WARNING "rar- result from read data register is %x\n", +- result); +- +- printk(KERN_WARNING "rar- value read from data register is %x\n", +- *addr); +- +- if (result) +- return -1; +- else +- return 0; ++ result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message); ++ ++ dev_dbg(&pdev->dev, "Result from send ctl register is %x\n", result); ++ ++ if (!result) { ++ result = pci_read_config_dword(pdev, LNC_MDR_OFFSET, ++ (u32 *)addr); ++ dev_dbg(&pdev->dev, ++ "Result from read data register is %x\n", result); ++ ++ dev_dbg(&pdev->dev, ++ "Value read from data register is %lx\n", ++ (unsigned long)*addr); ++ } ++ ++ mutex_unlock(&lnc_reg_mutex); ++ ++ return result; + } + +-static int memrar_set_rar_addr(struct pci_dev *pdev, +- int offset, +- u32 addr) ++static int set_rar_address(struct pci_dev *pdev, ++ int offset, ++ dma_addr_t addr) + { + /* +- * ======== The Lincroft Message Bus Interface ======== +- * Lincroft registers may be obtained from the PCI +- * (the Host Bridge) using the Lincroft Message Bus +- * Interface. That message bus interface is generally +- * comprised of two registers: a control register (MCR, 0xDO) +- * and a data register (MDR, 0xD4). +- * +- * The MCR (message control register) format is the following: +- * 1. [31:24]: Opcode +- * 2. [23:16]: Port +- * 3. [15:8]: Register Offset +- * 4. [7:4]: Byte Enables (use 0xF to set all of these bits +- * to 1) +- * 5. [3:0]: reserved +- * +- * Read (0xD0) and write (0xE0) opcodes are written to the +- * control register when reading and writing to Lincroft +- * registers, respectively. +- * +- * We're interested in registers found in the Lincroft +- * B-unit. The B-unit port is 0x3. +- * +- * The six B-unit RAR register offsets we use are listed +- * earlier in this file. +- * +- * Lastly writing to the MCR register requires the "Byte +- * enables" bits to be set to 1. This may be achieved by +- * writing 0xF at bit 4. +- * +- * The MDR (message data register) format is the following: +- * 1. [31:0]: Read/Write Data +- * +- * Data being read from this register is only available after +- * writing the appropriate control message to the MCR +- * register. +- * +- * Data being written to this register must be written before +- * writing the appropriate control message to the MCR +- * register. +- */ ++ * Data being written to this register must be written before ++ * writing the appropriate control message to the MCR ++ * register. ++ * @note See rar_get_address() for a description of the ++ * message bus interface being used here. ++ */ + +- int result = 0; /* result */ ++ int result = 0; + + /* Construct control message */ +- u32 const message = +- (LNC_MESSAGE_WRITE_OPCODE << 24) +- | (LNC_BUNIT_PORT << 16) +- | (offset << 8) +- | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); ++ u32 const message = (LNC_MESSAGE_WRITE_OPCODE << 24) ++ | (LNC_BUNIT_PORT << 16) ++ | (offset << 8) ++ | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); + +- printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset); +- +- if (addr == 0) ++ if (addr == 0) { ++ WARN_ON(1); + return -EINVAL; ++ } ++ ++ dev_dbg(&pdev->dev, "Offset for 'set' LNC MSG is %x\n", offset); ++ ++ /* ++ * We synchronize access to the Lincroft MCR and MDR registers ++ * until BOTH the command is issued through the MCR register ++ * and the corresponding data is read from the MDR register. ++ * Otherwise a race condition would exist between accesses to ++ * both registers. ++ */ ++ ++ mutex_lock(&lnc_reg_mutex); + + /* Send the control message */ +- result = pci_write_config_dword(pdev, +- LNC_MDR_OFFSET, +- addr); +- +- printk(KERN_WARNING "rar- result from send ctl register is %x\n", +- result); +- +- if (!result) +- result = pci_write_config_dword(pdev, +- LNC_MCR_OFFSET, +- message); +- +- printk(KERN_WARNING "rar- result from write data register is %x\n", +- result); +- +- printk(KERN_WARNING "rar- value read to data register is %x\n", +- addr); +- +- if (result) +- return -1; +- else +- return 0; ++ result = pci_write_config_dword(pdev, LNC_MDR_OFFSET, addr); ++ ++ dev_dbg(&pdev->dev, "Result from write data register is %x\n", result); ++ ++ if (!result) { ++ dev_dbg(&pdev->dev, ++ "Value written to data register is %lx\n", ++ (unsigned long)addr); ++ ++ result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message); ++ ++ dev_dbg(&pdev->dev, "Result from send ctl register is %x\n", ++ result); ++ } ++ ++ mutex_unlock(&lnc_reg_mutex); ++ ++ return result; ++} ++ ++/* ++* Initialize RAR parameters, such as bus addresses, etc. ++*/ ++static int init_rar_params(struct pci_dev *pdev) ++{ ++ unsigned int i; ++ int result = 0; ++ ++ /* Retrieve RAR start and end bus addresses. ++ * Access the RAR registers through the Lincroft Message Bus ++ * Interface on PCI device: 00:00.0 Host bridge. ++ */ ++ ++ for (i = 0; i < MRST_NUM_RAR; ++i) { ++ struct RAR_offsets const *offset = ++ &my_rar_device.rar_offsets[i]; ++ struct RAR_address_range *addr = &my_rar_device.rar_addr[i]; ++ ++ if ((retrieve_rar_addr(pdev, offset->low, &addr->low) != 0) ++ || (retrieve_rar_addr(pdev, offset->high, &addr->high) != 0)) { ++ result = -1; ++ break; ++ } ++ ++ /* ++ * Only the upper 22 bits of the RAR addresses are ++ * stored in their corresponding RAR registers so we ++ * must set the lower 10 bits accordingly. ++ ++ * The low address has its lower 10 bits cleared, and ++ * the high address has all its lower 10 bits set, ++ * e.g.: ++ * low = 0x2ffffc00 ++ */ ++ ++ addr->low &= (dma_addr_t)0xfffffc00u; ++ ++ /* ++ * Set bits 9:0 on uppser address if bits 31:10 are non ++ * zero; otherwize clear all bits ++ */ ++ ++ if ((addr->high & 0xfffffc00u) == 0) ++ addr->high = 0; ++ else ++ addr->high |= 0x3ffu; ++ } ++ /* Done accessing the device. */ ++ ++ if (result == 0) { ++ int z; ++ for (z = 0; z != MRST_NUM_RAR; ++z) { ++ /* ++ * "BRAR" refers to the RAR registers in the ++ * Lincroft B-unit. ++ */ ++ dev_info(&pdev->dev, "BRAR[%u] bus address range = " ++ "[%lx, %lx]\n", z, ++ (unsigned long)my_rar_device.rar_addr[z].low, ++ (unsigned long)my_rar_device.rar_addr[z].high); ++ } ++ } ++ ++ return result; + } + + /* ++ * The rar_get_address function is used by other device drivers ++ * to obtain RAR address information on a RAR. It takes three ++ * parameters: ++ * ++ * int rar_index ++ * The rar_index is an index to the rar for which you wish to retrieve ++ * the address information. ++ * Values can be 0,1, or 2. ++ * ++ * The function returns a 0 upon success or a -1 if there is no RAR ++ * facility on this system. ++ */ ++int rar_get_address(int rar_index, ++ dma_addr_t *start_address, ++ dma_addr_t *end_address) ++{ ++ int result = -ENODEV; ++ ++ if (my_rar_device.registered) { ++ if (start_address == 0 || end_address == 0 ++ || rar_index >= MRST_NUM_RAR || rar_index < 0) { ++ result = -EINVAL; ++ } else { ++ *start_address = ++ my_rar_device.rar_addr[rar_index].low; ++ *end_address = ++ my_rar_device.rar_addr[rar_index].high; + +- * Initialize RAR parameters, such as physical addresses, etc. ++ result = 0; ++ } ++ } + ++ return result; ++} ++EXPORT_SYMBOL(rar_get_address); ++ ++/* ++ * The rar_lock function is ued by other device drivers to lock an RAR. ++ * once an RAR is locked, it stays locked until the next system reboot. ++ * The function takes one parameter: ++ * ++ * int rar_index ++ * The rar_index is an index to the rar that you want to lock. ++ * Values can be 0,1, or 2. ++ * ++ * The function returns a 0 upon success or a -1 if there is no RAR ++ * facility on this system. + */ +-static int memrar_init_rar_params(struct pci_dev *pdev) ++int rar_lock(int rar_index) + { +- struct RAR_offsets const offsets[] = { +- { LNC_BRAR0L, LNC_BRAR0H }, +- { LNC_BRAR1L, LNC_BRAR1H }, +- { LNC_BRAR2L, LNC_BRAR2H } +- }; ++ int result = -ENODEV; + +- size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]); +- struct RAR_offsets const *end = offsets + num_offsets; +- struct RAR_offsets const *i; +- unsigned int n = 0; +- int result = 0; ++ if (rar_index >= MRST_NUM_RAR || rar_index < 0) { ++ result = -EINVAL; ++ return result; ++ } + +- /* Retrieve RAR start and end physical addresses. */ ++ dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex locking\n"); ++ mutex_lock(&rar_mutex); + +- /* +- * Access the RAR registers through the Lincroft Message Bus +- * Interface on PCI device: 00:00.0 Host bridge. +- */ +- +- /* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */ +- +- if (pdev == NULL) +- return -ENODEV; +- +- for (i = offsets; i != end; ++i, ++n) { +- if (memrar_get_rar_addr(pdev, +- (*i).low, +- &(rar_addr[n].low)) != 0 +- || memrar_get_rar_addr(pdev, +- (*i).high, +- &(rar_addr[n].high)) != 0) { +- result = -1; +- break; ++ if (my_rar_device.registered) { ++ ++ dma_addr_t low = my_rar_device.rar_addr[rar_index].low & ++ 0xfffffc00u; ++ ++ dma_addr_t high = my_rar_device.rar_addr[rar_index].high & ++ 0xfffffc00u; ++ ++ /* ++ * Only allow I/O from the graphics and Langwell; ++ * Not from the x96 processor ++ */ ++ if (rar_index == (int)RAR_TYPE_VIDEO) { ++ low |= 0x00000009; ++ high |= 0x00000015; + } ++ ++ else if (rar_index == (int)RAR_TYPE_AUDIO) { ++ /* Only allow I/O from Langwell; nothing from x86 */ ++ low |= 0x00000008; ++ high |= 0x00000018; ++ } ++ ++ else ++ /* Read-only from all agents */ ++ high |= 0x00000018; ++ ++ /* ++ * Now program the register using the Lincroft message ++ * bus interface. ++ */ ++ result = set_rar_address(my_rar_device.rar_dev, ++ my_rar_device.rar_offsets[rar_index].low, ++ low); ++ ++ if (result == 0) ++ result = set_rar_address( ++ my_rar_device.rar_dev, ++ my_rar_device.rar_offsets[rar_index].high, ++ high); + } + +- /* Done accessing the device. */ +- /* pci_dev_put(pdev); */ ++ dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex unlocking\n"); ++ mutex_unlock(&rar_mutex); ++ return result; ++} ++EXPORT_SYMBOL(rar_lock); + +- if (result == 0) { +- if (1) { +- size_t z; +- for (z = 0; z != MRST_NUM_RAR; ++z) { +- printk(KERN_WARNING +- "rar - BRAR[%Zd] physical address low\n" +- "\tlow: 0x%08x\n" +- "\thigh: 0x%08x\n", +- z, +- rar_addr[z].low, +- rar_addr[z].high); +- } +- } ++/* The register_rar function is to used by other device drivers ++ * to ensure that this driver is ready. As we cannot be sure of ++ * the compile/execute order of dirvers in ther kernel, it is ++ * best to give this driver a callback function to call when ++ * it is ready to give out addresses. The callback function ++ * would have those steps that continue the initialization of ++ * a driver that do require a valid RAR address. One of those ++ * steps would be to call rar_get_address() ++ * This function return 0 on success an -1 on failure. ++*/ ++int register_rar(int (*callback)(void *yourparameter), void *yourparameter) ++{ ++ ++ int result = -ENODEV; ++ ++ if (callback == NULL) ++ return -EINVAL; ++ ++ mutex_lock(&rar_mutex); ++ ++ if (my_rar_device.registered) { ++ ++ mutex_unlock(&rar_mutex); ++ /* ++ * if the driver already registered, then we can simply ++ * call the callback right now ++ */ ++ ++ return (*callback)(yourparameter); + } + ++ if (num_clients < MRST_NUM_RAR) { ++ ++ clients[num_clients].client_callback = callback; ++ clients[num_clients].customer_data = yourparameter; ++ num_clients += 1; ++ result = 0; ++ } ++ ++ mutex_unlock(&rar_mutex); + return result; ++ + } ++EXPORT_SYMBOL(register_rar); + + /* +- function that is activated on the successfull probe of the RAR device +-*/ +-static int __devinit rar_probe(struct pci_dev *pdev, +- const struct pci_device_id *ent) ++ * This function registers the driver with the device subsystem ( ++ * either PCI, USB, etc). ++ * Function that is activaed on the succesful probe of the RAR device ++ * (Moorestown host controller). ++ */ ++static int rar_probe(struct pci_dev *dev, const struct pci_device_id *id) + { +- /* error */ + int error; ++ int counter; + +- /*------------------------ +- CODE +- ---------------------------*/ +- +- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, +- "Rar pci probe starting\n"); +- error = 0; ++ dev_dbg(&dev->dev, "PCI probe starting\n"); + + /* enable the device */ +- error = pci_enable_device(pdev); ++ error = pci_enable_device(dev); + if (error) { +- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, +- "error enabling pci device\n"); ++ dev_err(&dev->dev, ++ "Error enabling RAR register PCI device\n"); + goto end_function; + } + +- rar_dev = pdev; +- registered = 1; +- +- /* Initialize the RAR parameters, which have to be retrieved */ +- /* via the message bus service */ +- error = memrar_init_rar_params(rar_dev); ++ /* we have only one device; fill in the rar_device structure */ ++ my_rar_device.rar_dev = dev; + ++ /* ++ * Initialize the RAR parameters, which have to be retrieved ++ * via the message bus interface. ++ */ ++ error = init_rar_params(dev); + if (error) { +- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, +- "error getting RAR addresses device\n"); +- registered = 0; ++ pci_disable_device(dev); ++ ++ dev_err(&dev->dev, ++ "Error retrieving RAR addresses\n"); ++ + goto end_function; ++ } ++ ++ dev_dbg(&dev->dev, "PCI probe locking\n"); ++ mutex_lock(&rar_mutex); ++ my_rar_device.registered = 1; ++ ++ /* now call anyone who has registered (using callbacks) */ ++ for (counter = 0; counter < num_clients; counter += 1) { ++ if (clients[counter].client_callback) { ++ error = (*clients[counter].client_callback)( ++ clients[counter].customer_data); ++ /* set callback to NULL to indicate it has been done */ ++ clients[counter].client_callback = NULL; ++ dev_dbg(&my_rar_device.rar_dev->dev, ++ "Callback called for %d\n", ++ counter); + } ++ } ++ ++ dev_dbg(&dev->dev, "PCI probe unlocking\n"); ++ mutex_unlock(&rar_mutex); + + end_function: + + return error; + } + +-/* +- this function registers the driver to +- the device subsystem (either PCI, USB, etc) +-*/ ++const struct pci_device_id rar_pci_id_tbl[] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_RAR_DEVICE_ID) }, ++ { 0 } ++}; ++ ++MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl); ++ ++const struct pci_device_id *my_id_table = rar_pci_id_tbl; ++ ++/* field for registering driver to PCI device */ ++static struct pci_driver rar_pci_driver = { ++ .name = "rar_register_driver", ++ .id_table = rar_pci_id_tbl, ++ .probe = rar_probe ++}; ++ + static int __init rar_init_handler(void) + { + return pci_register_driver(&rar_pci_driver); +@@ -382,59 +599,4 @@ module_init(rar_init_handler); + module_exit(rar_exit_handler); + + MODULE_LICENSE("GPL"); +- +- +-/* The get_rar_address function is used by other device drivers +- * to obtain RAR address information on a RAR. It takes two +- * parameter: +- * +- * int rar_index +- * The rar_index is an index to the rar for which you wish to retrieve +- * the address information. +- * Values can be 0,1, or 2. +- * +- * struct RAR_address_struct is a pointer to a place to which the function +- * can return the address structure for the RAR. +- * +- * The function returns a 0 upon success or a -1 if there is no RAR +- * facility on this system. +- */ +-int get_rar_address(int rar_index, struct RAR_address_struct *addresses) +-{ +- if (registered && (rar_index < 3) && (rar_index >= 0)) { +- *addresses = rar_addr[rar_index]; +- /* strip off lock bit information */ +- addresses->low = addresses->low & 0xfffffff0; +- addresses->high = addresses->high & 0xfffffff0; +- return 0; +- } else +- return -ENODEV; +-} +-EXPORT_SYMBOL(get_rar_address); +- +-/* The lock_rar function is used by other device drivers to lock an RAR. +- * once an RAR is locked, it stays locked until the next system reboot. +- * The function takes one parameter: +- * +- * int rar_index +- * The rar_index is an index to the rar that you want to lock. +- * Values can be 0,1, or 2. +- * +- * The function returns a 0 upon success or a -1 if there is no RAR +- * facility on this system. +- */ +-int lock_rar(int rar_index) +-{ +- u32 working_addr; +- int result; +- +- if (registered && (rar_index < 3) && (rar_index >= 0)) { +- /* first make sure that lock bits are clear (this does lock) */ +- working_addr = rar_addr[rar_index].low & 0xfffffff0; +- +- /* now send that value to the register using the IPC */ +- result = memrar_set_rar_addr(rar_dev, rar_index, working_addr); +- return result; +- } else +- return -ENODEV; +-} ++MODULE_DESCRIPTION("Intel Restricted Access Region Register Driver"); diff --git a/staging/staging-rar_register-provide-better-explanation-in-kconfig.patch b/staging/staging-rar_register-provide-better-explanation-in-kconfig.patch new file mode 100644 index 00000000000000..68e756c4a27ea4 --- /dev/null +++ b/staging/staging-rar_register-provide-better-explanation-in-kconfig.patch @@ -0,0 +1,39 @@ +From mark.a.allyn@intel.com Wed Feb 17 14:47:31 2010 +From: Mark Allyn <mark.a.allyn@intel.com> +Date: Fri, 5 Feb 2010 10:52:46 -0800 +Subject: Staging: rar_register: provide better explanation in Kconfig +To: linux-kernel@vger.kernel.org, alan@linux.intel.com, charles.f.johnson@intel.com, greg@kroah.com +Cc: Mark Allyn <mark.a.allyn@intel.com> +Message-ID: <1265395966-16001-1-git-send-email-mark.a.allyn@intel.com> + + +Provides a better explanation of what this +driver is for in the Kconfig file + +Signed-off-by: Mark Allyn <mark.a.allyn@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/rar_register/Kconfig | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/staging/rar_register/Kconfig ++++ b/drivers/staging/rar_register/Kconfig +@@ -14,4 +14,17 @@ config RAR_REGISTER + contents of the restricted access region control + registers. + ++ The restricted access region control registers ++ (rar_registers) are used to pass address and ++ locking information on restricted access regions ++ to other drivers that use restricted access regions ++ ++ The restricted access regions are regions of memory ++ on the Intel MID Platform that are not accessible to ++ the x86 processor, but are accessible to dedicated ++ processors on board peripheral devices. ++ ++ The purpose of the restricted access regions is to ++ protect sensitive data from compromise by unauthorized ++ programs running on the x86 processor. + endmenu diff --git a/staging/staging-rar_register-renaming-directory-to-rar_register.patch b/staging/staging-rar_register-renaming-directory-to-rar_register.patch new file mode 100644 index 00000000000000..6b21319472e698 --- /dev/null +++ b/staging/staging-rar_register-renaming-directory-to-rar_register.patch @@ -0,0 +1,1170 @@ +From mark.a.allyn@intel.com Wed Feb 17 14:41:38 2010 +From: Mark Allyn <mark.a.allyn@intel.com> +Date: Fri, 5 Feb 2010 10:52:26 -0800 +Subject: Staging: rar_register: renaming directory to rar_register +To: linux-kernel@vger.kernel.org, alan@linux.intel.com, charles.f.johnson@intel.com, greg@kroah.com +Cc: Mark Allyn <mark.a.allyn@intel.com> +Message-ID: <1265395946-15973-1-git-send-email-mark.a.allyn@intel.com> + + +Renames the directory in which the driver files +are located; again for clarity. + +Signed-off-by: Mark Allyn <mark.a.allyn@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 2 + drivers/staging/rar/Kconfig | 17 - + drivers/staging/rar/Makefile | 2 + drivers/staging/rar/rar_register.c | 440 ---------------------------- + drivers/staging/rar/rar_register.h | 89 ----- + drivers/staging/rar_register/Kconfig | 17 + + drivers/staging/rar_register/Makefile | 2 + drivers/staging/rar_register/rar_register.c | 440 ++++++++++++++++++++++++++++ + drivers/staging/rar_register/rar_register.h | 89 +++++ + 10 files changed, 550 insertions(+), 550 deletions(-) + +--- a/drivers/staging/Kconfig ++++ b/drivers/staging/Kconfig +@@ -109,7 +109,7 @@ source "drivers/staging/hv/Kconfig" + + source "drivers/staging/vme/Kconfig" + +-source "drivers/staging/rar/Kconfig" ++source "drivers/staging/rar_register/Kconfig" + + source "drivers/staging/sep/Kconfig" + +--- a/drivers/staging/Makefile ++++ b/drivers/staging/Makefile +@@ -35,7 +35,7 @@ obj-$(CONFIG_VT6656) += vt6656/ + obj-$(CONFIG_FB_UDL) += udlfb/ + obj-$(CONFIG_HYPERV) += hv/ + obj-$(CONFIG_VME_BUS) += vme/ +-obj-$(CONFIG_RAR_REGISTER) += rar/ ++obj-$(CONFIG_RAR_REGISTER) += rar_register/ + obj-$(CONFIG_DX_SEP) += sep/ + obj-$(CONFIG_IIO) += iio/ + obj-$(CONFIG_RAMZSWAP) += ramzswap/ +--- a/drivers/staging/rar/Kconfig ++++ /dev/null +@@ -1,17 +0,0 @@ +-# +-# RAR device configuration +-# +- +-menu "RAR Register Driver" +-# +-# Restricted Access Register Manager +-# +-config RAR_REGISTER +- tristate "Restricted Access Region Register Driver" +- default n +- ---help--- +- This driver allows other kernel drivers access to the +- contents of the restricted access region control +- registers. +- +-endmenu +--- a/drivers/staging/rar/Makefile ++++ /dev/null +@@ -1,2 +0,0 @@ +-EXTRA_CFLAGS += -DLITTLE__ENDIAN +-obj-$(CONFIG_RAR_REGISTER) += rar_register.o +--- a/drivers/staging/rar/rar_register.c ++++ /dev/null +@@ -1,440 +0,0 @@ +-#include <linux/init.h> +-#include <linux/module.h> +-#include <linux/fs.h> +-#include <linux/cdev.h> +-#include <linux/kdev_t.h> +-#include <linux/semaphore.h> +-#include <linux/mm.h> +-#include <linux/poll.h> +-#include <linux/wait.h> +-#include <linux/ioctl.h> +-#include <linux/ioport.h> +-#include <linux/io.h> +-#include <linux/interrupt.h> +-#include <linux/pagemap.h> +-#include <linux/pci.h> +-#include <linux/firmware.h> +-#include <linux/sched.h> +-#include "rar_register.h" +- +-/* The following defines are for the IPC process to retrieve RAR in */ +- +-/* === Lincroft Message Bus Interface === */ +-/* Message Control Register */ +-#define LNC_MCR_OFFSET 0xD0 +- +-/* Message Data Register */ +-#define LNC_MDR_OFFSET 0xD4 +- +-/* Message Opcodes */ +-#define LNC_MESSAGE_READ_OPCODE 0xD0 +-#define LNC_MESSAGE_WRITE_OPCODE 0xE0 +- +-/* Message Write Byte Enables */ +-#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF +- +-/* B-unit Port */ +-#define LNC_BUNIT_PORT 0x3 +- +-/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */ +-#define LNC_BRAR0L 0x10 +-#define LNC_BRAR0H 0x11 +-#define LNC_BRAR1L 0x12 +-#define LNC_BRAR1H 0x13 +- +-/* Reserved for SeP */ +-#define LNC_BRAR2L 0x14 +-#define LNC_BRAR2H 0x15 +- +- +-/* This structure is only used during module initialization. */ +-struct RAR_offsets { +- int low; /* Register offset for low RAR physical address. */ +- int high; /* Register offset for high RAR physical address. */ +-}; +- +-struct pci_dev *rar_dev; +-static uint32_t registered; +- +-/* Moorestown supports three restricted access regions. */ +-#define MRST_NUM_RAR 3 +- +-struct RAR_address_struct rar_addr[MRST_NUM_RAR]; +- +-/* prototype for init */ +-static int __init rar_init_handler(void); +-static void __exit rar_exit_handler(void); +- +-/* +- function that is activated on the successfull probe of the RAR device +-*/ +-static int __devinit rar_probe(struct pci_dev *pdev, +- const struct pci_device_id *ent); +- +-static const struct pci_device_id rar_pci_id_tbl[] = { +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4110) }, +- { 0 } +-}; +- +-MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl); +- +-/* field for registering driver to PCI device */ +-static struct pci_driver rar_pci_driver = { +- .name = "rar_driver", +- .id_table = rar_pci_id_tbl, +- .probe = rar_probe +-}; +- +-/* This function is used to retrieved RAR info using the IPC message +- bus interface */ +-static int memrar_get_rar_addr(struct pci_dev *pdev, +- int offset, +- u32 *addr) +-{ +- /* +- * ======== The Lincroft Message Bus Interface ======== +- * Lincroft registers may be obtained from the PCI +- * (the Host Bridge) using the Lincroft Message Bus +- * Interface. That message bus interface is generally +- * comprised of two registers: a control register (MCR, 0xDO) +- * and a data register (MDR, 0xD4). +- * +- * The MCR (message control register) format is the following: +- * 1. [31:24]: Opcode +- * 2. [23:16]: Port +- * 3. [15:8]: Register Offset +- * 4. [7:4]: Byte Enables (use 0xF to set all of these bits +- * to 1) +- * 5. [3:0]: reserved +- * +- * Read (0xD0) and write (0xE0) opcodes are written to the +- * control register when reading and writing to Lincroft +- * registers, respectively. +- * +- * We're interested in registers found in the Lincroft +- * B-unit. The B-unit port is 0x3. +- * +- * The six B-unit RAR register offsets we use are listed +- * earlier in this file. +- * +- * Lastly writing to the MCR register requires the "Byte +- * enables" bits to be set to 1. This may be achieved by +- * writing 0xF at bit 4. +- * +- * The MDR (message data register) format is the following: +- * 1. [31:0]: Read/Write Data +- * +- * Data being read from this register is only available after +- * writing the appropriate control message to the MCR +- * register. +- * +- * Data being written to this register must be written before +- * writing the appropriate control message to the MCR +- * register. +- */ +- +- int result = 0; /* result */ +- /* Construct control message */ +- u32 const message = +- (LNC_MESSAGE_READ_OPCODE << 24) +- | (LNC_BUNIT_PORT << 16) +- | (offset << 8) +- | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); +- +- printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset); +- +- if (addr == 0) +- return -EINVAL; +- +- /* Send the control message */ +- result = pci_write_config_dword(pdev, +- LNC_MCR_OFFSET, +- message); +- +- printk(KERN_WARNING "rar- result from send ctl register is %x\n", +- result); +- +- if (!result) +- result = pci_read_config_dword(pdev, +- LNC_MDR_OFFSET, +- addr); +- +- printk(KERN_WARNING "rar- result from read data register is %x\n", +- result); +- +- printk(KERN_WARNING "rar- value read from data register is %x\n", +- *addr); +- +- if (result) +- return -1; +- else +- return 0; +-} +- +-static int memrar_set_rar_addr(struct pci_dev *pdev, +- int offset, +- u32 addr) +-{ +- /* +- * ======== The Lincroft Message Bus Interface ======== +- * Lincroft registers may be obtained from the PCI +- * (the Host Bridge) using the Lincroft Message Bus +- * Interface. That message bus interface is generally +- * comprised of two registers: a control register (MCR, 0xDO) +- * and a data register (MDR, 0xD4). +- * +- * The MCR (message control register) format is the following: +- * 1. [31:24]: Opcode +- * 2. [23:16]: Port +- * 3. [15:8]: Register Offset +- * 4. [7:4]: Byte Enables (use 0xF to set all of these bits +- * to 1) +- * 5. [3:0]: reserved +- * +- * Read (0xD0) and write (0xE0) opcodes are written to the +- * control register when reading and writing to Lincroft +- * registers, respectively. +- * +- * We're interested in registers found in the Lincroft +- * B-unit. The B-unit port is 0x3. +- * +- * The six B-unit RAR register offsets we use are listed +- * earlier in this file. +- * +- * Lastly writing to the MCR register requires the "Byte +- * enables" bits to be set to 1. This may be achieved by +- * writing 0xF at bit 4. +- * +- * The MDR (message data register) format is the following: +- * 1. [31:0]: Read/Write Data +- * +- * Data being read from this register is only available after +- * writing the appropriate control message to the MCR +- * register. +- * +- * Data being written to this register must be written before +- * writing the appropriate control message to the MCR +- * register. +- */ +- +- int result = 0; /* result */ +- +- /* Construct control message */ +- u32 const message = +- (LNC_MESSAGE_WRITE_OPCODE << 24) +- | (LNC_BUNIT_PORT << 16) +- | (offset << 8) +- | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); +- +- printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset); +- +- if (addr == 0) +- return -EINVAL; +- +- /* Send the control message */ +- result = pci_write_config_dword(pdev, +- LNC_MDR_OFFSET, +- addr); +- +- printk(KERN_WARNING "rar- result from send ctl register is %x\n", +- result); +- +- if (!result) +- result = pci_write_config_dword(pdev, +- LNC_MCR_OFFSET, +- message); +- +- printk(KERN_WARNING "rar- result from write data register is %x\n", +- result); +- +- printk(KERN_WARNING "rar- value read to data register is %x\n", +- addr); +- +- if (result) +- return -1; +- else +- return 0; +-} +- +-/* +- +- * Initialize RAR parameters, such as physical addresses, etc. +- +- */ +-static int memrar_init_rar_params(struct pci_dev *pdev) +-{ +- struct RAR_offsets const offsets[] = { +- { LNC_BRAR0L, LNC_BRAR0H }, +- { LNC_BRAR1L, LNC_BRAR1H }, +- { LNC_BRAR2L, LNC_BRAR2H } +- }; +- +- size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]); +- struct RAR_offsets const *end = offsets + num_offsets; +- struct RAR_offsets const *i; +- unsigned int n = 0; +- int result = 0; +- +- /* Retrieve RAR start and end physical addresses. */ +- +- /* +- * Access the RAR registers through the Lincroft Message Bus +- * Interface on PCI device: 00:00.0 Host bridge. +- */ +- +- /* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */ +- +- if (pdev == NULL) +- return -ENODEV; +- +- for (i = offsets; i != end; ++i, ++n) { +- if (memrar_get_rar_addr(pdev, +- (*i).low, +- &(rar_addr[n].low)) != 0 +- || memrar_get_rar_addr(pdev, +- (*i).high, +- &(rar_addr[n].high)) != 0) { +- result = -1; +- break; +- } +- } +- +- /* Done accessing the device. */ +- /* pci_dev_put(pdev); */ +- +- if (result == 0) { +- if (1) { +- size_t z; +- for (z = 0; z != MRST_NUM_RAR; ++z) { +- printk(KERN_WARNING +- "rar - BRAR[%Zd] physical address low\n" +- "\tlow: 0x%08x\n" +- "\thigh: 0x%08x\n", +- z, +- rar_addr[z].low, +- rar_addr[z].high); +- } +- } +- } +- +- return result; +-} +- +-/* +- function that is activated on the successfull probe of the RAR device +-*/ +-static int __devinit rar_probe(struct pci_dev *pdev, +- const struct pci_device_id *ent) +-{ +- /* error */ +- int error; +- +- /*------------------------ +- CODE +- ---------------------------*/ +- +- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, +- "Rar pci probe starting\n"); +- error = 0; +- +- /* enable the device */ +- error = pci_enable_device(pdev); +- if (error) { +- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, +- "error enabling pci device\n"); +- goto end_function; +- } +- +- rar_dev = pdev; +- registered = 1; +- +- /* Initialize the RAR parameters, which have to be retrieved */ +- /* via the message bus service */ +- error = memrar_init_rar_params(rar_dev); +- +- if (error) { +- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, +- "error getting RAR addresses device\n"); +- registered = 0; +- goto end_function; +- } +- +-end_function: +- +- return error; +-} +- +-/* +- this function registers the driver to +- the device subsystem (either PCI, USB, etc) +-*/ +-static int __init rar_init_handler(void) +-{ +- return pci_register_driver(&rar_pci_driver); +-} +- +-static void __exit rar_exit_handler(void) +-{ +- pci_unregister_driver(&rar_pci_driver); +-} +- +-module_init(rar_init_handler); +-module_exit(rar_exit_handler); +- +-MODULE_LICENSE("GPL"); +- +- +-/* The get_rar_address function is used by other device drivers +- * to obtain RAR address information on a RAR. It takes two +- * parameter: +- * +- * int rar_index +- * The rar_index is an index to the rar for which you wish to retrieve +- * the address information. +- * Values can be 0,1, or 2. +- * +- * struct RAR_address_struct is a pointer to a place to which the function +- * can return the address structure for the RAR. +- * +- * The function returns a 0 upon success or a -1 if there is no RAR +- * facility on this system. +- */ +-int get_rar_address(int rar_index, struct RAR_address_struct *addresses) +-{ +- if (registered && (rar_index < 3) && (rar_index >= 0)) { +- *addresses = rar_addr[rar_index]; +- /* strip off lock bit information */ +- addresses->low = addresses->low & 0xfffffff0; +- addresses->high = addresses->high & 0xfffffff0; +- return 0; +- } else +- return -ENODEV; +-} +-EXPORT_SYMBOL(get_rar_address); +- +-/* The lock_rar function is used by other device drivers to lock an RAR. +- * once an RAR is locked, it stays locked until the next system reboot. +- * The function takes one parameter: +- * +- * int rar_index +- * The rar_index is an index to the rar that you want to lock. +- * Values can be 0,1, or 2. +- * +- * The function returns a 0 upon success or a -1 if there is no RAR +- * facility on this system. +- */ +-int lock_rar(int rar_index) +-{ +- u32 working_addr; +- int result; +- +- if (registered && (rar_index < 3) && (rar_index >= 0)) { +- /* first make sure that lock bits are clear (this does lock) */ +- working_addr = rar_addr[rar_index].low & 0xfffffff0; +- +- /* now send that value to the register using the IPC */ +- result = memrar_set_rar_addr(rar_dev, rar_index, working_addr); +- return result; +- } else +- return -ENODEV; +-} +--- a/drivers/staging/rar/rar_register.h ++++ /dev/null +@@ -1,89 +0,0 @@ +-/* === RAR Physical Addresses === */ +-struct RAR_address_struct { +- u32 low; +- u32 high; +-}; +- +-/* The get_rar_address function is used by other device drivers +- * to obtain RAR address information on a RAR. It takes two +- * parameter: +- * +- * int rar_index +- * The rar_index is an index to the rar for which you wish to retrieve +- * the address information. +- * Values can be 0,1, or 2. +- * +- * struct RAR_address_struct is a pointer to a place to which the function +- * can return the address structure for the RAR. +- * +- * The function returns a 0 upon success or a -1 if there is no RAR +- * facility on this system. +- */ +-int get_rar_address(int rar_index, struct RAR_address_struct *addresses); +- +- +-/* The lock_rar function is used by other device drivers to lock an RAR. +- * once an RAR is locked, it stays locked until the next system reboot. +- * The function takes one parameter: +- * +- * int rar_index +- * The rar_index is an index to the rar that you want to lock. +- * Values can be 0,1, or 2. +- * +- * The function returns a 0 upon success or a -1 if there is no RAR +- * facility on this system. +- */ +-int lock_rar(int rar_index); +- +- +-/* DEBUG LEVEL MASKS */ +-#define RAR_DEBUG_LEVEL_BASIC 0x1 +- +-#define RAR_DEBUG_LEVEL_REGISTERS 0x2 +- +-#define RAR_DEBUG_LEVEL_EXTENDED 0x4 +- +-#define DEBUG_LEVEL 0x7 +- +-/* FUNCTIONAL MACROS */ +- +-/* debug macro without paramaters */ +-#define DEBUG_PRINT_0(DEBUG_LEVEL , info) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info); \ +- } \ +-} while (0) +- +-/* debug macro with 1 paramater */ +-#define DEBUG_PRINT_1(DEBUG_LEVEL , info , param1) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info , param1); \ +- } \ +-} while (0) +- +-/* debug macro with 2 paramaters */ +-#define DEBUG_PRINT_2(DEBUG_LEVEL , info , param1, param2) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info , param1, param2); \ +- } \ +-} while (0) +- +-/* debug macro with 3 paramaters */ +-#define DEBUG_PRINT_3(DEBUG_LEVEL , info , param1, param2 , param3) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info , param1, param2 , param3); \ +- } \ +-} while (0) +- +-/* debug macro with 4 paramaters */ +-#define DEBUG_PRINT_4(DEBUG_LEVEL , info , param1, param2 , param3 , param4) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info , param1, param2 , param3 , param4); \ +- } \ +-} while (0) +- +--- /dev/null ++++ b/drivers/staging/rar_register/Kconfig +@@ -0,0 +1,17 @@ ++# ++# RAR device configuration ++# ++ ++menu "RAR Register Driver" ++# ++# Restricted Access Register Manager ++# ++config RAR_REGISTER ++ tristate "Restricted Access Region Register Driver" ++ default n ++ ---help--- ++ This driver allows other kernel drivers access to the ++ contents of the restricted access region control ++ registers. ++ ++endmenu +--- /dev/null ++++ b/drivers/staging/rar_register/Makefile +@@ -0,0 +1,2 @@ ++EXTRA_CFLAGS += -DLITTLE__ENDIAN ++obj-$(CONFIG_RAR_REGISTER) += rar_register.o +--- /dev/null ++++ b/drivers/staging/rar_register/rar_register.c +@@ -0,0 +1,440 @@ ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/fs.h> ++#include <linux/cdev.h> ++#include <linux/kdev_t.h> ++#include <linux/semaphore.h> ++#include <linux/mm.h> ++#include <linux/poll.h> ++#include <linux/wait.h> ++#include <linux/ioctl.h> ++#include <linux/ioport.h> ++#include <linux/io.h> ++#include <linux/interrupt.h> ++#include <linux/pagemap.h> ++#include <linux/pci.h> ++#include <linux/firmware.h> ++#include <linux/sched.h> ++#include "rar_register.h" ++ ++/* The following defines are for the IPC process to retrieve RAR in */ ++ ++/* === Lincroft Message Bus Interface === */ ++/* Message Control Register */ ++#define LNC_MCR_OFFSET 0xD0 ++ ++/* Message Data Register */ ++#define LNC_MDR_OFFSET 0xD4 ++ ++/* Message Opcodes */ ++#define LNC_MESSAGE_READ_OPCODE 0xD0 ++#define LNC_MESSAGE_WRITE_OPCODE 0xE0 ++ ++/* Message Write Byte Enables */ ++#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF ++ ++/* B-unit Port */ ++#define LNC_BUNIT_PORT 0x3 ++ ++/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */ ++#define LNC_BRAR0L 0x10 ++#define LNC_BRAR0H 0x11 ++#define LNC_BRAR1L 0x12 ++#define LNC_BRAR1H 0x13 ++ ++/* Reserved for SeP */ ++#define LNC_BRAR2L 0x14 ++#define LNC_BRAR2H 0x15 ++ ++ ++/* This structure is only used during module initialization. */ ++struct RAR_offsets { ++ int low; /* Register offset for low RAR physical address. */ ++ int high; /* Register offset for high RAR physical address. */ ++}; ++ ++struct pci_dev *rar_dev; ++static uint32_t registered; ++ ++/* Moorestown supports three restricted access regions. */ ++#define MRST_NUM_RAR 3 ++ ++struct RAR_address_struct rar_addr[MRST_NUM_RAR]; ++ ++/* prototype for init */ ++static int __init rar_init_handler(void); ++static void __exit rar_exit_handler(void); ++ ++/* ++ function that is activated on the successfull probe of the RAR device ++*/ ++static int __devinit rar_probe(struct pci_dev *pdev, ++ const struct pci_device_id *ent); ++ ++static const struct pci_device_id rar_pci_id_tbl[] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4110) }, ++ { 0 } ++}; ++ ++MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl); ++ ++/* field for registering driver to PCI device */ ++static struct pci_driver rar_pci_driver = { ++ .name = "rar_driver", ++ .id_table = rar_pci_id_tbl, ++ .probe = rar_probe ++}; ++ ++/* This function is used to retrieved RAR info using the IPC message ++ bus interface */ ++static int memrar_get_rar_addr(struct pci_dev *pdev, ++ int offset, ++ u32 *addr) ++{ ++ /* ++ * ======== The Lincroft Message Bus Interface ======== ++ * Lincroft registers may be obtained from the PCI ++ * (the Host Bridge) using the Lincroft Message Bus ++ * Interface. That message bus interface is generally ++ * comprised of two registers: a control register (MCR, 0xDO) ++ * and a data register (MDR, 0xD4). ++ * ++ * The MCR (message control register) format is the following: ++ * 1. [31:24]: Opcode ++ * 2. [23:16]: Port ++ * 3. [15:8]: Register Offset ++ * 4. [7:4]: Byte Enables (use 0xF to set all of these bits ++ * to 1) ++ * 5. [3:0]: reserved ++ * ++ * Read (0xD0) and write (0xE0) opcodes are written to the ++ * control register when reading and writing to Lincroft ++ * registers, respectively. ++ * ++ * We're interested in registers found in the Lincroft ++ * B-unit. The B-unit port is 0x3. ++ * ++ * The six B-unit RAR register offsets we use are listed ++ * earlier in this file. ++ * ++ * Lastly writing to the MCR register requires the "Byte ++ * enables" bits to be set to 1. This may be achieved by ++ * writing 0xF at bit 4. ++ * ++ * The MDR (message data register) format is the following: ++ * 1. [31:0]: Read/Write Data ++ * ++ * Data being read from this register is only available after ++ * writing the appropriate control message to the MCR ++ * register. ++ * ++ * Data being written to this register must be written before ++ * writing the appropriate control message to the MCR ++ * register. ++ */ ++ ++ int result = 0; /* result */ ++ /* Construct control message */ ++ u32 const message = ++ (LNC_MESSAGE_READ_OPCODE << 24) ++ | (LNC_BUNIT_PORT << 16) ++ | (offset << 8) ++ | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); ++ ++ printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset); ++ ++ if (addr == 0) ++ return -EINVAL; ++ ++ /* Send the control message */ ++ result = pci_write_config_dword(pdev, ++ LNC_MCR_OFFSET, ++ message); ++ ++ printk(KERN_WARNING "rar- result from send ctl register is %x\n", ++ result); ++ ++ if (!result) ++ result = pci_read_config_dword(pdev, ++ LNC_MDR_OFFSET, ++ addr); ++ ++ printk(KERN_WARNING "rar- result from read data register is %x\n", ++ result); ++ ++ printk(KERN_WARNING "rar- value read from data register is %x\n", ++ *addr); ++ ++ if (result) ++ return -1; ++ else ++ return 0; ++} ++ ++static int memrar_set_rar_addr(struct pci_dev *pdev, ++ int offset, ++ u32 addr) ++{ ++ /* ++ * ======== The Lincroft Message Bus Interface ======== ++ * Lincroft registers may be obtained from the PCI ++ * (the Host Bridge) using the Lincroft Message Bus ++ * Interface. That message bus interface is generally ++ * comprised of two registers: a control register (MCR, 0xDO) ++ * and a data register (MDR, 0xD4). ++ * ++ * The MCR (message control register) format is the following: ++ * 1. [31:24]: Opcode ++ * 2. [23:16]: Port ++ * 3. [15:8]: Register Offset ++ * 4. [7:4]: Byte Enables (use 0xF to set all of these bits ++ * to 1) ++ * 5. [3:0]: reserved ++ * ++ * Read (0xD0) and write (0xE0) opcodes are written to the ++ * control register when reading and writing to Lincroft ++ * registers, respectively. ++ * ++ * We're interested in registers found in the Lincroft ++ * B-unit. The B-unit port is 0x3. ++ * ++ * The six B-unit RAR register offsets we use are listed ++ * earlier in this file. ++ * ++ * Lastly writing to the MCR register requires the "Byte ++ * enables" bits to be set to 1. This may be achieved by ++ * writing 0xF at bit 4. ++ * ++ * The MDR (message data register) format is the following: ++ * 1. [31:0]: Read/Write Data ++ * ++ * Data being read from this register is only available after ++ * writing the appropriate control message to the MCR ++ * register. ++ * ++ * Data being written to this register must be written before ++ * writing the appropriate control message to the MCR ++ * register. ++ */ ++ ++ int result = 0; /* result */ ++ ++ /* Construct control message */ ++ u32 const message = ++ (LNC_MESSAGE_WRITE_OPCODE << 24) ++ | (LNC_BUNIT_PORT << 16) ++ | (offset << 8) ++ | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); ++ ++ printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset); ++ ++ if (addr == 0) ++ return -EINVAL; ++ ++ /* Send the control message */ ++ result = pci_write_config_dword(pdev, ++ LNC_MDR_OFFSET, ++ addr); ++ ++ printk(KERN_WARNING "rar- result from send ctl register is %x\n", ++ result); ++ ++ if (!result) ++ result = pci_write_config_dword(pdev, ++ LNC_MCR_OFFSET, ++ message); ++ ++ printk(KERN_WARNING "rar- result from write data register is %x\n", ++ result); ++ ++ printk(KERN_WARNING "rar- value read to data register is %x\n", ++ addr); ++ ++ if (result) ++ return -1; ++ else ++ return 0; ++} ++ ++/* ++ ++ * Initialize RAR parameters, such as physical addresses, etc. ++ ++ */ ++static int memrar_init_rar_params(struct pci_dev *pdev) ++{ ++ struct RAR_offsets const offsets[] = { ++ { LNC_BRAR0L, LNC_BRAR0H }, ++ { LNC_BRAR1L, LNC_BRAR1H }, ++ { LNC_BRAR2L, LNC_BRAR2H } ++ }; ++ ++ size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]); ++ struct RAR_offsets const *end = offsets + num_offsets; ++ struct RAR_offsets const *i; ++ unsigned int n = 0; ++ int result = 0; ++ ++ /* Retrieve RAR start and end physical addresses. */ ++ ++ /* ++ * Access the RAR registers through the Lincroft Message Bus ++ * Interface on PCI device: 00:00.0 Host bridge. ++ */ ++ ++ /* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */ ++ ++ if (pdev == NULL) ++ return -ENODEV; ++ ++ for (i = offsets; i != end; ++i, ++n) { ++ if (memrar_get_rar_addr(pdev, ++ (*i).low, ++ &(rar_addr[n].low)) != 0 ++ || memrar_get_rar_addr(pdev, ++ (*i).high, ++ &(rar_addr[n].high)) != 0) { ++ result = -1; ++ break; ++ } ++ } ++ ++ /* Done accessing the device. */ ++ /* pci_dev_put(pdev); */ ++ ++ if (result == 0) { ++ if (1) { ++ size_t z; ++ for (z = 0; z != MRST_NUM_RAR; ++z) { ++ printk(KERN_WARNING ++ "rar - BRAR[%Zd] physical address low\n" ++ "\tlow: 0x%08x\n" ++ "\thigh: 0x%08x\n", ++ z, ++ rar_addr[z].low, ++ rar_addr[z].high); ++ } ++ } ++ } ++ ++ return result; ++} ++ ++/* ++ function that is activated on the successfull probe of the RAR device ++*/ ++static int __devinit rar_probe(struct pci_dev *pdev, ++ const struct pci_device_id *ent) ++{ ++ /* error */ ++ int error; ++ ++ /*------------------------ ++ CODE ++ ---------------------------*/ ++ ++ DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, ++ "Rar pci probe starting\n"); ++ error = 0; ++ ++ /* enable the device */ ++ error = pci_enable_device(pdev); ++ if (error) { ++ DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, ++ "error enabling pci device\n"); ++ goto end_function; ++ } ++ ++ rar_dev = pdev; ++ registered = 1; ++ ++ /* Initialize the RAR parameters, which have to be retrieved */ ++ /* via the message bus service */ ++ error = memrar_init_rar_params(rar_dev); ++ ++ if (error) { ++ DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, ++ "error getting RAR addresses device\n"); ++ registered = 0; ++ goto end_function; ++ } ++ ++end_function: ++ ++ return error; ++} ++ ++/* ++ this function registers the driver to ++ the device subsystem (either PCI, USB, etc) ++*/ ++static int __init rar_init_handler(void) ++{ ++ return pci_register_driver(&rar_pci_driver); ++} ++ ++static void __exit rar_exit_handler(void) ++{ ++ pci_unregister_driver(&rar_pci_driver); ++} ++ ++module_init(rar_init_handler); ++module_exit(rar_exit_handler); ++ ++MODULE_LICENSE("GPL"); ++ ++ ++/* The get_rar_address function is used by other device drivers ++ * to obtain RAR address information on a RAR. It takes two ++ * parameter: ++ * ++ * int rar_index ++ * The rar_index is an index to the rar for which you wish to retrieve ++ * the address information. ++ * Values can be 0,1, or 2. ++ * ++ * struct RAR_address_struct is a pointer to a place to which the function ++ * can return the address structure for the RAR. ++ * ++ * The function returns a 0 upon success or a -1 if there is no RAR ++ * facility on this system. ++ */ ++int get_rar_address(int rar_index, struct RAR_address_struct *addresses) ++{ ++ if (registered && (rar_index < 3) && (rar_index >= 0)) { ++ *addresses = rar_addr[rar_index]; ++ /* strip off lock bit information */ ++ addresses->low = addresses->low & 0xfffffff0; ++ addresses->high = addresses->high & 0xfffffff0; ++ return 0; ++ } else ++ return -ENODEV; ++} ++EXPORT_SYMBOL(get_rar_address); ++ ++/* The lock_rar function is used by other device drivers to lock an RAR. ++ * once an RAR is locked, it stays locked until the next system reboot. ++ * The function takes one parameter: ++ * ++ * int rar_index ++ * The rar_index is an index to the rar that you want to lock. ++ * Values can be 0,1, or 2. ++ * ++ * The function returns a 0 upon success or a -1 if there is no RAR ++ * facility on this system. ++ */ ++int lock_rar(int rar_index) ++{ ++ u32 working_addr; ++ int result; ++ ++ if (registered && (rar_index < 3) && (rar_index >= 0)) { ++ /* first make sure that lock bits are clear (this does lock) */ ++ working_addr = rar_addr[rar_index].low & 0xfffffff0; ++ ++ /* now send that value to the register using the IPC */ ++ result = memrar_set_rar_addr(rar_dev, rar_index, working_addr); ++ return result; ++ } else ++ return -ENODEV; ++} +--- /dev/null ++++ b/drivers/staging/rar_register/rar_register.h +@@ -0,0 +1,89 @@ ++/* === RAR Physical Addresses === */ ++struct RAR_address_struct { ++ u32 low; ++ u32 high; ++}; ++ ++/* The get_rar_address function is used by other device drivers ++ * to obtain RAR address information on a RAR. It takes two ++ * parameter: ++ * ++ * int rar_index ++ * The rar_index is an index to the rar for which you wish to retrieve ++ * the address information. ++ * Values can be 0,1, or 2. ++ * ++ * struct RAR_address_struct is a pointer to a place to which the function ++ * can return the address structure for the RAR. ++ * ++ * The function returns a 0 upon success or a -1 if there is no RAR ++ * facility on this system. ++ */ ++int get_rar_address(int rar_index, struct RAR_address_struct *addresses); ++ ++ ++/* The lock_rar function is used by other device drivers to lock an RAR. ++ * once an RAR is locked, it stays locked until the next system reboot. ++ * The function takes one parameter: ++ * ++ * int rar_index ++ * The rar_index is an index to the rar that you want to lock. ++ * Values can be 0,1, or 2. ++ * ++ * The function returns a 0 upon success or a -1 if there is no RAR ++ * facility on this system. ++ */ ++int lock_rar(int rar_index); ++ ++ ++/* DEBUG LEVEL MASKS */ ++#define RAR_DEBUG_LEVEL_BASIC 0x1 ++ ++#define RAR_DEBUG_LEVEL_REGISTERS 0x2 ++ ++#define RAR_DEBUG_LEVEL_EXTENDED 0x4 ++ ++#define DEBUG_LEVEL 0x7 ++ ++/* FUNCTIONAL MACROS */ ++ ++/* debug macro without paramaters */ ++#define DEBUG_PRINT_0(DEBUG_LEVEL , info) \ ++do { \ ++ if (DEBUG_LEVEL) { \ ++ printk(KERN_WARNING info); \ ++ } \ ++} while (0) ++ ++/* debug macro with 1 paramater */ ++#define DEBUG_PRINT_1(DEBUG_LEVEL , info , param1) \ ++do { \ ++ if (DEBUG_LEVEL) { \ ++ printk(KERN_WARNING info , param1); \ ++ } \ ++} while (0) ++ ++/* debug macro with 2 paramaters */ ++#define DEBUG_PRINT_2(DEBUG_LEVEL , info , param1, param2) \ ++do { \ ++ if (DEBUG_LEVEL) { \ ++ printk(KERN_WARNING info , param1, param2); \ ++ } \ ++} while (0) ++ ++/* debug macro with 3 paramaters */ ++#define DEBUG_PRINT_3(DEBUG_LEVEL , info , param1, param2 , param3) \ ++do { \ ++ if (DEBUG_LEVEL) { \ ++ printk(KERN_WARNING info , param1, param2 , param3); \ ++ } \ ++} while (0) ++ ++/* debug macro with 4 paramaters */ ++#define DEBUG_PRINT_4(DEBUG_LEVEL , info , param1, param2 , param3 , param4) \ ++do { \ ++ if (DEBUG_LEVEL) { \ ++ printk(KERN_WARNING info , param1, param2 , param3 , param4); \ ++ } \ ++} while (0) ++ diff --git a/staging/staging-rar_register-renaming-driver-to-rar_register.patch b/staging/staging-rar_register-renaming-driver-to-rar_register.patch new file mode 100644 index 00000000000000..85d17380d35ec6 --- /dev/null +++ b/staging/staging-rar_register-renaming-driver-to-rar_register.patch @@ -0,0 +1,1099 @@ +From mark.a.allyn@intel.com Wed Feb 17 14:41:04 2010 +From: Mark Allyn <mark.a.allyn@intel.com> +Date: Fri, 5 Feb 2010 10:52:09 -0800 +Subject: staging: rar_register: renaming driver to rar_register +To: linux-kernel@vger.kernel.org, alan@linux.intel.com, charles.f.johnson@intel.com, greg@kroah.com +Cc: Mark Allyn <mark.a.allyn@intel.com> +Message-ID: <1265395929-15946-1-git-send-email-mark.a.allyn@intel.com> + + +Patch renames rar_driver to rar_register to clarifiy and differentiate +from rar_handler that will be submitted later + +Signed-off-by: Mark Allyn <mark.a.allyn@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/staging/rar/Makefile | 2 + drivers/staging/rar/rar_driver.c | 440 ------------------------------------- + drivers/staging/rar/rar_driver.h | 89 ------- + drivers/staging/rar/rar_register.c | 440 +++++++++++++++++++++++++++++++++++++ + drivers/staging/rar/rar_register.h | 89 +++++++ + 5 files changed, 530 insertions(+), 530 deletions(-) + +--- a/drivers/staging/rar/Makefile ++++ b/drivers/staging/rar/Makefile +@@ -1,2 +1,2 @@ + EXTRA_CFLAGS += -DLITTLE__ENDIAN +-obj-$(CONFIG_RAR_REGISTER) += rar_driver.o ++obj-$(CONFIG_RAR_REGISTER) += rar_register.o +--- a/drivers/staging/rar/rar_driver.c ++++ /dev/null +@@ -1,440 +0,0 @@ +-#include <linux/init.h> +-#include <linux/module.h> +-#include <linux/fs.h> +-#include <linux/cdev.h> +-#include <linux/kdev_t.h> +-#include <linux/semaphore.h> +-#include <linux/mm.h> +-#include <linux/poll.h> +-#include <linux/wait.h> +-#include <linux/ioctl.h> +-#include <linux/ioport.h> +-#include <linux/io.h> +-#include <linux/interrupt.h> +-#include <linux/pagemap.h> +-#include <linux/pci.h> +-#include <linux/firmware.h> +-#include <linux/sched.h> +-#include "rar_driver.h" +- +-/* The following defines are for the IPC process to retrieve RAR in */ +- +-/* === Lincroft Message Bus Interface === */ +-/* Message Control Register */ +-#define LNC_MCR_OFFSET 0xD0 +- +-/* Message Data Register */ +-#define LNC_MDR_OFFSET 0xD4 +- +-/* Message Opcodes */ +-#define LNC_MESSAGE_READ_OPCODE 0xD0 +-#define LNC_MESSAGE_WRITE_OPCODE 0xE0 +- +-/* Message Write Byte Enables */ +-#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF +- +-/* B-unit Port */ +-#define LNC_BUNIT_PORT 0x3 +- +-/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */ +-#define LNC_BRAR0L 0x10 +-#define LNC_BRAR0H 0x11 +-#define LNC_BRAR1L 0x12 +-#define LNC_BRAR1H 0x13 +- +-/* Reserved for SeP */ +-#define LNC_BRAR2L 0x14 +-#define LNC_BRAR2H 0x15 +- +- +-/* This structure is only used during module initialization. */ +-struct RAR_offsets { +- int low; /* Register offset for low RAR physical address. */ +- int high; /* Register offset for high RAR physical address. */ +-}; +- +-struct pci_dev *rar_dev; +-static uint32_t registered; +- +-/* Moorestown supports three restricted access regions. */ +-#define MRST_NUM_RAR 3 +- +-struct RAR_address_struct rar_addr[MRST_NUM_RAR]; +- +-/* prototype for init */ +-static int __init rar_init_handler(void); +-static void __exit rar_exit_handler(void); +- +-/* +- function that is activated on the successfull probe of the RAR device +-*/ +-static int __devinit rar_probe(struct pci_dev *pdev, +- const struct pci_device_id *ent); +- +-static const struct pci_device_id rar_pci_id_tbl[] = { +- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4110) }, +- { 0 } +-}; +- +-MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl); +- +-/* field for registering driver to PCI device */ +-static struct pci_driver rar_pci_driver = { +- .name = "rar_driver", +- .id_table = rar_pci_id_tbl, +- .probe = rar_probe +-}; +- +-/* This function is used to retrieved RAR info using the IPC message +- bus interface */ +-static int memrar_get_rar_addr(struct pci_dev *pdev, +- int offset, +- u32 *addr) +-{ +- /* +- * ======== The Lincroft Message Bus Interface ======== +- * Lincroft registers may be obtained from the PCI +- * (the Host Bridge) using the Lincroft Message Bus +- * Interface. That message bus interface is generally +- * comprised of two registers: a control register (MCR, 0xDO) +- * and a data register (MDR, 0xD4). +- * +- * The MCR (message control register) format is the following: +- * 1. [31:24]: Opcode +- * 2. [23:16]: Port +- * 3. [15:8]: Register Offset +- * 4. [7:4]: Byte Enables (use 0xF to set all of these bits +- * to 1) +- * 5. [3:0]: reserved +- * +- * Read (0xD0) and write (0xE0) opcodes are written to the +- * control register when reading and writing to Lincroft +- * registers, respectively. +- * +- * We're interested in registers found in the Lincroft +- * B-unit. The B-unit port is 0x3. +- * +- * The six B-unit RAR register offsets we use are listed +- * earlier in this file. +- * +- * Lastly writing to the MCR register requires the "Byte +- * enables" bits to be set to 1. This may be achieved by +- * writing 0xF at bit 4. +- * +- * The MDR (message data register) format is the following: +- * 1. [31:0]: Read/Write Data +- * +- * Data being read from this register is only available after +- * writing the appropriate control message to the MCR +- * register. +- * +- * Data being written to this register must be written before +- * writing the appropriate control message to the MCR +- * register. +- */ +- +- int result = 0; /* result */ +- /* Construct control message */ +- u32 const message = +- (LNC_MESSAGE_READ_OPCODE << 24) +- | (LNC_BUNIT_PORT << 16) +- | (offset << 8) +- | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); +- +- printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset); +- +- if (addr == 0) +- return -EINVAL; +- +- /* Send the control message */ +- result = pci_write_config_dword(pdev, +- LNC_MCR_OFFSET, +- message); +- +- printk(KERN_WARNING "rar- result from send ctl register is %x\n", +- result); +- +- if (!result) +- result = pci_read_config_dword(pdev, +- LNC_MDR_OFFSET, +- addr); +- +- printk(KERN_WARNING "rar- result from read data register is %x\n", +- result); +- +- printk(KERN_WARNING "rar- value read from data register is %x\n", +- *addr); +- +- if (result) +- return -1; +- else +- return 0; +-} +- +-static int memrar_set_rar_addr(struct pci_dev *pdev, +- int offset, +- u32 addr) +-{ +- /* +- * ======== The Lincroft Message Bus Interface ======== +- * Lincroft registers may be obtained from the PCI +- * (the Host Bridge) using the Lincroft Message Bus +- * Interface. That message bus interface is generally +- * comprised of two registers: a control register (MCR, 0xDO) +- * and a data register (MDR, 0xD4). +- * +- * The MCR (message control register) format is the following: +- * 1. [31:24]: Opcode +- * 2. [23:16]: Port +- * 3. [15:8]: Register Offset +- * 4. [7:4]: Byte Enables (use 0xF to set all of these bits +- * to 1) +- * 5. [3:0]: reserved +- * +- * Read (0xD0) and write (0xE0) opcodes are written to the +- * control register when reading and writing to Lincroft +- * registers, respectively. +- * +- * We're interested in registers found in the Lincroft +- * B-unit. The B-unit port is 0x3. +- * +- * The six B-unit RAR register offsets we use are listed +- * earlier in this file. +- * +- * Lastly writing to the MCR register requires the "Byte +- * enables" bits to be set to 1. This may be achieved by +- * writing 0xF at bit 4. +- * +- * The MDR (message data register) format is the following: +- * 1. [31:0]: Read/Write Data +- * +- * Data being read from this register is only available after +- * writing the appropriate control message to the MCR +- * register. +- * +- * Data being written to this register must be written before +- * writing the appropriate control message to the MCR +- * register. +- */ +- +- int result = 0; /* result */ +- +- /* Construct control message */ +- u32 const message = +- (LNC_MESSAGE_WRITE_OPCODE << 24) +- | (LNC_BUNIT_PORT << 16) +- | (offset << 8) +- | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); +- +- printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset); +- +- if (addr == 0) +- return -EINVAL; +- +- /* Send the control message */ +- result = pci_write_config_dword(pdev, +- LNC_MDR_OFFSET, +- addr); +- +- printk(KERN_WARNING "rar- result from send ctl register is %x\n", +- result); +- +- if (!result) +- result = pci_write_config_dword(pdev, +- LNC_MCR_OFFSET, +- message); +- +- printk(KERN_WARNING "rar- result from write data register is %x\n", +- result); +- +- printk(KERN_WARNING "rar- value read to data register is %x\n", +- addr); +- +- if (result) +- return -1; +- else +- return 0; +-} +- +-/* +- +- * Initialize RAR parameters, such as physical addresses, etc. +- +- */ +-static int memrar_init_rar_params(struct pci_dev *pdev) +-{ +- struct RAR_offsets const offsets[] = { +- { LNC_BRAR0L, LNC_BRAR0H }, +- { LNC_BRAR1L, LNC_BRAR1H }, +- { LNC_BRAR2L, LNC_BRAR2H } +- }; +- +- size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]); +- struct RAR_offsets const *end = offsets + num_offsets; +- struct RAR_offsets const *i; +- unsigned int n = 0; +- int result = 0; +- +- /* Retrieve RAR start and end physical addresses. */ +- +- /* +- * Access the RAR registers through the Lincroft Message Bus +- * Interface on PCI device: 00:00.0 Host bridge. +- */ +- +- /* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */ +- +- if (pdev == NULL) +- return -ENODEV; +- +- for (i = offsets; i != end; ++i, ++n) { +- if (memrar_get_rar_addr(pdev, +- (*i).low, +- &(rar_addr[n].low)) != 0 +- || memrar_get_rar_addr(pdev, +- (*i).high, +- &(rar_addr[n].high)) != 0) { +- result = -1; +- break; +- } +- } +- +- /* Done accessing the device. */ +- /* pci_dev_put(pdev); */ +- +- if (result == 0) { +- if (1) { +- size_t z; +- for (z = 0; z != MRST_NUM_RAR; ++z) { +- printk(KERN_WARNING +- "rar - BRAR[%Zd] physical address low\n" +- "\tlow: 0x%08x\n" +- "\thigh: 0x%08x\n", +- z, +- rar_addr[z].low, +- rar_addr[z].high); +- } +- } +- } +- +- return result; +-} +- +-/* +- function that is activated on the successfull probe of the RAR device +-*/ +-static int __devinit rar_probe(struct pci_dev *pdev, +- const struct pci_device_id *ent) +-{ +- /* error */ +- int error; +- +- /*------------------------ +- CODE +- ---------------------------*/ +- +- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, +- "Rar pci probe starting\n"); +- error = 0; +- +- /* enable the device */ +- error = pci_enable_device(pdev); +- if (error) { +- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, +- "error enabling pci device\n"); +- goto end_function; +- } +- +- rar_dev = pdev; +- registered = 1; +- +- /* Initialize the RAR parameters, which have to be retrieved */ +- /* via the message bus service */ +- error = memrar_init_rar_params(rar_dev); +- +- if (error) { +- DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, +- "error getting RAR addresses device\n"); +- registered = 0; +- goto end_function; +- } +- +-end_function: +- +- return error; +-} +- +-/* +- this function registers the driver to +- the device subsystem (either PCI, USB, etc) +-*/ +-static int __init rar_init_handler(void) +-{ +- return pci_register_driver(&rar_pci_driver); +-} +- +-static void __exit rar_exit_handler(void) +-{ +- pci_unregister_driver(&rar_pci_driver); +-} +- +-module_init(rar_init_handler); +-module_exit(rar_exit_handler); +- +-MODULE_LICENSE("GPL"); +- +- +-/* The get_rar_address function is used by other device drivers +- * to obtain RAR address information on a RAR. It takes two +- * parameter: +- * +- * int rar_index +- * The rar_index is an index to the rar for which you wish to retrieve +- * the address information. +- * Values can be 0,1, or 2. +- * +- * struct RAR_address_struct is a pointer to a place to which the function +- * can return the address structure for the RAR. +- * +- * The function returns a 0 upon success or a -1 if there is no RAR +- * facility on this system. +- */ +-int get_rar_address(int rar_index, struct RAR_address_struct *addresses) +-{ +- if (registered && (rar_index < 3) && (rar_index >= 0)) { +- *addresses = rar_addr[rar_index]; +- /* strip off lock bit information */ +- addresses->low = addresses->low & 0xfffffff0; +- addresses->high = addresses->high & 0xfffffff0; +- return 0; +- } else +- return -ENODEV; +-} +-EXPORT_SYMBOL(get_rar_address); +- +-/* The lock_rar function is used by other device drivers to lock an RAR. +- * once an RAR is locked, it stays locked until the next system reboot. +- * The function takes one parameter: +- * +- * int rar_index +- * The rar_index is an index to the rar that you want to lock. +- * Values can be 0,1, or 2. +- * +- * The function returns a 0 upon success or a -1 if there is no RAR +- * facility on this system. +- */ +-int lock_rar(int rar_index) +-{ +- u32 working_addr; +- int result; +- +- if (registered && (rar_index < 3) && (rar_index >= 0)) { +- /* first make sure that lock bits are clear (this does lock) */ +- working_addr = rar_addr[rar_index].low & 0xfffffff0; +- +- /* now send that value to the register using the IPC */ +- result = memrar_set_rar_addr(rar_dev, rar_index, working_addr); +- return result; +- } else +- return -ENODEV; +-} +--- a/drivers/staging/rar/rar_driver.h ++++ /dev/null +@@ -1,89 +0,0 @@ +-/* === RAR Physical Addresses === */ +-struct RAR_address_struct { +- u32 low; +- u32 high; +-}; +- +-/* The get_rar_address function is used by other device drivers +- * to obtain RAR address information on a RAR. It takes two +- * parameter: +- * +- * int rar_index +- * The rar_index is an index to the rar for which you wish to retrieve +- * the address information. +- * Values can be 0,1, or 2. +- * +- * struct RAR_address_struct is a pointer to a place to which the function +- * can return the address structure for the RAR. +- * +- * The function returns a 0 upon success or a -1 if there is no RAR +- * facility on this system. +- */ +-int get_rar_address(int rar_index, struct RAR_address_struct *addresses); +- +- +-/* The lock_rar function is used by other device drivers to lock an RAR. +- * once an RAR is locked, it stays locked until the next system reboot. +- * The function takes one parameter: +- * +- * int rar_index +- * The rar_index is an index to the rar that you want to lock. +- * Values can be 0,1, or 2. +- * +- * The function returns a 0 upon success or a -1 if there is no RAR +- * facility on this system. +- */ +-int lock_rar(int rar_index); +- +- +-/* DEBUG LEVEL MASKS */ +-#define RAR_DEBUG_LEVEL_BASIC 0x1 +- +-#define RAR_DEBUG_LEVEL_REGISTERS 0x2 +- +-#define RAR_DEBUG_LEVEL_EXTENDED 0x4 +- +-#define DEBUG_LEVEL 0x7 +- +-/* FUNCTIONAL MACROS */ +- +-/* debug macro without paramaters */ +-#define DEBUG_PRINT_0(DEBUG_LEVEL , info) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info); \ +- } \ +-} while (0) +- +-/* debug macro with 1 paramater */ +-#define DEBUG_PRINT_1(DEBUG_LEVEL , info , param1) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info , param1); \ +- } \ +-} while (0) +- +-/* debug macro with 2 paramaters */ +-#define DEBUG_PRINT_2(DEBUG_LEVEL , info , param1, param2) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info , param1, param2); \ +- } \ +-} while (0) +- +-/* debug macro with 3 paramaters */ +-#define DEBUG_PRINT_3(DEBUG_LEVEL , info , param1, param2 , param3) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info , param1, param2 , param3); \ +- } \ +-} while (0) +- +-/* debug macro with 4 paramaters */ +-#define DEBUG_PRINT_4(DEBUG_LEVEL , info , param1, param2 , param3 , param4) \ +-do { \ +- if (DEBUG_LEVEL) { \ +- printk(KERN_WARNING info , param1, param2 , param3 , param4); \ +- } \ +-} while (0) +- +--- /dev/null ++++ b/drivers/staging/rar/rar_register.c +@@ -0,0 +1,440 @@ ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/fs.h> ++#include <linux/cdev.h> ++#include <linux/kdev_t.h> ++#include <linux/semaphore.h> ++#include <linux/mm.h> ++#include <linux/poll.h> ++#include <linux/wait.h> ++#include <linux/ioctl.h> ++#include <linux/ioport.h> ++#include <linux/io.h> ++#include <linux/interrupt.h> ++#include <linux/pagemap.h> ++#include <linux/pci.h> ++#include <linux/firmware.h> ++#include <linux/sched.h> ++#include "rar_register.h" ++ ++/* The following defines are for the IPC process to retrieve RAR in */ ++ ++/* === Lincroft Message Bus Interface === */ ++/* Message Control Register */ ++#define LNC_MCR_OFFSET 0xD0 ++ ++/* Message Data Register */ ++#define LNC_MDR_OFFSET 0xD4 ++ ++/* Message Opcodes */ ++#define LNC_MESSAGE_READ_OPCODE 0xD0 ++#define LNC_MESSAGE_WRITE_OPCODE 0xE0 ++ ++/* Message Write Byte Enables */ ++#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF ++ ++/* B-unit Port */ ++#define LNC_BUNIT_PORT 0x3 ++ ++/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */ ++#define LNC_BRAR0L 0x10 ++#define LNC_BRAR0H 0x11 ++#define LNC_BRAR1L 0x12 ++#define LNC_BRAR1H 0x13 ++ ++/* Reserved for SeP */ ++#define LNC_BRAR2L 0x14 ++#define LNC_BRAR2H 0x15 ++ ++ ++/* This structure is only used during module initialization. */ ++struct RAR_offsets { ++ int low; /* Register offset for low RAR physical address. */ ++ int high; /* Register offset for high RAR physical address. */ ++}; ++ ++struct pci_dev *rar_dev; ++static uint32_t registered; ++ ++/* Moorestown supports three restricted access regions. */ ++#define MRST_NUM_RAR 3 ++ ++struct RAR_address_struct rar_addr[MRST_NUM_RAR]; ++ ++/* prototype for init */ ++static int __init rar_init_handler(void); ++static void __exit rar_exit_handler(void); ++ ++/* ++ function that is activated on the successfull probe of the RAR device ++*/ ++static int __devinit rar_probe(struct pci_dev *pdev, ++ const struct pci_device_id *ent); ++ ++static const struct pci_device_id rar_pci_id_tbl[] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4110) }, ++ { 0 } ++}; ++ ++MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl); ++ ++/* field for registering driver to PCI device */ ++static struct pci_driver rar_pci_driver = { ++ .name = "rar_driver", ++ .id_table = rar_pci_id_tbl, ++ .probe = rar_probe ++}; ++ ++/* This function is used to retrieved RAR info using the IPC message ++ bus interface */ ++static int memrar_get_rar_addr(struct pci_dev *pdev, ++ int offset, ++ u32 *addr) ++{ ++ /* ++ * ======== The Lincroft Message Bus Interface ======== ++ * Lincroft registers may be obtained from the PCI ++ * (the Host Bridge) using the Lincroft Message Bus ++ * Interface. That message bus interface is generally ++ * comprised of two registers: a control register (MCR, 0xDO) ++ * and a data register (MDR, 0xD4). ++ * ++ * The MCR (message control register) format is the following: ++ * 1. [31:24]: Opcode ++ * 2. [23:16]: Port ++ * 3. [15:8]: Register Offset ++ * 4. [7:4]: Byte Enables (use 0xF to set all of these bits ++ * to 1) ++ * 5. [3:0]: reserved ++ * ++ * Read (0xD0) and write (0xE0) opcodes are written to the ++ * control register when reading and writing to Lincroft ++ * registers, respectively. ++ * ++ * We're interested in registers found in the Lincroft ++ * B-unit. The B-unit port is 0x3. ++ * ++ * The six B-unit RAR register offsets we use are listed ++ * earlier in this file. ++ * ++ * Lastly writing to the MCR register requires the "Byte ++ * enables" bits to be set to 1. This may be achieved by ++ * writing 0xF at bit 4. ++ * ++ * The MDR (message data register) format is the following: ++ * 1. [31:0]: Read/Write Data ++ * ++ * Data being read from this register is only available after ++ * writing the appropriate control message to the MCR ++ * register. ++ * ++ * Data being written to this register must be written before ++ * writing the appropriate control message to the MCR ++ * register. ++ */ ++ ++ int result = 0; /* result */ ++ /* Construct control message */ ++ u32 const message = ++ (LNC_MESSAGE_READ_OPCODE << 24) ++ | (LNC_BUNIT_PORT << 16) ++ | (offset << 8) ++ | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); ++ ++ printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset); ++ ++ if (addr == 0) ++ return -EINVAL; ++ ++ /* Send the control message */ ++ result = pci_write_config_dword(pdev, ++ LNC_MCR_OFFSET, ++ message); ++ ++ printk(KERN_WARNING "rar- result from send ctl register is %x\n", ++ result); ++ ++ if (!result) ++ result = pci_read_config_dword(pdev, ++ LNC_MDR_OFFSET, ++ addr); ++ ++ printk(KERN_WARNING "rar- result from read data register is %x\n", ++ result); ++ ++ printk(KERN_WARNING "rar- value read from data register is %x\n", ++ *addr); ++ ++ if (result) ++ return -1; ++ else ++ return 0; ++} ++ ++static int memrar_set_rar_addr(struct pci_dev *pdev, ++ int offset, ++ u32 addr) ++{ ++ /* ++ * ======== The Lincroft Message Bus Interface ======== ++ * Lincroft registers may be obtained from the PCI ++ * (the Host Bridge) using the Lincroft Message Bus ++ * Interface. That message bus interface is generally ++ * comprised of two registers: a control register (MCR, 0xDO) ++ * and a data register (MDR, 0xD4). ++ * ++ * The MCR (message control register) format is the following: ++ * 1. [31:24]: Opcode ++ * 2. [23:16]: Port ++ * 3. [15:8]: Register Offset ++ * 4. [7:4]: Byte Enables (use 0xF to set all of these bits ++ * to 1) ++ * 5. [3:0]: reserved ++ * ++ * Read (0xD0) and write (0xE0) opcodes are written to the ++ * control register when reading and writing to Lincroft ++ * registers, respectively. ++ * ++ * We're interested in registers found in the Lincroft ++ * B-unit. The B-unit port is 0x3. ++ * ++ * The six B-unit RAR register offsets we use are listed ++ * earlier in this file. ++ * ++ * Lastly writing to the MCR register requires the "Byte ++ * enables" bits to be set to 1. This may be achieved by ++ * writing 0xF at bit 4. ++ * ++ * The MDR (message data register) format is the following: ++ * 1. [31:0]: Read/Write Data ++ * ++ * Data being read from this register is only available after ++ * writing the appropriate control message to the MCR ++ * register. ++ * ++ * Data being written to this register must be written before ++ * writing the appropriate control message to the MCR ++ * register. ++ */ ++ ++ int result = 0; /* result */ ++ ++ /* Construct control message */ ++ u32 const message = ++ (LNC_MESSAGE_WRITE_OPCODE << 24) ++ | (LNC_BUNIT_PORT << 16) ++ | (offset << 8) ++ | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); ++ ++ printk(KERN_WARNING "rar- offset to LNC MSG is %x\n", offset); ++ ++ if (addr == 0) ++ return -EINVAL; ++ ++ /* Send the control message */ ++ result = pci_write_config_dword(pdev, ++ LNC_MDR_OFFSET, ++ addr); ++ ++ printk(KERN_WARNING "rar- result from send ctl register is %x\n", ++ result); ++ ++ if (!result) ++ result = pci_write_config_dword(pdev, ++ LNC_MCR_OFFSET, ++ message); ++ ++ printk(KERN_WARNING "rar- result from write data register is %x\n", ++ result); ++ ++ printk(KERN_WARNING "rar- value read to data register is %x\n", ++ addr); ++ ++ if (result) ++ return -1; ++ else ++ return 0; ++} ++ ++/* ++ ++ * Initialize RAR parameters, such as physical addresses, etc. ++ ++ */ ++static int memrar_init_rar_params(struct pci_dev *pdev) ++{ ++ struct RAR_offsets const offsets[] = { ++ { LNC_BRAR0L, LNC_BRAR0H }, ++ { LNC_BRAR1L, LNC_BRAR1H }, ++ { LNC_BRAR2L, LNC_BRAR2H } ++ }; ++ ++ size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]); ++ struct RAR_offsets const *end = offsets + num_offsets; ++ struct RAR_offsets const *i; ++ unsigned int n = 0; ++ int result = 0; ++ ++ /* Retrieve RAR start and end physical addresses. */ ++ ++ /* ++ * Access the RAR registers through the Lincroft Message Bus ++ * Interface on PCI device: 00:00.0 Host bridge. ++ */ ++ ++ /* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */ ++ ++ if (pdev == NULL) ++ return -ENODEV; ++ ++ for (i = offsets; i != end; ++i, ++n) { ++ if (memrar_get_rar_addr(pdev, ++ (*i).low, ++ &(rar_addr[n].low)) != 0 ++ || memrar_get_rar_addr(pdev, ++ (*i).high, ++ &(rar_addr[n].high)) != 0) { ++ result = -1; ++ break; ++ } ++ } ++ ++ /* Done accessing the device. */ ++ /* pci_dev_put(pdev); */ ++ ++ if (result == 0) { ++ if (1) { ++ size_t z; ++ for (z = 0; z != MRST_NUM_RAR; ++z) { ++ printk(KERN_WARNING ++ "rar - BRAR[%Zd] physical address low\n" ++ "\tlow: 0x%08x\n" ++ "\thigh: 0x%08x\n", ++ z, ++ rar_addr[z].low, ++ rar_addr[z].high); ++ } ++ } ++ } ++ ++ return result; ++} ++ ++/* ++ function that is activated on the successfull probe of the RAR device ++*/ ++static int __devinit rar_probe(struct pci_dev *pdev, ++ const struct pci_device_id *ent) ++{ ++ /* error */ ++ int error; ++ ++ /*------------------------ ++ CODE ++ ---------------------------*/ ++ ++ DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, ++ "Rar pci probe starting\n"); ++ error = 0; ++ ++ /* enable the device */ ++ error = pci_enable_device(pdev); ++ if (error) { ++ DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, ++ "error enabling pci device\n"); ++ goto end_function; ++ } ++ ++ rar_dev = pdev; ++ registered = 1; ++ ++ /* Initialize the RAR parameters, which have to be retrieved */ ++ /* via the message bus service */ ++ error = memrar_init_rar_params(rar_dev); ++ ++ if (error) { ++ DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED, ++ "error getting RAR addresses device\n"); ++ registered = 0; ++ goto end_function; ++ } ++ ++end_function: ++ ++ return error; ++} ++ ++/* ++ this function registers the driver to ++ the device subsystem (either PCI, USB, etc) ++*/ ++static int __init rar_init_handler(void) ++{ ++ return pci_register_driver(&rar_pci_driver); ++} ++ ++static void __exit rar_exit_handler(void) ++{ ++ pci_unregister_driver(&rar_pci_driver); ++} ++ ++module_init(rar_init_handler); ++module_exit(rar_exit_handler); ++ ++MODULE_LICENSE("GPL"); ++ ++ ++/* The get_rar_address function is used by other device drivers ++ * to obtain RAR address information on a RAR. It takes two ++ * parameter: ++ * ++ * int rar_index ++ * The rar_index is an index to the rar for which you wish to retrieve ++ * the address information. ++ * Values can be 0,1, or 2. ++ * ++ * struct RAR_address_struct is a pointer to a place to which the function ++ * can return the address structure for the RAR. ++ * ++ * The function returns a 0 upon success or a -1 if there is no RAR ++ * facility on this system. ++ */ ++int get_rar_address(int rar_index, struct RAR_address_struct *addresses) ++{ ++ if (registered && (rar_index < 3) && (rar_index >= 0)) { ++ *addresses = rar_addr[rar_index]; ++ /* strip off lock bit information */ ++ addresses->low = addresses->low & 0xfffffff0; ++ addresses->high = addresses->high & 0xfffffff0; ++ return 0; ++ } else ++ return -ENODEV; ++} ++EXPORT_SYMBOL(get_rar_address); ++ ++/* The lock_rar function is used by other device drivers to lock an RAR. ++ * once an RAR is locked, it stays locked until the next system reboot. ++ * The function takes one parameter: ++ * ++ * int rar_index ++ * The rar_index is an index to the rar that you want to lock. ++ * Values can be 0,1, or 2. ++ * ++ * The function returns a 0 upon success or a -1 if there is no RAR ++ * facility on this system. ++ */ ++int lock_rar(int rar_index) ++{ ++ u32 working_addr; ++ int result; ++ ++ if (registered && (rar_index < 3) && (rar_index >= 0)) { ++ /* first make sure that lock bits are clear (this does lock) */ ++ working_addr = rar_addr[rar_index].low & 0xfffffff0; ++ ++ /* now send that value to the register using the IPC */ ++ result = memrar_set_rar_addr(rar_dev, rar_index, working_addr); ++ return result; ++ } else ++ return -ENODEV; ++} +--- /dev/null ++++ b/drivers/staging/rar/rar_register.h +@@ -0,0 +1,89 @@ ++/* === RAR Physical Addresses === */ ++struct RAR_address_struct { ++ u32 low; ++ u32 high; ++}; ++ ++/* The get_rar_address function is used by other device drivers ++ * to obtain RAR address information on a RAR. It takes two ++ * parameter: ++ * ++ * int rar_index ++ * The rar_index is an index to the rar for which you wish to retrieve ++ * the address information. ++ * Values can be 0,1, or 2. ++ * ++ * struct RAR_address_struct is a pointer to a place to which the function ++ * can return the address structure for the RAR. ++ * ++ * The function returns a 0 upon success or a -1 if there is no RAR ++ * facility on this system. ++ */ ++int get_rar_address(int rar_index, struct RAR_address_struct *addresses); ++ ++ ++/* The lock_rar function is used by other device drivers to lock an RAR. ++ * once an RAR is locked, it stays locked until the next system reboot. ++ * The function takes one parameter: ++ * ++ * int rar_index ++ * The rar_index is an index to the rar that you want to lock. ++ * Values can be 0,1, or 2. ++ * ++ * The function returns a 0 upon success or a -1 if there is no RAR ++ * facility on this system. ++ */ ++int lock_rar(int rar_index); ++ ++ ++/* DEBUG LEVEL MASKS */ ++#define RAR_DEBUG_LEVEL_BASIC 0x1 ++ ++#define RAR_DEBUG_LEVEL_REGISTERS 0x2 ++ ++#define RAR_DEBUG_LEVEL_EXTENDED 0x4 ++ ++#define DEBUG_LEVEL 0x7 ++ ++/* FUNCTIONAL MACROS */ ++ ++/* debug macro without paramaters */ ++#define DEBUG_PRINT_0(DEBUG_LEVEL , info) \ ++do { \ ++ if (DEBUG_LEVEL) { \ ++ printk(KERN_WARNING info); \ ++ } \ ++} while (0) ++ ++/* debug macro with 1 paramater */ ++#define DEBUG_PRINT_1(DEBUG_LEVEL , info , param1) \ ++do { \ ++ if (DEBUG_LEVEL) { \ ++ printk(KERN_WARNING info , param1); \ ++ } \ ++} while (0) ++ ++/* debug macro with 2 paramaters */ ++#define DEBUG_PRINT_2(DEBUG_LEVEL , info , param1, param2) \ ++do { \ ++ if (DEBUG_LEVEL) { \ ++ printk(KERN_WARNING info , param1, param2); \ ++ } \ ++} while (0) ++ ++/* debug macro with 3 paramaters */ ++#define DEBUG_PRINT_3(DEBUG_LEVEL , info , param1, param2 , param3) \ ++do { \ ++ if (DEBUG_LEVEL) { \ ++ printk(KERN_WARNING info , param1, param2 , param3); \ ++ } \ ++} while (0) ++ ++/* debug macro with 4 paramaters */ ++#define DEBUG_PRINT_4(DEBUG_LEVEL , info , param1, param2 , param3 , param4) \ ++do { \ ++ if (DEBUG_LEVEL) { \ ++ printk(KERN_WARNING info , param1, param2 , param3 , param4); \ ++ } \ ++} while (0) ++ diff --git a/tty/nozomi-add-tty_port-usage.patch b/tty/nozomi-add-tty_port-usage.patch new file mode 100644 index 00000000000000..19854c8ab846a0 --- /dev/null +++ b/tty/nozomi-add-tty_port-usage.patch @@ -0,0 +1,205 @@ +From alan@linux.intel.com Wed Feb 17 14:59:13 2010 +From: Alan Cox <alan@linux.intel.com> +Date: Mon, 08 Feb 2010 10:06:45 +0000 +Subject: nozomi: Add tty_port usage +To: greg@kroah.com, linux-kernel@vger.kernel.org, p.hardwick@option.com +Message-ID: <20100208100642.2794.73225.stgit@localhost.localdomain> + + +The Nozomi tty handling is very broken on the open/close side (See +http://bugzilla.kernel.org/show_bug.cgi?id=13024 for one example). In +particular it marks the tty as closed on the first close() not on the last. + +Most of the logic is pretty solid except for the open/close path so switch +to the tty_port helpers and let them do all the heavy lifting. This is also +fixes all the POSIX behaviour violations in the open/close paths. + +Begin by adding the tty port usage + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/char/nozomi.c | 115 +++++++++++++++++++++++++++++--------------------- + 1 file changed, 68 insertions(+), 47 deletions(-) + +--- a/drivers/char/nozomi.c ++++ b/drivers/char/nozomi.c +@@ -371,6 +371,8 @@ struct port { + struct mutex tty_sem; + wait_queue_head_t tty_wait; + struct async_icount tty_icount; ++ ++ struct nozomi *dc; + }; + + /* Private data one for each card in the system */ +@@ -414,6 +416,8 @@ MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl) + static struct nozomi *ndevs[NOZOMI_MAX_CARDS]; + static struct tty_driver *ntty_driver; + ++static const struct tty_port_operations noz_tty_port_ops; ++ + /* + * find card by tty_index + */ +@@ -1473,9 +1477,11 @@ static int __devinit nozomi_card_init(st + + for (i = 0; i < MAX_PORT; i++) { + struct device *tty_dev; +- +- mutex_init(&dc->port[i].tty_sem); +- tty_port_init(&dc->port[i].port); ++ struct port *port = &dc->port[i]; ++ port->dc = dc; ++ mutex_init(&port->tty_sem); ++ tty_port_init(&port->port); ++ port->port.ops = &noz_tty_port_ops; + tty_dev = tty_register_device(ntty_driver, dc->index_start + i, + &pdev->dev); + +@@ -1600,67 +1606,74 @@ static void set_dtr(const struct tty_str + * ---------------------------------------------------------------------------- + */ + +-/* Called when the userspace process opens the tty, /dev/noz*. */ +-static int ntty_open(struct tty_struct *tty, struct file *file) ++static int ntty_install(struct tty_driver *driver, struct tty_struct *tty) + { + struct port *port = get_port_by_tty(tty); + struct nozomi *dc = get_dc_by_tty(tty); +- unsigned long flags; +- ++ int ret; + if (!port || !dc || dc->state != NOZOMI_STATE_READY) + return -ENODEV; +- +- if (mutex_lock_interruptible(&port->tty_sem)) +- return -ERESTARTSYS; +- +- port->port.count++; +- dc->open_ttys++; +- +- /* Enable interrupt downlink for channel */ +- if (port->port.count == 1) { +- tty->driver_data = port; +- tty_port_tty_set(&port->port, tty); +- DBG1("open: %d", port->token_dl); +- spin_lock_irqsave(&dc->spin_mutex, flags); +- dc->last_ier = dc->last_ier | port->token_dl; +- writew(dc->last_ier, dc->reg_ier); +- spin_unlock_irqrestore(&dc->spin_mutex, flags); ++ ret = tty_init_termios(tty); ++ if (ret == 0) { ++ tty_driver_kref_get(driver); ++ driver->ttys[tty->index] = tty; + } +- mutex_unlock(&port->tty_sem); +- return 0; ++ return ret; + } + +-/* Called when the userspace process close the tty, /dev/noz*. Also +- called immediately if ntty_open fails in which case tty->driver_data +- will be NULL an we exit by the first return */ ++static void ntty_cleanup(struct tty_struct *tty) ++{ ++ tty->driver_data = NULL; ++} + +-static void ntty_close(struct tty_struct *tty, struct file *file) ++static int ntty_activate(struct tty_port *tport, struct tty_struct *tty) + { +- struct nozomi *dc = get_dc_by_tty(tty); +- struct port *nport = tty->driver_data; +- struct tty_port *port = &nport->port; ++ struct port *port = container_of(tport, struct port, port); ++ struct nozomi *dc = port->dc; + unsigned long flags; + +- if (!dc || !nport) +- return; ++ DBG1("open: %d", port->token_dl); ++ spin_lock_irqsave(&dc->spin_mutex, flags); ++ dc->last_ier = dc->last_ier | port->token_dl; ++ writew(dc->last_ier, dc->reg_ier); ++ dc->open_ttys++; ++ spin_unlock_irqrestore(&dc->spin_mutex, flags); ++ printk("noz: activated %d: %p\n", tty->index, tport); ++ return 0; ++} + +- /* Users cannot interrupt a close */ +- mutex_lock(&nport->tty_sem); ++static int ntty_open(struct tty_struct *tty, struct file *filp) ++{ ++ struct port *port = get_port_by_tty(tty); ++ return tty_port_open(&port->port, tty, filp); ++} + +- WARN_ON(!port->count); ++static void ntty_shutdown(struct tty_port *tport) ++{ ++ struct port *port = container_of(tport, struct port, port); ++ struct nozomi *dc = port->dc; ++ unsigned long flags; + ++ DBG1("close: %d", port->token_dl); ++ spin_lock_irqsave(&dc->spin_mutex, flags); ++ dc->last_ier &= ~(port->token_dl); ++ writew(dc->last_ier, dc->reg_ier); + dc->open_ttys--; +- port->count--; ++ spin_unlock_irqrestore(&dc->spin_mutex, flags); ++ printk("noz: shutdown %p\n", tport); ++} + +- if (port->count == 0) { +- DBG1("close: %d", nport->token_dl); +- tty_port_tty_set(port, NULL); +- spin_lock_irqsave(&dc->spin_mutex, flags); +- dc->last_ier &= ~(nport->token_dl); +- writew(dc->last_ier, dc->reg_ier); +- spin_unlock_irqrestore(&dc->spin_mutex, flags); +- } +- mutex_unlock(&nport->tty_sem); ++static void ntty_close(struct tty_struct *tty, struct file *filp) ++{ ++ struct port *port = tty->driver_data; ++ if (port) ++ tty_port_close(&port->port, tty, filp); ++} ++ ++static void ntty_hangup(struct tty_struct *tty) ++{ ++ struct port *port = tty->driver_data; ++ tty_port_hangup(&port->port); + } + + /* +@@ -1906,10 +1919,16 @@ exit_in_buffer: + return rval; + } + ++static const struct tty_port_operations noz_tty_port_ops = { ++ .activate = ntty_activate, ++ .shutdown = ntty_shutdown, ++}; ++ + static const struct tty_operations tty_ops = { + .ioctl = ntty_ioctl, + .open = ntty_open, + .close = ntty_close, ++ .hangup = ntty_hangup, + .write = ntty_write, + .write_room = ntty_write_room, + .unthrottle = ntty_unthrottle, +@@ -1917,6 +1936,8 @@ static const struct tty_operations tty_o + .chars_in_buffer = ntty_chars_in_buffer, + .tiocmget = ntty_tiocmget, + .tiocmset = ntty_tiocmset, ++ .install = ntty_install, ++ .cleanup = ntty_cleanup, + }; + + /* Module initialization */ diff --git a/tty/nozomi-fix-mutex-handling.patch b/tty/nozomi-fix-mutex-handling.patch new file mode 100644 index 00000000000000..73d252534b12e4 --- /dev/null +++ b/tty/nozomi-fix-mutex-handling.patch @@ -0,0 +1,76 @@ +From alan@linux.intel.com Wed Feb 17 14:59:38 2010 +From: Alan Cox <alan@linux.intel.com> +Date: Mon, 08 Feb 2010 10:07:04 +0000 +Subject: nozomi: Fix mutex handling +To: greg@kroah.com, linux-kernel@vger.kernel.org, p.hardwick@option.com +Message-ID: <20100208100650.2794.82836.stgit@localhost.localdomain> + + +The original author didn't realise the kernel lock was a drop while sleep +lock so did clever (and wrong) things to work around the non need to avoid +deadlocks. Remove the cleverness and the comment (as we don't hold the BKL +now anyway in those paths) + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/char/nozomi.c | 34 ++++++++++++---------------------- + 1 file changed, 12 insertions(+), 22 deletions(-) + +--- a/drivers/char/nozomi.c ++++ b/drivers/char/nozomi.c +@@ -1693,15 +1693,7 @@ static int ntty_write(struct tty_struct + if (!dc || !port) + return -ENODEV; + +- if (unlikely(!mutex_trylock(&port->tty_sem))) { +- /* +- * must test lock as tty layer wraps calls +- * to this function with BKL +- */ +- dev_err(&dc->pdev->dev, "Would have deadlocked - " +- "return EAGAIN\n"); +- return -EAGAIN; +- } ++ mutex_lock(&port->tty_sem); + + if (unlikely(!port->port.count)) { + DBG1(" "); +@@ -1741,25 +1733,23 @@ exit: + * This method is called by the upper tty layer. + * #according to sources N_TTY.c it expects a value >= 0 and + * does not check for negative values. ++ * ++ * If the port is unplugged report lots of room and let the bits ++ * dribble away so we don't block anything. + */ + static int ntty_write_room(struct tty_struct *tty) + { + struct port *port = tty->driver_data; +- int room = 0; ++ int room = 4096; + const struct nozomi *dc = get_dc_by_tty(tty); + +- if (!dc || !port) +- return 0; +- if (!mutex_trylock(&port->tty_sem)) +- return 0; +- +- if (!port->port.count) +- goto exit; +- +- room = port->fifo_ul.size - kfifo_len(&port->fifo_ul); +- +-exit: +- mutex_unlock(&port->tty_sem); ++ if (dc) { ++ mutex_lock(&port->tty_sem); ++ if (port->port.count) ++ room = port->fifo_ul.size - ++ kfifo_len(&port->fifo_ul); ++ mutex_unlock(&port->tty_sem); ++ } + return room; + } + diff --git a/tty/nozomi-tidy-up-the-pci-table.patch b/tty/nozomi-tidy-up-the-pci-table.patch new file mode 100644 index 00000000000000..04c0e244d48fe7 --- /dev/null +++ b/tty/nozomi-tidy-up-the-pci-table.patch @@ -0,0 +1,37 @@ +From alan@linux.intel.com Wed Feb 17 14:59:58 2010 +From: Alan Cox <alan@linux.intel.com> +Date: Mon, 08 Feb 2010 10:07:15 +0000 +Subject: nozomi: Tidy up the PCI table +To: greg@kroah.com, linux-kernel@vger.kernel.org, p.hardwick@option.com +Message-ID: <20100208100710.2794.73323.stgit@localhost.localdomain> + + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/char/nozomi.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +--- a/drivers/char/nozomi.c ++++ b/drivers/char/nozomi.c +@@ -136,10 +136,6 @@ static int debug; + #define RECEIVE_BUF_MAX 4 + + +-/* Define all types of vendors and devices to support */ +-#define VENDOR1 0x1931 /* Vendor Option */ +-#define DEVICE1 0x000c /* HSDPA card */ +- + #define R_IIR 0x0000 /* Interrupt Identity Register */ + #define R_FCR 0x0000 /* Flow Control Register */ + #define R_IER 0x0004 /* Interrupt Enable Register */ +@@ -407,7 +403,7 @@ struct buffer { + + /* Global variables */ + static const struct pci_device_id nozomi_pci_tbl[] __devinitconst = { +- {PCI_DEVICE(VENDOR1, DEVICE1)}, ++ {PCI_DEVICE(0x1931, 0x000c)}, /* Nozomi HSDPA */ + {}, + }; + diff --git a/tty/sdio_uart-use-kfifo-instead-of-the-messy-circ-stuff.patch b/tty/sdio_uart-use-kfifo-instead-of-the-messy-circ-stuff.patch new file mode 100644 index 00000000000000..5e4d4d985f62c4 --- /dev/null +++ b/tty/sdio_uart-use-kfifo-instead-of-the-messy-circ-stuff.patch @@ -0,0 +1,242 @@ +From alan@linux.intel.com Wed Feb 17 14:58:30 2010 +From: Alan Cox <alan@linux.intel.com> +Date: Mon, 08 Feb 2010 10:08:39 +0000 +Subject: sdio_uart: Use kfifo instead of the messy circ stuff +To: linux-kernel@vger.kernel.org, greg@kroah.com +Message-ID: <20100208100808.2887.38401.stgit@localhost.localdomain> + + +Revised patch to use the new kfifo API. This replaces the one that was dropped +from -next due to collisions with the kfifo API changes. + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/mmc/card/sdio_uart.c | 93 +++++++++++++------------------------------ + 1 file changed, 30 insertions(+), 63 deletions(-) + +--- a/drivers/mmc/card/sdio_uart.c ++++ b/drivers/mmc/card/sdio_uart.c +@@ -37,6 +37,7 @@ + #include <linux/gfp.h> + #include <linux/tty.h> + #include <linux/tty_flip.h> ++#include <linux/kfifo.h> + + #include <linux/mmc/core.h> + #include <linux/mmc/card.h> +@@ -47,19 +48,9 @@ + #define UART_NR 8 /* Number of UARTs this driver can handle */ + + +-#define UART_XMIT_SIZE PAGE_SIZE ++#define FIFO_SIZE PAGE_SIZE + #define WAKEUP_CHARS 256 + +-#define circ_empty(circ) ((circ)->head == (circ)->tail) +-#define circ_clear(circ) ((circ)->head = (circ)->tail = 0) +- +-#define circ_chars_pending(circ) \ +- (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE)) +- +-#define circ_chars_free(circ) \ +- (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE)) +- +- + struct uart_icount { + __u32 cts; + __u32 dsr; +@@ -82,7 +73,7 @@ struct sdio_uart_port { + struct mutex func_lock; + struct task_struct *in_sdio_uart_irq; + unsigned int regs_offset; +- struct circ_buf xmit; ++ struct kfifo xmit_fifo; + spinlock_t write_lock; + struct uart_icount icount; + unsigned int uartclk; +@@ -105,6 +96,8 @@ static int sdio_uart_add_port(struct sdi + kref_init(&port->kref); + mutex_init(&port->func_lock); + spin_lock_init(&port->write_lock); ++ if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL)) ++ return -ENOMEM; + + spin_lock(&sdio_uart_table_lock); + for (index = 0; index < UART_NR; index++) { +@@ -140,6 +133,7 @@ static void sdio_uart_port_destroy(struc + { + struct sdio_uart_port *port = + container_of(kref, struct sdio_uart_port, kref); ++ kfifo_free(&port->xmit_fifo); + kfree(port); + } + +@@ -456,9 +450,11 @@ static void sdio_uart_receive_chars(stru + + static void sdio_uart_transmit_chars(struct sdio_uart_port *port) + { +- struct circ_buf *xmit = &port->xmit; ++ struct kfifo *xmit = &port->xmit_fifo; + int count; + struct tty_struct *tty; ++ u8 iobuf[16]; ++ int len; + + if (port->x_char) { + sdio_out(port, UART_TX, port->x_char); +@@ -469,27 +465,25 @@ static void sdio_uart_transmit_chars(str + + tty = tty_port_tty_get(&port->port); + +- if (tty == NULL || circ_empty(xmit) || ++ if (tty == NULL || !kfifo_len(xmit) || + tty->stopped || tty->hw_stopped) { + sdio_uart_stop_tx(port); + tty_kref_put(tty); + return; + } + +- count = 16; +- do { +- sdio_out(port, UART_TX, xmit->buf[xmit->tail]); +- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); ++ len = kfifo_out_locked(xmit, iobuf, 16, &port->write_lock); ++ for (count = 0; count < len; count++) { ++ sdio_out(port, UART_TX, iobuf[count]); + port->icount.tx++; +- if (circ_empty(xmit)) +- break; +- } while (--count > 0); ++ } + +- if (circ_chars_pending(xmit) < WAKEUP_CHARS) ++ len = kfifo_len(xmit); ++ if (len < WAKEUP_CHARS) { + tty_wakeup(tty); +- +- if (circ_empty(xmit)) +- sdio_uart_stop_tx(port); ++ if (len == 0) ++ sdio_uart_stop_tx(port); ++ } + tty_kref_put(tty); + } + +@@ -632,7 +626,6 @@ static int sdio_uart_activate(struct tty + { + struct sdio_uart_port *port = + container_of(tport, struct sdio_uart_port, port); +- unsigned long page; + int ret; + + /* +@@ -641,22 +634,17 @@ static int sdio_uart_activate(struct tty + */ + set_bit(TTY_IO_ERROR, &tty->flags); + +- /* Initialise and allocate the transmit buffer. */ +- page = __get_free_page(GFP_KERNEL); +- if (!page) +- return -ENOMEM; +- port->xmit.buf = (unsigned char *)page; +- circ_clear(&port->xmit); ++ kfifo_reset(&port->xmit_fifo); + + ret = sdio_uart_claim_func(port); + if (ret) +- goto err1; ++ return ret; + ret = sdio_enable_func(port->func); + if (ret) +- goto err2; ++ goto err1; + ret = sdio_claim_irq(port->func, sdio_uart_irq); + if (ret) +- goto err3; ++ goto err2; + + /* + * Clear the FIFO buffers and disable them. +@@ -700,12 +688,10 @@ static int sdio_uart_activate(struct tty + sdio_uart_release_func(port); + return 0; + +-err3: +- sdio_disable_func(port->func); + err2: +- sdio_uart_release_func(port); ++ sdio_disable_func(port->func); + err1: +- free_page((unsigned long)port->xmit.buf); ++ sdio_uart_release_func(port); + return ret; + } + +@@ -727,7 +713,7 @@ static void sdio_uart_shutdown(struct tt + + ret = sdio_uart_claim_func(port); + if (ret) +- goto skip; ++ return; + + sdio_uart_stop_rx(port); + +@@ -749,10 +735,6 @@ static void sdio_uart_shutdown(struct tt + sdio_disable_func(port->func); + + sdio_uart_release_func(port); +- +-skip: +- /* Free the transmit buffer page. */ +- free_page((unsigned long)port->xmit.buf); + } + + /** +@@ -822,27 +804,12 @@ static int sdio_uart_write(struct tty_st + int count) + { + struct sdio_uart_port *port = tty->driver_data; +- struct circ_buf *circ = &port->xmit; +- int c, ret = 0; ++ int ret; + + if (!port->func) + return -ENODEV; + +- spin_lock(&port->write_lock); +- while (1) { +- c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); +- if (count < c) +- c = count; +- if (c <= 0) +- break; +- memcpy(circ->buf + circ->head, buf, c); +- circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1); +- buf += c; +- count -= c; +- ret += c; +- } +- spin_unlock(&port->write_lock); +- ++ ret = kfifo_in_locked(&port->xmit_fifo, buf, count, &port->write_lock); + if (!(port->ier & UART_IER_THRI)) { + int err = sdio_uart_claim_func(port); + if (!err) { +@@ -859,13 +826,13 @@ static int sdio_uart_write(struct tty_st + static int sdio_uart_write_room(struct tty_struct *tty) + { + struct sdio_uart_port *port = tty->driver_data; +- return port ? circ_chars_free(&port->xmit) : 0; ++ return FIFO_SIZE - kfifo_len(&port->xmit_fifo); + } + + static int sdio_uart_chars_in_buffer(struct tty_struct *tty) + { + struct sdio_uart_port *port = tty->driver_data; +- return port ? circ_chars_pending(&port->xmit) : 0; ++ return kfifo_len(&port->xmit_fifo); + } + + static void sdio_uart_send_xchar(struct tty_struct *tty, char ch) diff --git a/tty/serial-timberdale-remove-dependancies.patch b/tty/serial-timberdale-remove-dependancies.patch new file mode 100644 index 00000000000000..4e985fea0e6b97 --- /dev/null +++ b/tty/serial-timberdale-remove-dependancies.patch @@ -0,0 +1,28 @@ +From alan@linux.intel.com Wed Feb 17 15:00:23 2010 +From: Alan Cox <alan@linux.intel.com> +Date: Mon, 08 Feb 2010 10:03:58 +0000 +Subject: serial: timberdale: Remove dependancies +To: greg@kroah.com, linux-kernel@vger.kernel.org +Message-ID: <20100208100353.2633.42797.stgit@localhost.localdomain> + + +MFD_TIMBERDALE doesn't appear to be defined anywhere. However the code in +question can build happily without platform specifics so remove the check + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/serial/Kconfig | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/serial/Kconfig ++++ b/drivers/serial/Kconfig +@@ -1449,7 +1449,6 @@ config SERIAL_BFIN_SPORT3_UART + + config SERIAL_TIMBERDALE + tristate "Support for timberdale UART" +- depends on MFD_TIMBERDALE + select SERIAL_CORE + ---help--- + Add support for UART controller on timberdale. diff --git a/tty/tty-fix-the-ldisc-hangup-race.patch b/tty/tty-fix-the-ldisc-hangup-race.patch new file mode 100644 index 00000000000000..c3e2c5df2cc296 --- /dev/null +++ b/tty/tty-fix-the-ldisc-hangup-race.patch @@ -0,0 +1,121 @@ +From alan@linux.intel.com Wed Feb 17 15:01:01 2010 +From: Alan Cox <alan@linux.intel.com> +Date: Mon, 08 Feb 2010 10:09:26 +0000 +Subject: tty: Fix the ldisc hangup race +To: linux-kernel@vger.kernel.org, greg@kroah.com +Message-ID: <20100208100858.2930.80953.stgit@localhost.localdomain> + + +This was noticed by Matthias Urlichs and he proposed a fix. This patch +does the fixing a different way to avoid introducing several new race +conditions into the code. + +The problem case is TTY_DRIVER_RESET_TERMIOS = 0. In that case while we +abort the ldisc change, the hangup processing has not cleaned up and restarted +the ldisc either. + +We can't restart the ldisc stuff in the set_ldisc as we don't know what +the hangup did and may touch stuff we shouldn't as we are no longer +supposed to influence the tty at that point in case it has been re-opened +before we get rescheduled. + +Instead do it the simple way. Always re-init the ldisc on the hangup, but +use TTY_DRIVER_RESET_TERMIOS to indicate that we should force N_TTY. + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Cc: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/char/tty_ldisc.c | 50 ++++++++++++++++++++++++++++------------------- + 1 file changed, 30 insertions(+), 20 deletions(-) + +--- a/drivers/char/tty_ldisc.c ++++ b/drivers/char/tty_ldisc.c +@@ -706,12 +706,13 @@ static void tty_reset_termios(struct tty + /** + * tty_ldisc_reinit - reinitialise the tty ldisc + * @tty: tty to reinit ++ * @ldisc: line discipline to reinitialize + * +- * Switch the tty back to N_TTY line discipline and leave the +- * ldisc state closed ++ * Switch the tty to a line discipline and leave the ldisc ++ * state closed + */ + +-static void tty_ldisc_reinit(struct tty_struct *tty) ++static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc) + { + struct tty_ldisc *ld; + +@@ -721,10 +722,10 @@ static void tty_ldisc_reinit(struct tty_ + /* + * Switch the line discipline back + */ +- ld = tty_ldisc_get(N_TTY); ++ ld = tty_ldisc_get(ldisc); + BUG_ON(IS_ERR(ld)); + tty_ldisc_assign(tty, ld); +- tty_set_termios_ldisc(tty, N_TTY); ++ tty_set_termios_ldisc(tty, ldisc); + } + + /** +@@ -745,6 +746,8 @@ static void tty_ldisc_reinit(struct tty_ + void tty_ldisc_hangup(struct tty_struct *tty) + { + struct tty_ldisc *ld; ++ int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS; ++ int err = 0; + + /* + * FIXME! What are the locking issues here? This may me overdoing +@@ -772,25 +775,32 @@ void tty_ldisc_hangup(struct tty_struct + wake_up_interruptible_poll(&tty->read_wait, POLLIN); + /* + * Shutdown the current line discipline, and reset it to +- * N_TTY. ++ * N_TTY if need be. ++ * ++ * Avoid racing set_ldisc or tty_ldisc_release + */ +- if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { +- /* Avoid racing set_ldisc or tty_ldisc_release */ +- mutex_lock(&tty->ldisc_mutex); +- tty_ldisc_halt(tty); +- if (tty->ldisc) { /* Not yet closed */ +- /* Switch back to N_TTY */ +- tty_ldisc_reinit(tty); +- /* At this point we have a closed ldisc and we want to +- reopen it. We could defer this to the next open but +- it means auditing a lot of other paths so this is +- a FIXME */ ++ mutex_lock(&tty->ldisc_mutex); ++ tty_ldisc_halt(tty); ++ /* At this point we have a closed ldisc and we want to ++ reopen it. We could defer this to the next open but ++ it means auditing a lot of other paths so this is ++ a FIXME */ ++ if (tty->ldisc) { /* Not yet closed */ ++ if (reset == 0) { ++ tty_ldisc_reinit(tty, tty->termios->c_line); ++ err = tty_ldisc_open(tty, tty->ldisc); ++ } ++ /* If the re-open fails or we reset then go to N_TTY. The ++ N_TTY open cannot fail */ ++ if (reset || err) { ++ tty_ldisc_reinit(tty, N_TTY); + WARN_ON(tty_ldisc_open(tty, tty->ldisc)); +- tty_ldisc_enable(tty); + } +- mutex_unlock(&tty->ldisc_mutex); +- tty_reset_termios(tty); ++ tty_ldisc_enable(tty); + } ++ mutex_unlock(&tty->ldisc_mutex); ++ if (reset) ++ tty_reset_termios(tty); + } + + /** diff --git a/usb/tty-fix-various-bogus-warn-checks-in-the-usb-serial-layer.patch b/usb/tty-fix-various-bogus-warn-checks-in-the-usb-serial-layer.patch new file mode 100644 index 00000000000000..f368c5b986a6bb --- /dev/null +++ b/usb/tty-fix-various-bogus-warn-checks-in-the-usb-serial-layer.patch @@ -0,0 +1,96 @@ +From alan@linux.intel.com Wed Feb 17 15:01:55 2010 +From: Alan Cox <alan@linux.intel.com> +Date: Mon, 08 Feb 2010 10:10:04 +0000 +Subject: tty: Fix various bogus WARN checks in the usb serial layer +To: linux-usb@vger.kernel.org, greg@kroah.com +Message-ID: <20100208100956.2972.27945.stgit@localhost.localdomain> + + +We are now refcounted and all the port.count checking is no longer valid +and in fact produces false warnings. + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/usb-serial.c | 13 ------------- + 1 file changed, 13 deletions(-) + +--- a/drivers/usb/serial/usb-serial.c ++++ b/drivers/usb/serial/usb-serial.c +@@ -358,10 +358,6 @@ static int serial_write(struct tty_struc + + dbg("%s - port %d, %d byte(s)", __func__, port->number, count); + +- /* count is managed under the mutex lock for the tty so cannot +- drop to zero until after the last close completes */ +- WARN_ON(!port->port.count); +- + /* pass on to the driver specific version of this function */ + retval = port->serial->type->write(tty, port, buf, count); + +@@ -373,7 +369,6 @@ static int serial_write_room(struct tty_ + { + struct usb_serial_port *port = tty->driver_data; + dbg("%s - port %d", __func__, port->number); +- WARN_ON(!port->port.count); + /* pass on to the driver specific version of this function */ + return port->serial->type->write_room(tty); + } +@@ -396,7 +391,6 @@ static void serial_throttle(struct tty_s + struct usb_serial_port *port = tty->driver_data; + dbg("%s - port %d", __func__, port->number); + +- WARN_ON(!port->port.count); + /* pass on to the driver specific version of this function */ + if (port->serial->type->throttle) + port->serial->type->throttle(tty); +@@ -407,7 +401,6 @@ static void serial_unthrottle(struct tty + struct usb_serial_port *port = tty->driver_data; + dbg("%s - port %d", __func__, port->number); + +- WARN_ON(!port->port.count); + /* pass on to the driver specific version of this function */ + if (port->serial->type->unthrottle) + port->serial->type->unthrottle(tty); +@@ -421,8 +414,6 @@ static int serial_ioctl(struct tty_struc + + dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd); + +- WARN_ON(!port->port.count); +- + /* pass on to the driver specific version of this function + if it is available */ + if (port->serial->type->ioctl) { +@@ -437,7 +428,6 @@ static void serial_set_termios(struct tt + struct usb_serial_port *port = tty->driver_data; + dbg("%s - port %d", __func__, port->number); + +- WARN_ON(!port->port.count); + /* pass on to the driver specific version of this function + if it is available */ + if (port->serial->type->set_termios) +@@ -452,7 +442,6 @@ static int serial_break(struct tty_struc + + dbg("%s - port %d", __func__, port->number); + +- WARN_ON(!port->port.count); + /* pass on to the driver specific version of this function + if it is available */ + if (port->serial->type->break_ctl) +@@ -513,7 +502,6 @@ static int serial_tiocmget(struct tty_st + + dbg("%s - port %d", __func__, port->number); + +- WARN_ON(!port->port.count); + if (port->serial->type->tiocmget) + return port->serial->type->tiocmget(tty, file); + return -EINVAL; +@@ -526,7 +514,6 @@ static int serial_tiocmset(struct tty_st + + dbg("%s - port %d", __func__, port->number); + +- WARN_ON(!port->port.count); + if (port->serial->type->tiocmset) + return port->serial->type->tiocmset(tty, file, set, clear); + return -EINVAL; diff --git a/usb/usb-convert-concatenated-__file__-to-s-__file__.patch b/usb/usb-convert-concatenated-__file__-to-s-__file__.patch new file mode 100644 index 00000000000000..d32aa77fb802f0 --- /dev/null +++ b/usb/usb-convert-concatenated-__file__-to-s-__file__.patch @@ -0,0 +1,328 @@ +From joe@perches.com Wed Feb 17 14:51:04 2010 +From: Joe Perches <joe@perches.com> +Date: Fri, 05 Feb 2010 17:51:13 -0800 +Subject: USB: Convert concatenated __FILE__ to %s, __FILE__ +To: Greg Kroah-Hartman <gregkh@suse.de> +Message-ID: <1265421073.10226.56.camel@Joe-Laptop.home> + + +Reduces string space a bit +Neaten a macro redefine of dbg + +Signed-off-by: Joe Perches <joe@perches.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/host/ehci-ppc-of.c | 12 ++++++------ + drivers/usb/host/ehci-xilinx-of.c | 6 +++--- + drivers/usb/host/ohci-dbg.c | 4 ++-- + drivers/usb/host/ohci-lh7a404.c | 11 +++++------ + drivers/usb/host/ohci-ppc-of.c | 8 ++++---- + drivers/usb/host/ohci-ppc-soc.c | 8 ++++---- + drivers/usb/host/ohci-sa1111.c | 8 ++++---- + drivers/usb/misc/adutux.c | 6 +++--- + drivers/usb/misc/ldusb.c | 2 +- + drivers/usb/misc/legousbtower.c | 11 +++++++---- + drivers/usb/serial/omninet.c | 4 ++-- + 11 files changed, 41 insertions(+), 39 deletions(-) + +--- a/drivers/usb/host/ehci-ppc-of.c ++++ b/drivers/usb/host/ehci-ppc-of.c +@@ -134,21 +134,21 @@ ehci_hcd_ppc_of_probe(struct of_device * + hcd->rsrc_len = res.end - res.start + 1; + + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { +- printk(KERN_ERR __FILE__ ": request_mem_region failed\n"); ++ printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__); + rv = -EBUSY; + goto err_rmr; + } + + irq = irq_of_parse_and_map(dn, 0); + if (irq == NO_IRQ) { +- printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n"); ++ printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); + rv = -EBUSY; + goto err_irq; + } + + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + if (!hcd->regs) { +- printk(KERN_ERR __FILE__ ": ioremap failed\n"); ++ printk(KERN_ERR "%s: ioremap failed\n", __FILE__); + rv = -ENOMEM; + goto err_ioremap; + } +@@ -161,9 +161,9 @@ ehci_hcd_ppc_of_probe(struct of_device * + ehci->ohci_hcctrl_reg = ioremap(res.start + + OHCI_HCCTRL_OFFSET, OHCI_HCCTRL_LEN); + else +- pr_debug(__FILE__ ": no ohci offset in fdt\n"); ++ pr_debug("%s: no ohci offset in fdt\n", __FILE__); + if (!ehci->ohci_hcctrl_reg) { +- pr_debug(__FILE__ ": ioremap for ohci hcctrl failed\n"); ++ pr_debug("%s: ioremap for ohci hcctrl failed\n", __FILE__); + } else { + ehci->has_amcc_usb23 = 1; + } +@@ -241,7 +241,7 @@ static int ehci_hcd_ppc_of_remove(struct + else + release_mem_region(res.start, 0x4); + else +- pr_debug(__FILE__ ": no ohci offset in fdt\n"); ++ pr_debug("%s: no ohci offset in fdt\n", __FILE__); + of_node_put(np); + } + +--- a/drivers/usb/host/ehci-xilinx-of.c ++++ b/drivers/usb/host/ehci-xilinx-of.c +@@ -177,21 +177,21 @@ ehci_hcd_xilinx_of_probe(struct of_devic + hcd->rsrc_len = res.end - res.start + 1; + + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { +- printk(KERN_ERR __FILE__ ": request_mem_region failed\n"); ++ printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__); + rv = -EBUSY; + goto err_rmr; + } + + irq = irq_of_parse_and_map(dn, 0); + if (irq == NO_IRQ) { +- printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n"); ++ printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); + rv = -EBUSY; + goto err_irq; + } + + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + if (!hcd->regs) { +- printk(KERN_ERR __FILE__ ": ioremap failed\n"); ++ printk(KERN_ERR "%s: ioremap failed\n", __FILE__); + rv = -ENOMEM; + goto err_ioremap; + } +--- a/drivers/usb/host/ohci-dbg.c ++++ b/drivers/usb/host/ohci-dbg.c +@@ -53,13 +53,13 @@ urb_print(struct urb * urb, char * str, + int i, len; + + if (usb_pipecontrol (pipe)) { +- printk (KERN_DEBUG __FILE__ ": setup(8):"); ++ printk (KERN_DEBUG "%s: setup(8):", __FILE__); + for (i = 0; i < 8 ; i++) + printk (" %02x", ((__u8 *) urb->setup_packet) [i]); + printk ("\n"); + } + if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) { +- printk (KERN_DEBUG __FILE__ ": data(%d/%d):", ++ printk (KERN_DEBUG "%s: data(%d/%d):", __FILE__, + urb->actual_length, + urb->transfer_buffer_length); + len = usb_pipeout (pipe)? +--- a/drivers/usb/host/ohci-lh7a404.c ++++ b/drivers/usb/host/ohci-lh7a404.c +@@ -28,8 +28,8 @@ extern int usb_disabled(void); + + static void lh7a404_start_hc(struct platform_device *dev) + { +- printk(KERN_DEBUG __FILE__ +- ": starting LH7A404 OHCI USB Controller\n"); ++ printk(KERN_DEBUG "%s: starting LH7A404 OHCI USB Controller\n", ++ __FILE__); + + /* + * Now, carefully enable the USB clock, and take +@@ -39,14 +39,13 @@ static void lh7a404_start_hc(struct plat + udelay(1000); + USBH_CMDSTATUS = OHCI_HCR; + +- printk(KERN_DEBUG __FILE__ +- ": Clock to USB host has been enabled \n"); ++ printk(KERN_DEBUG "%s: Clock to USB host has been enabled \n", __FILE__); + } + + static void lh7a404_stop_hc(struct platform_device *dev) + { +- printk(KERN_DEBUG __FILE__ +- ": stopping LH7A404 OHCI USB Controller\n"); ++ printk(KERN_DEBUG "%s: stopping LH7A404 OHCI USB Controller\n", ++ __FILE__); + + CSC_PWRCNT &= ~CSC_PWRCNT_USBH_EN; /* Disable clock */ + } +--- a/drivers/usb/host/ohci-ppc-of.c ++++ b/drivers/usb/host/ohci-ppc-of.c +@@ -114,21 +114,21 @@ ohci_hcd_ppc_of_probe(struct of_device * + hcd->rsrc_len = res.end - res.start + 1; + + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { +- printk(KERN_ERR __FILE__ ": request_mem_region failed\n"); ++ printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__); + rv = -EBUSY; + goto err_rmr; + } + + irq = irq_of_parse_and_map(dn, 0); + if (irq == NO_IRQ) { +- printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n"); ++ printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); + rv = -EBUSY; + goto err_irq; + } + + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + if (!hcd->regs) { +- printk(KERN_ERR __FILE__ ": ioremap failed\n"); ++ printk(KERN_ERR "%s: ioremap failed\n", __FILE__); + rv = -ENOMEM; + goto err_ioremap; + } +@@ -169,7 +169,7 @@ ohci_hcd_ppc_of_probe(struct of_device * + } else + release_mem_region(res.start, 0x4); + } else +- pr_debug(__FILE__ ": cannot get ehci offset from fdt\n"); ++ pr_debug("%s: cannot get ehci offset from fdt\n", __FILE__); + } + + iounmap(hcd->regs); +--- a/drivers/usb/host/ohci-ppc-soc.c ++++ b/drivers/usb/host/ohci-ppc-soc.c +@@ -41,14 +41,14 @@ static int usb_hcd_ppc_soc_probe(const s + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { +- pr_debug(__FILE__ ": no irq\n"); ++ pr_debug("%s: no irq\n", __FILE__); + return -ENODEV; + } + irq = res->start; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { +- pr_debug(__FILE__ ": no reg addr\n"); ++ pr_debug("%s: no reg addr\n", __FILE__); + return -ENODEV; + } + +@@ -59,14 +59,14 @@ static int usb_hcd_ppc_soc_probe(const s + hcd->rsrc_len = res->end - res->start + 1; + + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { +- pr_debug(__FILE__ ": request_mem_region failed\n"); ++ pr_debug("%s: request_mem_region failed\n", __FILE__); + retval = -EBUSY; + goto err1; + } + + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + if (!hcd->regs) { +- pr_debug(__FILE__ ": ioremap failed\n"); ++ pr_debug("%s: ioremap failed\n", __FILE__); + retval = -ENOMEM; + goto err2; + } +--- a/drivers/usb/host/ohci-sa1111.c ++++ b/drivers/usb/host/ohci-sa1111.c +@@ -31,8 +31,8 @@ static void sa1111_start_hc(struct sa111 + { + unsigned int usb_rst = 0; + +- printk(KERN_DEBUG __FILE__ +- ": starting SA-1111 OHCI USB Controller\n"); ++ printk(KERN_DEBUG "%s: starting SA-1111 OHCI USB Controller\n", ++ __FILE__); + + #ifdef CONFIG_SA1100_BADGE4 + if (machine_is_badge4()) { +@@ -65,8 +65,8 @@ static void sa1111_start_hc(struct sa111 + static void sa1111_stop_hc(struct sa1111_dev *dev) + { + unsigned int usb_rst; +- printk(KERN_DEBUG __FILE__ +- ": stopping SA-1111 OHCI USB Controller\n"); ++ printk(KERN_DEBUG "%s: stopping SA-1111 OHCI USB Controller\n", ++ __FILE__); + + /* + * Put the USB host controller into reset. +--- a/drivers/usb/misc/adutux.c ++++ b/drivers/usb/misc/adutux.c +@@ -38,7 +38,7 @@ static int debug = 1; + #define dbg(lvl, format, arg...) \ + do { \ + if (debug >= lvl) \ +- printk(KERN_DEBUG __FILE__ " : " format " \n", ## arg); \ ++ printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg); \ + } while (0) + + +@@ -132,8 +132,8 @@ static void adu_debug_data(int level, co + if (debug < level) + return; + +- printk(KERN_DEBUG __FILE__": %s - length = %d, data = ", +- function, size); ++ printk(KERN_DEBUG "%s: %s - length = %d, data = ", ++ __FILE__, function, size); + for (i = 0; i < size; ++i) + printk("%.2x ", data[i]); + printk("\n"); +--- a/drivers/usb/misc/ldusb.c ++++ b/drivers/usb/misc/ldusb.c +@@ -798,7 +798,7 @@ static int __init ld_usb_init(void) + /* register this driver with the USB subsystem */ + retval = usb_register(&ld_usb_driver); + if (retval) +- err("usb_register failed for the "__FILE__" driver. Error number %d\n", retval); ++ err("usb_register failed for the %s driver. Error number %d\n", __FILE__, retval); + + return retval; + } +--- a/drivers/usb/misc/legousbtower.c ++++ b/drivers/usb/misc/legousbtower.c +@@ -95,8 +95,11 @@ + + /* Use our own dbg macro */ + #undef dbg +-#define dbg(lvl, format, arg...) do { if (debug >= lvl) printk(KERN_DEBUG __FILE__ ": " format "\n", ## arg); } while (0) +- ++#define dbg(lvl, format, arg...) \ ++do { \ ++ if (debug >= lvl) \ ++ printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg); \ ++} while (0) + + /* Version Information */ + #define DRIVER_VERSION "v0.96" +@@ -302,7 +305,7 @@ static inline void lego_usb_tower_debug_ + if (debug < level) + return; + +- printk (KERN_DEBUG __FILE__": %s - length = %d, data = ", function, size); ++ printk (KERN_DEBUG "%s: %s - length = %d, data = ", __FILE__, function, size); + for (i = 0; i < size; ++i) { + printk ("%.2x ", data[i]); + } +@@ -1055,7 +1058,7 @@ static int __init lego_usb_tower_init(vo + /* register this driver with the USB subsystem */ + result = usb_register(&tower_driver); + if (result < 0) { +- err("usb_register failed for the "__FILE__" driver. Error number %d", result); ++ err("usb_register failed for the %s driver. Error number %d", __FILE__, result); + retval = -1; + goto exit; + } +--- a/drivers/usb/serial/omninet.c ++++ b/drivers/usb/serial/omninet.c +@@ -218,8 +218,8 @@ static void omninet_read_bulk_callback(s + + if (debug && header->oh_xxx != 0x30) { + if (urb->actual_length) { +- printk(KERN_DEBUG __FILE__ +- ": omninet_read %d: ", header->oh_len); ++ printk(KERN_DEBUG "%s: omninet_read %d: ", ++ __FILE__, header->oh_len); + for (i = 0; i < (header->oh_len + + OMNINET_HEADERLEN); i++) + printk("%.2x ", data[i]); diff --git a/usb/usb-cp210x-add-81e8-zephyr-bioharness.patch b/usb/usb-cp210x-add-81e8-zephyr-bioharness.patch new file mode 100644 index 00000000000000..822097bfbf1ae2 --- /dev/null +++ b/usb/usb-cp210x-add-81e8-zephyr-bioharness.patch @@ -0,0 +1,35 @@ +From alan@linux.intel.com Wed Feb 17 15:02:21 2010 +From: Alan Cox <alan@linux.intel.com> +Date: Mon, 08 Feb 2010 10:10:44 +0000 +Subject: USB: cp210x: Add 81E8 (Zephyr Bioharness) +To: linux-usb@vger.kernel.org, greg@kroah.com +Message-ID: <20100208101032.3032.14471.stgit@localhost.localdomain> + + +As reported in +http://bugzilla.kernel.org/show_bug.cgi?id=10980 + +Signed-off-by: Alan Cox <alan@linux.intel.com> +Cc: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/cp210x.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -91,11 +91,12 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ + { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ + { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ ++ { USB_DEVICE(0x10C4, 0x81E8) }, /* Zephyr Bioharness */ + { USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */ + { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ + { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */ + { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */ +- { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ ++ { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesys ETRX2USB */ + { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ + { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ + { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */ diff --git a/usb/usb-ehci-dbgp-split-pid-register-updates-for-in-and-out-pipes.patch b/usb/usb-ehci-dbgp-split-pid-register-updates-for-in-and-out-pipes.patch new file mode 100644 index 00000000000000..0137731156609d --- /dev/null +++ b/usb/usb-ehci-dbgp-split-pid-register-updates-for-in-and-out-pipes.patch @@ -0,0 +1,170 @@ +From jason.wessel@windriver.com Wed Feb 17 14:39:09 2010 +From: Jason Wessel <jason.wessel@windriver.com> +Date: Fri, 5 Feb 2010 11:49:05 -0600 +Subject: USB: ehci-dbgp: split PID register updates for IN and OUT pipes +To: gregkh@suse.de +Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Jason Wessel <jason.wessel@windriver.com>, Eric Biederman <ebiederm@xmission.com>, Yinghai Lu <yhlu.kernel@gmail.com> +Message-ID: <1265392145-24197-1-git-send-email-jason.wessel@windriver.com> + + +This patch addresses two problems: + +1) Bulk reads should always use the DATA0 for the pid, and the write + PID should toggle between DATA0 and DATA1. The fix is using + dbgp_pid_write_update() and dbgp_pid_read_update(). + +2) The delay loop for waiting for a transaction was not long enough to + always complete the initial handshake inside dbgp_wait_until_done(). + After the initial handshake the maximum delay length is never reached. + +The combined result of these two changes allows for the removal of the +forced resynchronization where a bulk write was issued with a dummy +data payload only to get the device to start accepting data writes +again. + +CC: Eric Biederman <ebiederm@xmission.com> +CC: Yinghai Lu <yhlu.kernel@gmail.com> +Signed-off-by: Jason Wessel <jason.wessel@windriver.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/early/ehci-dbgp.c | 68 +++++++++++++++++------------------------- + 1 file changed, 28 insertions(+), 40 deletions(-) + +--- a/drivers/usb/early/ehci-dbgp.c ++++ b/drivers/usb/early/ehci-dbgp.c +@@ -66,8 +66,6 @@ static struct ehci_dev ehci_dev; + + #define USB_DEBUG_DEVNUM 127 + +-#define DBGP_DATA_TOGGLE 0x8800 +- + #ifdef DBGP_DEBUG + #define dbgp_printk printk + static void dbgp_ehci_status(char *str) +@@ -88,11 +86,6 @@ static inline void dbgp_ehci_status(char + static inline void dbgp_printk(const char *fmt, ...) { } + #endif + +-static inline u32 dbgp_pid_update(u32 x, u32 tok) +-{ +- return ((x ^ DBGP_DATA_TOGGLE) & 0xffff00) | (tok & 0xff); +-} +- + static inline u32 dbgp_len_update(u32 x, u32 len) + { + return (x & ~0x0f) | (len & 0x0f); +@@ -136,6 +129,19 @@ static inline u32 dbgp_len_update(u32 x, + + #define DBGP_MAX_PACKET 8 + #define DBGP_TIMEOUT (250 * 1000) ++#define DBGP_LOOPS 1000 ++ ++static inline u32 dbgp_pid_write_update(u32 x, u32 tok) ++{ ++ static int data0 = USB_PID_DATA1; ++ data0 ^= USB_PID_DATA_TOGGLE; ++ return (x & 0xffff0000) | (data0 << 8) | (tok & 0xff); ++} ++ ++static inline u32 dbgp_pid_read_update(u32 x, u32 tok) ++{ ++ return (x & 0xffff0000) | (USB_PID_DATA0 << 8) | (tok & 0xff); ++} + + static int dbgp_wait_until_complete(void) + { +@@ -180,7 +186,7 @@ static int dbgp_wait_until_done(unsigned + { + u32 pids, lpid; + int ret; +- int loop = 3; ++ int loop = DBGP_LOOPS; + + retry: + writel(ctrl | DBGP_GO, &ehci_debug->control); +@@ -197,6 +203,8 @@ retry: + */ + if (ret == -DBGP_TIMEOUT && !dbgp_not_safe) + dbgp_not_safe = 1; ++ if (ret == -DBGP_ERR_BAD && --loop > 0) ++ goto retry; + return ret; + } + +@@ -245,12 +253,20 @@ static inline void dbgp_get_data(void *b + bytes[i] = (hi >> (8*(i - 4))) & 0xff; + } + +-static int dbgp_out(u32 addr, const char *bytes, int size) ++static int dbgp_bulk_write(unsigned devnum, unsigned endpoint, ++ const char *bytes, int size) + { ++ int ret; ++ u32 addr; + u32 pids, ctrl; + ++ if (size > DBGP_MAX_PACKET) ++ return -1; ++ ++ addr = DBGP_EPADDR(devnum, endpoint); ++ + pids = readl(&ehci_debug->pids); +- pids = dbgp_pid_update(pids, USB_PID_OUT); ++ pids = dbgp_pid_write_update(pids, USB_PID_OUT); + + ctrl = readl(&ehci_debug->control); + ctrl = dbgp_len_update(ctrl, size); +@@ -260,34 +276,7 @@ static int dbgp_out(u32 addr, const char + dbgp_set_data(bytes, size); + writel(addr, &ehci_debug->address); + writel(pids, &ehci_debug->pids); +- return dbgp_wait_until_done(ctrl); +-} +- +-static int dbgp_bulk_write(unsigned devnum, unsigned endpoint, +- const char *bytes, int size) +-{ +- int ret; +- int loops = 5; +- u32 addr; +- if (size > DBGP_MAX_PACKET) +- return -1; +- +- addr = DBGP_EPADDR(devnum, endpoint); +-try_again: +- if (loops--) { +- ret = dbgp_out(addr, bytes, size); +- if (ret == -DBGP_ERR_BAD) { +- int try_loops = 3; +- do { +- /* Emit a dummy packet to re-sync communication +- * with the debug device */ +- if (dbgp_out(addr, "12345678", 8) >= 0) { +- udelay(2); +- goto try_again; +- } +- } while (try_loops--); +- } +- } ++ ret = dbgp_wait_until_done(ctrl); + + return ret; + } +@@ -304,7 +293,7 @@ static int dbgp_bulk_read(unsigned devnu + addr = DBGP_EPADDR(devnum, endpoint); + + pids = readl(&ehci_debug->pids); +- pids = dbgp_pid_update(pids, USB_PID_IN); ++ pids = dbgp_pid_read_update(pids, USB_PID_IN); + + ctrl = readl(&ehci_debug->control); + ctrl = dbgp_len_update(ctrl, size); +@@ -362,7 +351,6 @@ static int dbgp_control_msg(unsigned dev + return dbgp_bulk_read(devnum, 0, data, size); + } + +- + /* Find a PCI capability */ + static u32 __init find_cap(u32 num, u32 slot, u32 func, int cap) + { diff --git a/usb/usb-extend-and-neaten-dbg-macros.patch b/usb/usb-extend-and-neaten-dbg-macros.patch new file mode 100644 index 00000000000000..2f85586fa1bd30 --- /dev/null +++ b/usb/usb-extend-and-neaten-dbg-macros.patch @@ -0,0 +1,67 @@ +From joe@perches.com Wed Feb 17 14:57:12 2010 +From: Joe Perches <joe@perches.com> +Date: Fri, 05 Feb 2010 18:09:49 -0800 +Subject: USB: Extend and neaten dbg macros +To: Greg Kroah-Hartman <gregkh@suse.de> +Message-ID: <1265422189.10226.73.camel@Joe-Laptop.home> + + +Add format/argument validation for #ifndef DEBUG dbg macro +Neaten dbg macro definitions + +Signed-off-by: Joe Perches <joe@perches.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + include/linux/usb.h | 14 +++++++++----- + include/linux/usb/serial.h | 13 +++++-------- + 2 files changed, 14 insertions(+), 13 deletions(-) + +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -1565,14 +1565,18 @@ extern void usb_register_notify(struct n + extern void usb_unregister_notify(struct notifier_block *nb); + + #ifdef DEBUG +-#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \ +- __FILE__ , ## arg) ++#define dbg(format, arg...) \ ++ printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg) + #else +-#define dbg(format, arg...) do {} while (0) ++#define dbg(format, arg...) \ ++do { \ ++ if (0) \ ++ printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg); \ ++} while (0) + #endif + +-#define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \ +- format "\n" , ## arg) ++#define err(format, arg...) \ ++ printk(KERN_ERR KBUILD_MODNAME ": " format "\n", ##arg) + + /* debugfs stuff */ + extern struct dentry *usb_debug_root; +--- a/include/linux/usb/serial.h ++++ b/include/linux/usb/serial.h +@@ -351,14 +351,11 @@ static inline void usb_serial_debug_data + + /* Use our own dbg macro */ + #undef dbg +-#define dbg(format, arg...) \ +- do { \ +- if (debug) \ +- printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , \ +- ## arg); \ +- } while (0) +- +- ++#define dbg(format, arg...) \ ++do { \ ++ if (debug) \ ++ printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg); \ ++} while (0) + + #endif /* __LINUX_USB_SERIAL_H */ + diff --git a/usb/usb-serial-remove-unnecessary-n-s-from-dbg-uses.patch b/usb/usb-serial-remove-unnecessary-n-s-from-dbg-uses.patch new file mode 100644 index 00000000000000..05aed072e038d8 --- /dev/null +++ b/usb/usb-serial-remove-unnecessary-n-s-from-dbg-uses.patch @@ -0,0 +1,270 @@ +From joe@perches.com Wed Feb 17 14:49:53 2010 +From: Joe Perches <joe@perches.com> +Date: Fri, 05 Feb 2010 16:50:08 -0800 +Subject: USB: serial: Remove unnecessary \n's from dbg uses +To: Greg Kroah-Hartman <gregkh@suse.de> +Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org +Message-ID: <1265417408.10226.53.camel@Joe-Laptop.home> + + +#define dbg adds the newline, messages shouldn't. +Converted dbg("%s", "some string") to dbg("some string") + +Signed-off-by: Joe Perches <joe@perches.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/cp210x.c | 2 +- + drivers/usb/serial/cyberjack.c | 2 +- + drivers/usb/serial/ftdi_sio.c | 2 +- + drivers/usb/serial/generic.c | 2 +- + drivers/usb/serial/io_edgeport.c | 8 ++++---- + drivers/usb/serial/io_ti.c | 2 +- + drivers/usb/serial/mos7720.c | 14 +++++++------- + drivers/usb/serial/omninet.c | 2 +- + drivers/usb/serial/opticon.c | 4 ++-- + drivers/usb/serial/option.c | 4 ++-- + drivers/usb/serial/spcp8x5.c | 2 +- + drivers/usb/serial/visor.c | 4 ++-- + 12 files changed, 24 insertions(+), 24 deletions(-) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -612,7 +612,7 @@ static void cp210x_set_termios(struct tt + baud); + if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV, + ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { +- dbg("Baud rate requested not supported by device\n"); ++ dbg("Baud rate requested not supported by device"); + baud = tty_termios_baud_rate(old_termios); + } + } +--- a/drivers/usb/serial/cyberjack.c ++++ b/drivers/usb/serial/cyberjack.c +@@ -391,7 +391,7 @@ static void cyberjack_read_bulk_callback + + tty = tty_port_tty_get(&port->port); + if (!tty) { +- dbg("%s - ignoring since device not open\n", __func__); ++ dbg("%s - ignoring since device not open", __func__); + return; + } + if (urb->actual_length) { +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1836,7 +1836,7 @@ static int ftdi_write(struct tty_struct + spin_lock_irqsave(&priv->tx_lock, flags); + if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) { + spin_unlock_irqrestore(&priv->tx_lock, flags); +- dbg("%s - write limit hit\n", __func__); ++ dbg("%s - write limit hit", __func__); + return 0; + } + priv->tx_outstanding_urbs++; +--- a/drivers/usb/serial/generic.c ++++ b/drivers/usb/serial/generic.c +@@ -194,7 +194,7 @@ static int usb_serial_multi_urb_write(st + if (port->urbs_in_flight > + port->serial->type->max_in_flight_urbs) { + spin_unlock_irqrestore(&port->lock, flags); +- dbg("%s - write limit hit\n", __func__); ++ dbg("%s - write limit hit", __func__); + return bwrite; + } + port->tx_bytes_flight += towrite; +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -1971,7 +1971,7 @@ static void process_rcvd_status(struct e + return; + + case IOSP_EXT_STATUS_RX_CHECK_RSP: +- dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============\n", __func__, edge_serial->rxPort, byte3); ++ dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============", __func__, edge_serial->rxPort, byte3); + /* Port->RxCheckRsp = true; */ + return; + } +@@ -2039,7 +2039,7 @@ static void process_rcvd_status(struct e + break; + + default: +- dbg("%s - Unrecognized IOSP status code %u\n", __func__, code); ++ dbg("%s - Unrecognized IOSP status code %u", __func__, code); + break; + } + return; +@@ -2494,7 +2494,7 @@ static int calc_baud_rate_divisor(int ba + + *divisor = custom; + +- dbg("%s - Baud %d = %d\n", __func__, baudrate, custom); ++ dbg("%s - Baud %d = %d", __func__, baudrate, custom); + return 0; + } + +@@ -2879,7 +2879,7 @@ static void load_application_firmware(st + break; + + case EDGE_DOWNLOAD_FILE_NONE: +- dbg ("No download file specified, skipping download\n"); ++ dbg("No download file specified, skipping download"); + return; + + default: +--- a/drivers/usb/serial/io_ti.c ++++ b/drivers/usb/serial/io_ti.c +@@ -1716,7 +1716,7 @@ static void edge_interrupt_callback(stru + case TIUMP_INTERRUPT_CODE_MSR: /* MSR */ + /* Copy MSR from UMP */ + msr = data[1]; +- dbg("%s - ===== Port %u MSR Status = %02x ======\n", ++ dbg("%s - ===== Port %u MSR Status = %02x ======", + __func__, port_number, msr); + handle_new_msr(edge_port, msr); + break; +--- a/drivers/usb/serial/mos7720.c ++++ b/drivers/usb/serial/mos7720.c +@@ -109,7 +109,7 @@ static void mos7720_interrupt_callback(s + __u8 sp1; + __u8 sp2; + +- dbg("%s", " : Entering\n"); ++ dbg(" : Entering"); + + switch (status) { + case 0: +@@ -278,7 +278,7 @@ static void mos7720_bulk_in_callback(str + + mos7720_port = urb->context; + if (!mos7720_port) { +- dbg("%s", "NULL mos7720_port pointer \n"); ++ dbg("NULL mos7720_port pointer"); + return ; + } + +@@ -386,7 +386,7 @@ static int send_mos_cmd(struct usb_seria + } + out: + if (status < 0) +- dbg("Command Write failed Value %x index %x\n", value, index); ++ dbg("Command Write failed Value %x index %x", value, index); + + return status; + } +@@ -491,7 +491,7 @@ static int mos7720_open(struct tty_struc + */ + port_number = port->number - port->serial->minor; + send_mos_cmd(port->serial, MOS_READ, port_number, UART_LSR, &data); +- dbg("SS::%p LSR:%x\n", mos7720_port, data); ++ dbg("SS::%p LSR:%x", mos7720_port, data); + + dbg("Check:Sending Command .........."); + +@@ -830,7 +830,7 @@ static void mos7720_throttle(struct tty_ + struct moschip_port *mos7720_port; + int status; + +- dbg("%s- port %d\n", __func__, port->number); ++ dbg("%s- port %d", __func__, port->number); + + mos7720_port = usb_get_serial_port_data(port); + +@@ -1309,7 +1309,7 @@ static void mos7720_set_termios(struct t + return; + } + +- dbg("%s\n", "setting termios - ASPIRE"); ++ dbg("setting termios - ASPIRE"); + + cflag = tty->termios->c_cflag; + +@@ -1327,7 +1327,7 @@ static void mos7720_set_termios(struct t + change_port_settings(tty, mos7720_port, old_termios); + + if (!port->read_urb) { +- dbg("%s", "URB KILLED !!!!!\n"); ++ dbg("URB KILLED !!!!!"); + return; + } + +--- a/drivers/usb/serial/omninet.c ++++ b/drivers/usb/serial/omninet.c +@@ -332,7 +332,7 @@ static void omninet_write_bulk_callback( + struct usb_serial_port *port = urb->context; + int status = urb->status; + +- dbg("%s - port %0x\n", __func__, port->number); ++ dbg("%s - port %0x", __func__, port->number); + + port->write_urb_busy = 0; + if (status) { +--- a/drivers/usb/serial/opticon.c ++++ b/drivers/usb/serial/opticon.c +@@ -217,7 +217,7 @@ static int opticon_write(struct tty_stru + spin_lock_irqsave(&priv->lock, flags); + if (priv->outstanding_urbs > URB_UPPER_LIMIT) { + spin_unlock_irqrestore(&priv->lock, flags); +- dbg("%s - write limit hit\n", __func__); ++ dbg("%s - write limit hit", __func__); + return 0; + } + priv->outstanding_urbs++; +@@ -288,7 +288,7 @@ static int opticon_write_room(struct tty + spin_lock_irqsave(&priv->lock, flags); + if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) { + spin_unlock_irqrestore(&priv->lock, flags); +- dbg("%s - write limit hit\n", __func__); ++ dbg("%s - write limit hit", __func__); + return 0; + } + spin_unlock_irqrestore(&priv->lock, flags); +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1028,7 +1028,7 @@ static void option_instat_callback(struc + (struct usb_ctrlrequest *)urb->transfer_buffer; + + if (!req_pkt) { +- dbg("%s: NULL req_pkt\n", __func__); ++ dbg("%s: NULL req_pkt", __func__); + return; + } + if ((req_pkt->bRequestType == 0xA1) && +@@ -1452,7 +1452,7 @@ static int option_resume(struct usb_seri + for (i = 0; i < serial->num_ports; i++) { + port = serial->port[i]; + if (!port->interrupt_in_urb) { +- dbg("%s: No interrupt URB for port %d\n", __func__, i); ++ dbg("%s: No interrupt URB for port %d", __func__, i); + continue; + } + err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); +--- a/drivers/usb/serial/spcp8x5.c ++++ b/drivers/usb/serial/spcp8x5.c +@@ -609,7 +609,7 @@ static void spcp8x5_set_termios(struct t + if (i < 0) + dev_err(&port->dev, "Set UART format %#x failed (error = %d)\n", + uartdata, i); +- dbg("0x21:0x40:0:0 %d\n", i); ++ dbg("0x21:0x40:0:0 %d", i); + + if (cflag & CRTSCTS) { + /* enable hardware flow control */ +--- a/drivers/usb/serial/visor.c ++++ b/drivers/usb/serial/visor.c +@@ -368,7 +368,7 @@ static int visor_write(struct tty_struct + spin_lock_irqsave(&priv->lock, flags); + if (priv->outstanding_urbs > URB_UPPER_LIMIT) { + spin_unlock_irqrestore(&priv->lock, flags); +- dbg("%s - write limit hit\n", __func__); ++ dbg("%s - write limit hit", __func__); + return 0; + } + priv->outstanding_urbs++; +@@ -446,7 +446,7 @@ static int visor_write_room(struct tty_s + spin_lock_irqsave(&priv->lock, flags); + if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) { + spin_unlock_irqrestore(&priv->lock, flags); +- dbg("%s - write limit hit\n", __func__); ++ dbg("%s - write limit hit", __func__); + return 0; + } + spin_unlock_irqrestore(&priv->lock, flags); |
