diff options
73 files changed, 1473 insertions, 1768 deletions
diff --git a/Documentation/ja_JP/HOWTO b/Documentation/ja_JP/HOWTO index b2446a09087..9f08dab1e75 100644 --- a/Documentation/ja_JP/HOWTO +++ b/Documentation/ja_JP/HOWTO @@ -1,23 +1,24 @@ -NOTE: -This is Japanese translated version of "Documentation/HOWTO". -This one is maintained by Tsugikazu Shibata <tshibata@ab.jp.nec.com> -and JF Project team <www.linux.or.jp/JF>. -If you find difference with original file or problem in translation, -please contact maintainer of this file or JF project. - -Please also note that purpose of this file is easier to read for non -English natives and not to be intended to fork. So, if you have any -comments or updates of this file, please try to update Original(English) -file at first. - -Last Updated: 2007/06/04 +NOTE: +This is a version of Documentation/HOWTO translated into Japanese. +This document is maintained by Tsugikazu Shibata <tshibata@ab.jp.nec.com> +and the JF Project team <www.linux.or.jp/JF>. +If you find any difference between this document and the original file +or a problem with the translation, +please contact the maintainer of this file or JF project. + +Please also note that the purpose of this file is to be easier to read +for non English (read: Japanese) speakers and is not intended as a +fork. So if you have any comments or updates for this file, please try +to update the original English file first. + +Last Updated: 2007/07/18 ================================== これは、 -linux-2.6.21/Documentation/HOWTO +linux-2.6.22/Documentation/HOWTO の和訳です。 翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ > -翻訳日: 2007/06/04 +翻訳日: 2007/07/16 翻訳者: Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com> 校正者: 松倉さん <nbh--mats at nifty dot com> 小林 雅典さん (Masanori Kobayasi) <zap03216 at nifty dot ne dot jp> @@ -52,6 +53,7 @@ Linux カーネル開発コミュニティと共に活動するやり方を学 また、このコミュニティがなぜ今うまくまわっているのかという理由の一部も 説明しようと試みています。 + カーネルは 少量のアーキテクチャ依存部分がアセンブリ言語で書かれている 以外は大部分は C 言語で書かれています。C言語をよく理解していることはカー ネル開発者には必要です。アーキテクチャ向けの低レベル部分の開発をするの @@ -141,6 +143,7 @@ Linux カーネルソースツリーは幅広い範囲のドキュメントを これらのルールに従えばうまくいくことを保証することではありません が (すべてのパッチは内容とスタイルについて精査を受けるので)、 ルールに従わなければ間違いなくうまくいかないでしょう。 + この他にパッチを作る方法についてのよくできた記述は- "The Perfect Patch" @@ -360,44 +363,42 @@ linux-kernel メーリングリストで収集された多数のパッチと同 git ツリー- - Kbuild の開発ツリー、Sam Ravnborg <sam@ravnborg.org> - kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git + git.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git - ACPI の開発ツリー、 Len Brown <len.brown@intel.com> - kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git + git.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git - Block の開発ツリー、Jens Axboe <axboe@suse.de> - kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git + git.kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git - DRM の開発ツリー、Dave Airlie <airlied@linux.ie> - kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git + git.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git - ia64 の開発ツリー、Tony Luck <tony.luck@intel.com> - kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git - - - ieee1394 の開発ツリー、Jody McIntyre <scjody@modernduck.com> - kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git + git.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git - infiniband, Roland Dreier <rolandd@cisco.com> - kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git + git.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git - libata, Jeff Garzik <jgarzik@pobox.com> - kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git + git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git - ネットワークドライバ, Jeff Garzik <jgarzik@pobox.com> - kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git + git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git - pcmcia, Dominik Brodowski <linux@dominikbrodowski.net> - kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git + git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git - SCSI, James Bottomley <James.Bottomley@SteelEye.com> - kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git - - その他の git カーネルツリーは http://kernel.org/git に一覧表がありま - す。 + git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git quilt ツリー- - USB, PCI ドライバコアと I2C, Greg Kroah-Hartman <gregkh@suse.de> kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ + - x86-64 と i386 の仲間 Andi Kleen <ak@suse.de> + + その他のカーネルツリーは http://git.kernel.org/ と MAINTAINERS ファ + イルに一覧表があります。 バグレポート ------------- @@ -508,6 +509,7 @@ MAINTAINERS ファイルにリストがありますので参照してくださ せん*。単に自分のパッチに対して指摘された問題を全て修正して再送すれば いいのです。 + カーネルコミュニティと企業組織のちがい ----------------------------------------------------------------- @@ -577,6 +579,7 @@ Linux カーネルコミュニティは、一度に大量のコードの塊を かし、500行のパッチは、正しいことをレビューするのに数時間かかるかも しれません(時間はパッチのサイズなどにより指数関数に比例してかかりま す) + 小さいパッチは何かあったときにデバッグもとても簡単になります。パッ チを1個1個取り除くのは、とても大きなパッチを当てた後に(かつ、何かお かしくなった後で)解剖するのに比べればとても簡単です。 @@ -591,6 +594,7 @@ Linux カーネルコミュニティは、一度に大量のコードの塊を う。先生は簡潔な最高の解をみたいのです。良い生徒はこれを知って おり、そして最終解の前の中間作業を提出することは決してないので す" + カーネル開発でもこれは同じです。メンテナー達とレビューア達は、 問題を解決する解の背後になる思考プロセスをみたいとは思いません。 彼らは単純であざやかな解決方法をみたいのです。 diff --git a/Documentation/ja_JP/stable_api_nonsense.txt b/Documentation/ja_JP/stable_api_nonsense.txt index b3f2b27f088..7653b5cbfed 100644 --- a/Documentation/ja_JP/stable_api_nonsense.txt +++ b/Documentation/ja_JP/stable_api_nonsense.txt @@ -1,17 +1,17 @@ NOTE: -This is a Japanese translated version of -"Documentation/stable_api_nonsense.txt". -This one is maintained by -IKEDA, Munehiro <m-ikeda@ds.jp.nec.com> -and JF Project team <http://www.linux.or.jp/JF/>. -If you find difference with original file or problem in translation, +This is a version of Documentation/stable_api_nonsense.txt into Japanese. +This document is maintained by IKEDA, Munehiro <m-ikeda@ds.jp.nec.com> +and the JF Project team <http://www.linux.or.jp/JF/>. +If you find any difference between this document and the original file +or a problem with the translation, please contact the maintainer of this file or JF project. -Please also note that purpose of this file is easier to read for non -English natives and not to be intended to fork. So, if you have any -comments or updates of this file, please try to update -Original(English) file at first. +Please also note that the purpose of this file is to be easier to read +for non English (read: Japanese) speakers and is not intended as a +fork. So if you have any comments or updates of this file, please try +to update the original English file first. +Last Updated: 2007/07/18 ================================== これは、 linux-2.6.22-rc4/Documentation/stable_api_nonsense.txt の和訳 diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt index e44855513b3..8ee49ee7c96 100644 --- a/Documentation/kobject.txt +++ b/Documentation/kobject.txt @@ -27,7 +27,6 @@ in detail, and briefly here: - kobjects a simple object. - kset a set of objects of a certain type. - ktype a set of helpers for objects of a common type. -- subsystem a controlling object for a number of ksets. The kobject infrastructure maintains a close relationship with the @@ -54,13 +53,15 @@ embedded in larger data structures and replace fields they duplicate. 1.2 Definition struct kobject { + const char * k_name; char name[KOBJ_NAME_LEN]; - atomic_t refcount; + struct kref kref; struct list_head entry; struct kobject * parent; struct kset * kset; struct kobj_type * ktype; - struct dentry * dentry; + struct sysfs_dirent * sd; + wait_queue_head_t poll; }; void kobject_init(struct kobject *); @@ -137,8 +138,7 @@ If a kobject does not have a parent when it is registered, its parent becomes its dominant kset. If a kobject does not have a parent nor a dominant kset, its directory -is created at the top-level of the sysfs partition. This should only -happen for kobjects that are embedded in a struct subsystem. +is created at the top-level of the sysfs partition. @@ -150,10 +150,10 @@ A kset is a set of kobjects that are embedded in the same type. struct kset { - struct subsystem * subsys; struct kobj_type * ktype; struct list_head list; struct kobject kobj; + struct kset_uevent_ops * uevent_ops; }; @@ -169,8 +169,7 @@ struct kobject * kset_find_obj(struct kset *, char *); The type that the kobjects are embedded in is described by the ktype -pointer. The subsystem that the kobject belongs to is pointed to by the -subsys pointer. +pointer. A kset contains a kobject itself, meaning that it may be registered in the kobject hierarchy and exported via sysfs. More importantly, the @@ -209,6 +208,58 @@ the hierarchy. kset_find_obj() may be used to locate a kobject with a particular name. The kobject, if found, is returned. +There are also some helper functions which names point to the formerly +existing "struct subsystem", whose functions have been taken over by +ksets. + + +decl_subsys(name,type,uevent_ops) + +Declares a kset named '<name>_subsys' of type <type> with +uevent_ops <uevent_ops>. For example, + +decl_subsys(devices, &ktype_device, &device_uevent_ops); + +is equivalent to doing: + +struct kset devices_subsys = { + .kobj = { + .name = "devices", + }, + .ktype = &ktype_devices, + .uevent_ops = &device_uevent_ops, +}; + + +The objects that are registered with a subsystem that use the +subsystem's default list must have their kset ptr set properly. These +objects may have embedded kobjects or ksets. The +following helpers make setting the kset easier: + + +kobj_set_kset_s(obj,subsys) + +- Assumes that obj->kobj exists, and is a struct kobject. +- Sets the kset of that kobject to the kset <subsys>. + + +kset_set_kset_s(obj,subsys) + +- Assumes that obj->kset exists, and is a struct kset. +- Sets the kset of the embedded kobject to the kset <subsys>. + +subsys_set_kset(obj,subsys) + +- Assumes obj->subsys exists, and is a struct subsystem. +- Sets obj->subsys.kset.kobj.kset to the subsystem's embedded kset. + +void subsystem_init(struct kset *s); +int subsystem_register(struct kset *s); +void subsystem_unregister(struct kset *s); +struct kset *subsys_get(struct kset *s); +void kset_put(struct kset *s); + +These are just wrappers around the respective kset_* functions. 2.3 sysfs @@ -254,114 +305,3 @@ Instances of struct kobj_type are not registered; only referenced by the kset. A kobj_type may be referenced by an arbitrary number of ksets, as there may be disparate sets of identical objects. - - -4. subsystems - -4.1 Description - -A subsystem represents a significant entity of code that maintains an -arbitrary number of sets of objects of various types. Since the number -of ksets and the type of objects they contain are variable, a -generic representation of a subsystem is minimal. - - -struct subsystem { - struct kset kset; - struct rw_semaphore rwsem; -}; - -int subsystem_register(struct subsystem *); -void subsystem_unregister(struct subsystem *); - -struct subsystem * subsys_get(struct subsystem * s); -void subsys_put(struct subsystem * s); - - -A subsystem contains an embedded kset so: - -- It can be represented in the object hierarchy via the kset's - embedded kobject. - -- It can maintain a default list of objects of one type. - -Additional ksets may attach to the subsystem simply by referencing the -subsystem before they are registered. (This one-way reference means -that there is no way to determine the ksets that are attached to the -subsystem.) - -All ksets that are attached to a subsystem share the subsystem's R/W -semaphore. - - -4.2 subsystem Programming Interface. - -The subsystem programming interface is simple and does not offer the -flexibility that the kset and kobject programming interfaces do. They -may be registered and unregistered, as well as reference counted. Each -call forwards the calls to their embedded ksets (which forward the -calls to their embedded kobjects). - - -4.3 Helpers - -A number of macros are available to make dealing with subsystems and -their embedded objects easier. - - -decl_subsys(name,type) - -Declares a subsystem named '<name>_subsys', with an embedded kset of -type <type>. For example, - -decl_subsys(devices,&ktype_devices); - -is equivalent to doing: - -struct subsystem device_subsys = { - .kset = { - .kobj = { - .name = "devices", - }, - .ktype = &ktype_devices, - } -}; - - -The objects that are registered with a subsystem that use the -subsystem's default list must have their kset ptr set properly. These -objects may have embedded kobjects, ksets, or other subsystems. The -following helpers make setting the kset easier: - - -kobj_set_kset_s(obj,subsys) - -- Assumes that obj->kobj exists, and is a struct kobject. -- Sets the kset of that kobject to the subsystem's embedded kset. - - -kset_set_kset_s(obj,subsys) - -- Assumes that obj->kset exists, and is a struct kset. -- Sets the kset of the embedded kobject to the subsystem's - embedded kset. - -subsys_set_kset(obj,subsys) - -- Assumes obj->subsys exists, and is a struct subsystem. -- Sets obj->subsys.kset.kobj.kset to the subsystem's embedded kset. - - -4.4 sysfs - -subsystems are represented in sysfs via their embedded kobjects. They -follow the same rules as previously mentioned with no exceptions. They -typically receive a top-level directory in sysfs, except when their -embedded kobject is part of another kset, or the parent of the -embedded kobject is explicitly set. - -Note that the subsystem's embedded kset must be 'attached' to the -subsystem itself in order to use its rwsem. This is done after -kset_add() has been called. (Not before, because kset_add() uses its -subsystem for a default parent if it doesn't already have one). - diff --git a/Documentation/stable_api_nonsense.txt b/Documentation/stable_api_nonsense.txt index a2afca3b2ba..847b342b7b2 100644 --- a/Documentation/stable_api_nonsense.txt +++ b/Documentation/stable_api_nonsense.txt @@ -10,7 +10,7 @@ kernel to userspace interfaces. The kernel to userspace interface is the one that application programs use, the syscall interface. That interface is _very_ stable over time, and will not break. I have old programs that were built on a pre 0.9something kernel that still work -just fine on the latest 2.6 kernel release. This interface is the one +just fine on the latest 2.6 kernel release. That interface is the one that users and application programmers can count on being stable. diff --git a/Documentation/sysfs-rules.txt b/Documentation/sysfs-rules.txt index 42861bb0bc9..80ef562160b 100644 --- a/Documentation/sysfs-rules.txt +++ b/Documentation/sysfs-rules.txt @@ -1,19 +1,18 @@ Rules on how to access information in the Linux kernel sysfs -The kernel exported sysfs exports internal kernel implementation-details +The kernel-exported sysfs exports internal kernel implementation details and depends on internal kernel structures and layout. It is agreed upon by the kernel developers that the Linux kernel does not provide a stable internal API. As sysfs is a direct export of kernel internal -structures, the sysfs interface can not provide a stable interface eighter, +structures, the sysfs interface cannot provide a stable interface either; it may always change along with internal kernel changes. To minimize the risk of breaking users of sysfs, which are in most cases low-level userspace applications, with a new kernel release, the users -of sysfs must follow some rules to use an as abstract-as-possible way to +of sysfs must follow some rules to use an as-abstract-as-possible way to access this filesystem. The current udev and HAL programs already implement this and users are encouraged to plug, if possible, into the -abstractions these programs provide instead of accessing sysfs -directly. +abstractions these programs provide instead of accessing sysfs directly. But if you really do want or need to access sysfs directly, please follow the following rules and then your programs should work with future @@ -25,22 +24,22 @@ versions of the sysfs interface. implementation details in its own API. Therefore it is not better than reading directories and opening the files yourself. Also, it is not actively maintained, in the sense of reflecting the - current kernel-development. The goal of providing a stable interface - to sysfs has failed, it causes more problems, than it solves. It + current kernel development. The goal of providing a stable interface + to sysfs has failed; it causes more problems than it solves. It violates many of the rules in this document. - sysfs is always at /sys Parsing /proc/mounts is a waste of time. Other mount points are a system configuration bug you should not try to solve. For test cases, possibly support a SYSFS_PATH environment variable to overwrite the - applications behavior, but never try to search for sysfs. Never try + application's behavior, but never try to search for sysfs. Never try to mount it, if you are not an early boot script. - devices are only "devices" There is no such thing like class-, bus-, physical devices, interfaces, and such that you can rely on in userspace. Everything is just simply a "device". Class-, bus-, physical, ... types are just - kernel implementation details, which should not be expected by + kernel implementation details which should not be expected by applications that look for devices in sysfs. The properties of a device are: @@ -48,11 +47,11 @@ versions of the sysfs interface. - identical to the DEVPATH value in the event sent from the kernel at device creation and removal - the unique key to the device at that point in time - - the kernels path to the device-directory without the leading + - the kernel's path to the device directory without the leading /sys, and always starting with with a slash - all elements of a devpath must be real directories. Symlinks pointing to /sys/devices must always be resolved to their real - target, and the target path must be used to access the device. + target and the target path must be used to access the device. That way the devpath to the device matches the devpath of the kernel used at event time. - using or exposing symlink values as elements in a devpath string @@ -73,17 +72,17 @@ versions of the sysfs interface. link - it is retrieved by reading the "driver"-link and using only the last element of the target path - - devices which do not have "driver"-link, just do not have a - driver; copying the driver value in a child device context, is a + - devices which do not have "driver"-link just do not have a + driver; copying the driver value in a child device context is a bug in the application o attributes - - the files in the device directory or files below a subdirectories + - the files in the device directory or files below subdirectories of the same device directory - accessing attributes reached by a symlink pointing to another device, like the "device"-link, is a bug in the application - Everything else is just a kernel driver-core implementation detail, + Everything else is just a kernel driver-core implementation detail that should not be assumed to be stable across kernel releases. - Properties of parent devices never belong into a child device. @@ -91,25 +90,25 @@ versions of the sysfs interface. context properties. If the device 'eth0' or 'sda' does not have a "driver"-link, then this device does not have a driver. Its value is empty. Never copy any property of the parent-device into a child-device. Parent - device-properties may change dynamically without any notice to the + device properties may change dynamically without any notice to the child device. -- Hierarchy in a single device-tree +- Hierarchy in a single device tree There is only one valid place in sysfs where hierarchy can be examined and this is below: /sys/devices. - It is planned, that all device directories will end up in the tree + It is planned that all device directories will end up in the tree below this directory. - Classification by subsystem There are currently three places for classification of devices: /sys/block, /sys/class and /sys/bus. It is planned that these will - not contain any device-directories themselves, but only flat lists of + not contain any device directories themselves, but only flat lists of symlinks pointing to the unified /sys/devices tree. All three places have completely different rules on how to access device information. It is planned to merge all three - classification-directories into one place at /sys/subsystem, - following the layout of the bus-directories. All buses and - classes, including the converted block-subsystem, will show up + classification directories into one place at /sys/subsystem, + following the layout of the bus directories. All buses and + classes, including the converted block subsystem, will show up there. The devices belonging to a subsystem will create a symlink in the "devices" directory at /sys/subsystem/<name>/devices. @@ -121,38 +120,38 @@ versions of the sysfs interface. subsystem name. Assuming /sys/class/<subsystem> and /sys/bus/<subsystem>, or - /sys/block and /sys/class/block are not interchangeable, is a bug in + /sys/block and /sys/class/block are not interchangeable is a bug in the application. - Block - The converted block-subsystem at /sys/class/block, or + The converted block subsystem at /sys/class/block or /sys/subsystem/block will contain the links for disks and partitions - at the same level, never in a hierarchy. Assuming the block-subsytem to - contain only disks and not partition-devices in the same flat list is + at the same level, never in a hierarchy. Assuming the block subsytem to + contain only disks and not partition devices in the same flat list is a bug in the application. - "device"-link and <subsystem>:<kernel name>-links Never depend on the "device"-link. The "device"-link is a workaround - for the old layout, where class-devices are not created in - /sys/devices/ like the bus-devices. If the link-resolving of a - device-directory does not end in /sys/devices/, you can use the + for the old layout, where class devices are not created in + /sys/devices/ like the bus devices. If the link-resolving of a + device directory does not end in /sys/devices/, you can use the "device"-link to find the parent devices in /sys/devices/. That is the - single valid use of the "device"-link, it must never appear in any + single valid use of the "device"-link; it must never appear in any path as an element. Assuming the existence of the "device"-link for a device in /sys/devices/ is a bug in the application. Accessing /sys/class/net/eth0/device is a bug in the application. Never depend on the class-specific links back to the /sys/class directory. These links are also a workaround for the design mistake - that class-devices are not created in /sys/devices. If a device + that class devices are not created in /sys/devices. If a device directory does not contain directories for child devices, these links may be used to find the child devices in /sys/class. That is the single - valid use of these links, they must never appear in any path as an + valid use of these links; they must never appear in any path as an element. Assuming the existence of these links for devices which are - real child device directories in the /sys/devices tree, is a bug in + real child device directories in the /sys/devices tree is a bug in the application. - It is planned to remove all these links when when all class-device + It is planned to remove all these links when all class device directories live in /sys/devices. - Position of devices along device chain can change. @@ -161,6 +160,5 @@ versions of the sysfs interface. the chain. You must always request the parent device you are looking for by its subsystem value. You need to walk up the chain until you find the device that matches the expected subsystem. Depending on a specific - position of a parent device, or exposing relative paths, using "../" to - access the chain of parents, is a bug in the application. - + position of a parent device or exposing relative paths using "../" to + access the chain of parents is a bug in the application. diff --git a/MAINTAINERS b/MAINTAINERS index babd00b0c65..5c784be00b5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3674,11 +3674,9 @@ W: http://www.auk.cx/tms380tr/ S: Maintained TULIP NETWORK DRIVER -P: Valerie Henson -M: val@nmt.edu L: tulip-users@lists.sourceforge.net W: http://sourceforge.net/projects/tulip/ -S: Maintained +S: Orphan TUN/TAP driver P: Maxim Krasnyansky diff --git a/drivers/base/core.c b/drivers/base/core.c index 3599ab2506d..e6738bcbe5a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -24,8 +24,6 @@ #include "base.h" #include "power/power.h" -extern const char *kobject_actions[]; - int (*platform_notify)(struct device * dev) = NULL; int (*platform_notify_remove)(struct device * dev) = NULL; @@ -680,8 +678,7 @@ static int device_add_class_symlinks(struct device *dev) if (error) goto out_subsys; } - /* only bus-device parents get a "device"-link */ - if (dev->parent && dev->parent->bus) { + if (dev->parent) { error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); if (error) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 53f0ee6f301..b24efd4e3e3 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -232,6 +232,7 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) /** * firmware_data_write - write method for firmware * @kobj: kobject for the device + * @bin_attr: bin_attr structure * @buffer: buffer being written * @offset: buffer offset for write in total data store area * @count: buffer size diff --git a/drivers/infiniband/hw/amso1100/c2_qp.c b/drivers/infiniband/hw/amso1100/c2_qp.c index 420c1380f5c..01d07862ea8 100644 --- a/drivers/infiniband/hw/amso1100/c2_qp.c +++ b/drivers/infiniband/hw/amso1100/c2_qp.c @@ -506,6 +506,7 @@ int c2_alloc_qp(struct c2_dev *c2dev, qp->send_sgl_depth = qp_attrs->cap.max_send_sge; qp->rdma_write_sgl_depth = qp_attrs->cap.max_send_sge; qp->recv_sgl_depth = qp_attrs->cap.max_recv_sge; + init_waitqueue_head(&qp->wait); /* Initialize the SQ MQ */ q_size = be32_to_cpu(reply->sq_depth); diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h index 3725aa8664d..b5e96030531 100644 --- a/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/drivers/infiniband/hw/ehca/ehca_classes.h @@ -322,6 +322,7 @@ extern int ehca_static_rate; extern int ehca_port_act_time; extern int ehca_use_hp_mr; extern int ehca_scaling_code; +extern int ehca_mr_largepage; struct ipzu_queue_resp { u32 qe_size; /* queue entry size */ diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c index c1b868b79d6..d97eda3e1da 100644 --- a/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c @@ -40,10 +40,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <rdma/ib_umem.h> - #include <asm/current.h> +#include <rdma/ib_umem.h> + #include "ehca_iverbs.h" #include "ehca_mrmw.h" #include "hcp_if.h" @@ -64,8 +64,6 @@ enum ehca_mr_pgsize { EHCA_MR_PGSIZE16M = 0x1000000L }; -extern int ehca_mr_largepage; - static u32 ehca_encode_hwpage_size(u32 pgsize) { u32 idx = 0; diff --git a/drivers/infiniband/hw/ehca/ehca_pd.c b/drivers/infiniband/hw/ehca/ehca_pd.c index 3dafd7ff36c..43bcf085fcf 100644 --- a/drivers/infiniband/hw/ehca/ehca_pd.c +++ b/drivers/infiniband/hw/ehca/ehca_pd.c @@ -88,7 +88,6 @@ int ehca_dealloc_pd(struct ib_pd *pd) u32 cur_pid = current->tgid; struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd); int i, leftovers = 0; - extern struct kmem_cache *small_qp_cache; struct ipz_small_queue_page *page, *tmp; if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c index fdbfebea7d1..24f454162f2 100644 --- a/drivers/infiniband/hw/ehca/hcp_if.c +++ b/drivers/infiniband/hw/ehca/hcp_if.c @@ -758,7 +758,6 @@ u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle, const u64 logical_address_of_page, const u64 count) { - extern int ehca_debug_level; u64 ret; if (unlikely(ehca_debug_level >= 2)) { diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.h b/drivers/infiniband/hw/ehca/ipz_pt_fn.h index c6937a044e8..a801274ea33 100644 --- a/drivers/infiniband/hw/ehca/ipz_pt_fn.h +++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.h @@ -54,6 +54,8 @@ struct ehca_pd; struct ipz_small_queue_page; +extern struct kmem_cache *small_qp_cache; + /* struct generic ehca page */ struct ipz_page { u8 entries[EHCA_PAGESIZE]; diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h index b4b786d0dfc..6ad822c3593 100644 --- a/drivers/infiniband/hw/ipath/ipath_common.h +++ b/drivers/infiniband/hw/ipath/ipath_common.h @@ -100,8 +100,7 @@ struct infinipath_stats { __u64 sps_hwerrs; /* number of times IB link changed state unexpectedly */ __u64 sps_iblink; - /* kernel receive interrupts that didn't read intstat */ - __u64 sps_fastrcvint; + __u64 sps_unused; /* was fastrcvint, no longer implemented */ /* number of kernel (port0) packets received */ __u64 sps_port0pkts; /* number of "ethernet" packets sent by driver */ diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 09c5fd84b1e..6ccba365a24 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c @@ -740,7 +740,7 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first, * pioavail updates to memory to stop. */ ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, - sendorig & ~IPATH_S_PIOBUFAVAILUPD); + sendorig & ~INFINIPATH_S_PIOBUFAVAILUPD); sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); @@ -1614,7 +1614,7 @@ int ipath_waitfor_mdio_cmdready(struct ipath_devdata *dd) * it's safer to always do it. * PIOAvail bits are updated by the chip as if normal send had happened. */ -void ipath_cancel_sends(struct ipath_devdata *dd) +void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl) { ipath_dbg("Cancelling all in-progress send buffers\n"); dd->ipath_lastcancel = jiffies+HZ/2; /* skip armlaunch errs a bit */ @@ -1627,6 +1627,9 @@ void ipath_cancel_sends(struct ipath_devdata *dd) ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); ipath_disarm_piobufs(dd, 0, (unsigned)(dd->ipath_piobcnt2k + dd->ipath_piobcnt4k)); + if (restore_sendctrl) /* else done by caller later */ + ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, + dd->ipath_sendctrl); /* and again, be sure all have hit the chip */ ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); @@ -1655,7 +1658,7 @@ static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which) /* flush all queued sends when going to DOWN or INIT, to be sure that * they don't block MAD packets */ if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT) - ipath_cancel_sends(dd); + ipath_cancel_sends(dd, 1); ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, dd->ipath_ibcctrl | which); @@ -2000,7 +2003,7 @@ void ipath_shutdown_device(struct ipath_devdata *dd) ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE << INFINIPATH_IBCC_LINKINITCMD_SHIFT); - ipath_cancel_sends(dd); + ipath_cancel_sends(dd, 0); /* disable IBC */ dd->ipath_control &= ~INFINIPATH_C_LINKENABLE; diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c index 9868ccda5f2..5b6ac9a1a70 100644 --- a/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ b/drivers/infiniband/hw/ipath/ipath_iba6120.c @@ -321,6 +321,8 @@ static const struct ipath_hwerror_msgs ipath_6120_hwerror_msgs[] = { << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) static int ipath_pe_txe_recover(struct ipath_devdata *); +static void ipath_pe_put_tid_2(struct ipath_devdata *, u64 __iomem *, + u32, unsigned long); /** * ipath_pe_handle_hwerrors - display hardware errors. @@ -555,8 +557,11 @@ static int ipath_pe_boardname(struct ipath_devdata *dd, char *name, ipath_dev_err(dd, "Unsupported InfiniPath hardware revision %u.%u!\n", dd->ipath_majrev, dd->ipath_minrev); ret = 1; - } else + } else { ret = 0; + if (dd->ipath_minrev >= 2) + dd->ipath_f_put_tid = ipath_pe_put_tid_2; + } return ret; } @@ -1220,7 +1225,7 @@ static void ipath_pe_clear_tids(struct ipath_devdata *dd, unsigned port) port * dd->ipath_rcvtidcnt * sizeof(*tidbase)); for (i = 0; i < dd->ipath_rcvtidcnt; i++) - ipath_pe_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED, + dd->ipath_f_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED, tidinv); tidbase = (u64 __iomem *) @@ -1229,7 +1234,7 @@ static void ipath_pe_clear_tids(struct ipath_devdata *dd, unsigned port) port * dd->ipath_rcvegrcnt * sizeof(*tidbase)); for (i = 0; i < dd->ipath_rcvegrcnt; i++) - ipath_pe_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER, + dd->ipath_f_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER, tidinv); } @@ -1395,10 +1400,11 @@ void ipath_init_iba6120_funcs(struct ipath_devdata *dd) dd->ipath_f_quiet_serdes = ipath_pe_quiet_serdes; dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes; dd->ipath_f_clear_tids = ipath_pe_clear_tids; - if (dd->ipath_minrev >= 2) - dd->ipath_f_put_tid = ipath_pe_put_tid_2; - else - dd->ipath_f_put_tid = ipath_pe_put_tid; + /* + * this may get changed after we read the chip revision, + * but we start with the safe version for all revs + */ + dd->ipath_f_put_tid = ipath_pe_put_tid; dd->ipath_f_cleanup = ipath_setup_pe_cleanup; dd->ipath_f_setextled = ipath_setup_pe_setextled; dd->ipath_f_get_base_info = ipath_pe_get_base_info; diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c index 49951d58380..9dd0bacf846 100644 --- a/drivers/infiniband/hw/ipath/ipath_init_chip.c +++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c @@ -782,7 +782,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) * Follows early_init because some chips have to initialize * PIO buffers in early_init to avoid false parity errors. */ - ipath_cancel_sends(dd); + ipath_cancel_sends(dd, 0); /* early_init sets rcvhdrentsize and rcvhdrsize, so this must be * done after early_init */ @@ -851,13 +851,14 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, dd->ipath_hwerrmask); - dd->ipath_maskederrs = dd->ipath_ignorederrs; /* clear all */ ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, -1LL); /* enable errors that are masked, at least this first time. */ ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, ~dd->ipath_maskederrs); - /* clear any interrups up to this point (ints still not enabled) */ + dd->ipath_errormask = ipath_read_kreg64(dd, + dd->ipath_kregs->kr_errormask); + /* clear any interrupts up to this point (ints still not enabled) */ ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, -1LL); /* diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c index 1fd91c59f24..b29fe7e9b11 100644 --- a/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/drivers/infiniband/hw/ipath/ipath_intr.c @@ -303,7 +303,7 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd, * Flush all queued sends when link went to DOWN or INIT, * to be sure that they don't block SMA and other MAD packets */ - ipath_cancel_sends(dd); + ipath_cancel_sends(dd, 1); } else if (lstate == IPATH_IBSTATE_INIT || lstate == IPATH_IBSTATE_ARM || lstate == IPATH_IBSTATE_ACTIVE) { @@ -517,10 +517,7 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) supp_msgs = handle_frequent_errors(dd, errs, msg, &noprint); - /* - * don't report errors that are masked (includes those always - * ignored) - */ + /* don't report errors that are masked */ errs &= ~dd->ipath_maskederrs; /* do these first, they are most important */ @@ -566,19 +563,19 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) * ones on this particular interrupt, which also isn't great */ dd->ipath_maskederrs |= dd->ipath_lasterror | errs; + dd->ipath_errormask &= ~dd->ipath_maskederrs; ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, - ~dd->ipath_maskederrs); + dd->ipath_errormask); s_iserr = ipath_decode_err(msg, sizeof msg, - (dd->ipath_maskederrs & ~dd-> - ipath_ignorederrs)); + dd->ipath_maskederrs); - if ((dd->ipath_maskederrs & ~dd->ipath_ignorederrs) & + if (dd->ipath_maskederrs & ~(INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL | INFINIPATH_E_PKTERRS)) ipath_dev_err(dd, "Temporarily disabling " "error(s) %llx reporting; too frequent (%s)\n", - (unsigned long long) (dd->ipath_maskederrs & - ~dd->ipath_ignorederrs), msg); + (unsigned long long)dd->ipath_maskederrs, + msg); else { /* * rcvegrfull and rcvhdrqfull are "normal", @@ -793,19 +790,22 @@ void ipath_clear_freeze(struct ipath_devdata *dd) /* disable error interrupts, to avoid confusion */ ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 0ULL); + /* also disable interrupts; errormask is sometimes overwriten */ + ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, 0ULL); + /* * clear all sends, because they have may been * completed by usercode while in freeze mode, and * therefore would not be sent, and eventually * might cause the process to run out of bufs */ - ipath_cancel_sends(dd); + ipath_cancel_sends(dd, 0); ipath_write_kreg(dd, dd->ipath_kregs->kr_control, dd->ipath_control); /* ensure pio avail updates continue */ ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, - dd->ipath_sendctrl & ~IPATH_S_PIOBUFAVAILUPD); + dd->ipath_sendctrl & ~INFINIPATH_S_PIOBUFAVAILUPD); ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); @@ -817,7 +817,7 @@ void ipath_clear_freeze(struct ipath_devdata *dd) for (i = 0; i < dd->ipath_pioavregs; i++) { /* deal with 6110 chip bug */ im = i > 3 ? ((i&1) ? i-1 : i+1) : i; - val = ipath_read_kreg64(dd, 0x1000+(im*sizeof(u64))); + val = ipath_read_kreg64(dd, (0x1000/sizeof(u64))+im); dd->ipath_pioavailregs_dma[i] = dd->ipath_pioavailshadow[i] = le64_to_cpu(val); } @@ -832,7 +832,8 @@ void ipath_clear_freeze(struct ipath_devdata *dd) ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, E_SPKT_ERRS_IGNORE); ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, - ~dd->ipath_maskederrs); + dd->ipath_errormask); + ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, -1LL); ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, 0ULL); } @@ -1002,7 +1003,6 @@ irqreturn_t ipath_intr(int irq, void *data) u32 istat, chk0rcv = 0; ipath_err_t estat = 0; irqreturn_t ret; - u32 oldhead, curtail; static unsigned unexpected = 0; static const u32 port0rbits = (1U<<INFINIPATH_I_RCVAVAIL_SHIFT) | (1U<<INFINIPATH_I_RCVURG_SHIFT); @@ -1035,36 +1035,6 @@ irqreturn_t ipath_intr(int irq, void *data) goto bail; } - /* - * We try to avoid reading the interrupt status register, since - * that's a PIO read, and stalls the processor for up to about - * ~0.25 usec. The idea is that if we processed a port0 packet, - * we blindly clear the port 0 receive interrupt bits, and nothing - * else, then return. If other interrupts are pending, the chip - * will re-interrupt us as soon as we write the intclear register. - * We then won't process any more kernel packets (if not the 2nd - * time, then the 3rd or 4th) and we'll then handle the other - * interrupts. We clear the interrupts first so that we don't - * lose intr for later packets that arrive while we are processing. - */ - oldhead = dd->ipath_port0head; - curtail = (u32)le64_to_cpu(*dd->ipath_hdrqtailptr); - if (oldhead != curtail) { - if (dd->ipath_flags & IPATH_GPIO_INTR) { - ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear, - (u64) (1 << IPATH_GPIO_PORT0_BIT)); - istat = port0rbits | INFINIPATH_I_GPIO; - } - else - istat = port0rbits; - ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat); - ipath_kreceive(dd); - if (oldhead != dd->ipath_port0head) { - ipath_stats.sps_fastrcvint++; - goto done; - } - } - istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus); if (unlikely(!istat)) { @@ -1225,7 +1195,6 @@ irqreturn_t ipath_intr(int irq, void *data) handle_layer_pioavail(dd); } -done: ret = IRQ_HANDLED; bail: diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index ace63ef78e6..7a7966f7e4f 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h @@ -261,18 +261,10 @@ struct ipath_devdata { * limiting of hwerror reporting */ ipath_err_t ipath_lasthwerror; - /* - * errors masked because they occur too fast, also includes errors - * that are always ignored (ipath_ignorederrs) - */ + /* errors masked because they occur too fast */ ipath_err_t ipath_maskederrs; /* time in jiffies at which to re-enable maskederrs */ unsigned long ipath_unmasktime; - /* - * errors always ignored (masked), at least for a given - * chip/device, because they are wrong or not useful - */ - ipath_err_t ipath_ignorederrs; /* count of egrfull errors, combined for all ports */ u64 ipath_last_tidfull; /* for ipath_qcheck() */ @@ -436,6 +428,7 @@ struct ipath_devdata { u64 ipath_lastibcstat; /* hwerrmask shadow */ ipath_err_t ipath_hwerrmask; + ipath_err_t ipath_errormask; /* errormask shadow */ /* interrupt config reg shadow */ u64 ipath_intconfig; /* kr_sendpiobufbase value */ @@ -683,7 +676,7 @@ int ipath_unordered_wc(void); void ipath_disarm_piobufs(struct ipath_devdata *, unsigned first, unsigned cnt); -void ipath_cancel_sends(struct ipath_devdata *); +void ipath_cancel_sends(struct ipath_devdata *, int); int ipath_create_rcvhdrq(struct ipath_devdata *, struct ipath_portdata *); void ipath_free_pddata(struct ipath_devdata *, struct ipath_portdata *); diff --git a/drivers/infiniband/hw/ipath/ipath_stats.c b/drivers/infiniband/hw/ipath/ipath_stats.c index 73ed17d0318..bae4f56f727 100644 --- a/drivers/infiniband/hw/ipath/ipath_stats.c +++ b/drivers/infiniband/hw/ipath/ipath_stats.c @@ -196,6 +196,45 @@ static void ipath_qcheck(struct ipath_devdata *dd) } } +static void ipath_chk_errormask(struct ipath_devdata *dd) +{ + static u32 fixed; + u32 ctrl; + unsigned long errormask; + unsigned long hwerrs; + + if (!dd->ipath_errormask || !(dd->ipath_flags & IPATH_INITTED)) + return; + + errormask = ipath_read_kreg64(dd, dd->ipath_kregs->kr_errormask); + + if (errormask == dd->ipath_errormask) + return; + fixed++; + + hwerrs = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus); + ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control); + + ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, + dd->ipath_errormask); + + if ((hwerrs & dd->ipath_hwerrmask) || + (ctrl & INFINIPATH_C_FREEZEMODE)) { + /* force re-interrupt of pending events, just in case */ + ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, 0ULL); + ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, 0ULL); + ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, 0ULL); + dev_info(&dd->pcidev->dev, + "errormask fixed(%u) %lx -> %lx, ctrl %x hwerr %lx\n", + fixed, errormask, (unsigned long)dd->ipath_errormask, + ctrl, hwerrs); + } else + ipath_dbg("errormask fixed(%u) %lx -> %lx, no freeze\n", + fixed, errormask, + (unsigned long)dd->ipath_errormask); +} + + /** * ipath_get_faststats - get word counters from chip before they overflow * @opaque - contains a pointer to the infinipath device ipath_devdata @@ -251,14 +290,13 @@ void ipath_get_faststats(unsigned long opaque) dd->ipath_lasterror = 0; if (dd->ipath_lasthwerror) dd->ipath_lasthwerror = 0; - if ((dd->ipath_maskederrs & ~dd->ipath_ignorederrs) + if (dd->ipath_maskederrs && time_after(jiffies, dd->ipath_unmasktime)) { char ebuf[256]; int iserr; iserr = ipath_decode_err(ebuf, sizeof ebuf, - (dd->ipath_maskederrs & ~dd-> - ipath_ignorederrs)); - if ((dd->ipath_maskederrs & ~dd->ipath_ignorederrs) & + dd->ipath_maskederrs); + if (dd->ipath_maskederrs & ~(INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL | INFINIPATH_E_PKTERRS )) ipath_dev_err(dd, "Re-enabling masked errors " @@ -278,9 +316,12 @@ void ipath_get_faststats(unsigned long opaque) ipath_cdbg(ERRPKT, "Re-enabling packet" " problem interrupt (%s)\n", ebuf); } - dd->ipath_maskederrs = dd->ipath_ignorederrs; + + /* re-enable masked errors */ + dd->ipath_errormask |= dd->ipath_maskederrs; ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, - ~dd->ipath_maskederrs); + dd->ipath_errormask); + dd->ipath_maskederrs = 0; } /* limit qfull messages to ~one per minute per port */ @@ -294,6 +335,7 @@ void ipath_get_faststats(unsigned long opaque) } } + ipath_chk_errormask(dd); done: mod_timer(&dd->ipath_stats_timer, jiffies + HZ * 5); } diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index f6315dfb213..ba0428d872a 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -1209,7 +1209,6 @@ static void set_datagram_seg(struct mlx4_wqe_datagram_seg *dseg, memcpy(dseg->av, &to_mah(wr->wr.ud.ah)->av, sizeof (struct mlx4_av)); dseg->dqpn = cpu_to_be32(wr->wr.ud.remote_qpn); dseg->qkey = cpu_to_be32(wr->wr.ud.remote_qkey); - } static void set_data_seg(struct mlx4_wqe_data_seg *dseg, diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c index 7195c946152..b1a9c4cdec9 100644 --- a/drivers/media/dvb/dvb-usb/af9005-fe.c +++ b/drivers/media/dvb/dvb-usb/af9005-fe.c @@ -29,8 +29,6 @@ struct af9005_fe_state { struct dvb_usb_device *d; - struct dvb_frontend *tuner; - fe_status_t stat; /* retraining parameters */ @@ -345,8 +343,8 @@ static int af9005_reset_pre_viterbi(struct dvb_frontend *fe) 1 & 0xff); if (ret) return ret; - af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8, - 1 >> 8); + ret = af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8, + 1 >> 8); if (ret) return ret; /* reset pre viterbi error count */ @@ -447,7 +445,7 @@ static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat) u8 temp; int ret; - if (state->tuner == NULL) + if (fe->ops.tuner_ops.release == NULL) return -ENODEV; *stat = 0; @@ -493,7 +491,7 @@ static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat) static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber) { struct af9005_fe_state *state = fe->demodulator_priv; - if (state->tuner == NULL) + if (fe->ops.tuner_ops.release == NULL) return -ENODEV; af9005_fe_refresh_state(fe); *ber = state->ber; @@ -503,7 +501,7 @@ static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber) static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) { struct af9005_fe_state *state = fe->demodulator_priv; - if (state->tuner == NULL) + if (fe->ops.tuner_ops.release == NULL) return -ENODEV; af9005_fe_refresh_state(fe); *unc = state->unc; @@ -517,7 +515,7 @@ static int af9005_fe_read_signal_strength(struct dvb_frontend *fe, int ret; u8 if_gain, rf_gain; - if (state->tuner == NULL) + if (fe->ops.tuner_ops.release == NULL) return -ENODEV; ret = af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain, @@ -881,10 +879,8 @@ static int af9005_fe_init(struct dvb_frontend *fe) af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst, reg_ofdm_rst_pos, reg_ofdm_rst_len, 1))) return ret; - if ((ret = - af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst, - reg_ofdm_rst_pos, reg_ofdm_rst_len, 0))) - return ret; + ret = af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst, + reg_ofdm_rst_pos, reg_ofdm_rst_len, 0); if (ret) return ret; @@ -1041,7 +1037,7 @@ static int af9005_fe_init(struct dvb_frontend *fe) return ret; /* attach tuner and init */ - if (state->tuner == NULL) { + if (fe->ops.tuner_ops.release == NULL) { /* read tuner and board id from eeprom */ ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2); if (ret) { @@ -1058,20 +1054,16 @@ static int af9005_fe_init(struct dvb_frontend *fe) return ret; } if1 = (u16) (buf[0] << 8) + buf[1]; - state->tuner = - dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap, - &af9005_mt2060_config, if1); - if (state->tuner == NULL) { + if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap, + &af9005_mt2060_config, if1) == NULL) { deb_info("MT2060 attach failed\n"); return -ENODEV; } break; case 3: /* QT1010 */ case 9: /* QT1010B */ - state->tuner = - dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap, - &af9005_qt1010_config); - if (state->tuner == NULL) { + if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap, + &af9005_qt1010_config) ==NULL) { deb_info("QT1010 attach failed\n"); return -ENODEV; } @@ -1080,7 +1072,7 @@ static int af9005_fe_init(struct dvb_frontend *fe) err("Unsupported tuner type %d", buf[0]); return -ENODEV; } - ret = state->tuner->ops.tuner_ops.init(state->tuner); + ret = fe->ops.tuner_ops.init(fe); if (ret) return ret; } @@ -1118,7 +1110,7 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe, deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency, fep->u.ofdm.bandwidth); - if (state->tuner == NULL) { + if (fe->ops.tuner_ops.release == NULL) { err("Tuner not attached"); return -ENODEV; } @@ -1199,7 +1191,7 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe, return ret; /* set tuner */ deb_info("set tuner\n"); - ret = state->tuner->ops.tuner_ops.set_params(state->tuner, fep); + ret = fe->ops.tuner_ops.set_params(fe, fep); if (ret) return ret; @@ -1435,12 +1427,6 @@ static void af9005_fe_release(struct dvb_frontend *fe) { struct af9005_fe_state *state = (struct af9005_fe_state *)fe->demodulator_priv; - if (state->tuner != NULL && state->tuner->ops.tuner_ops.release != NULL) { - state->tuner->ops.tuner_ops.release(state->tuner); -#ifdef CONFIG_DVB_CORE_ATTACH - symbol_put_addr(state->tuner->ops.tuner_ops.release); -#endif - } kfree(state); } @@ -1458,7 +1444,6 @@ struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d) deb_info("attaching frontend af9005\n"); state->d = d; - state->tuner = NULL; state->opened = 0; memcpy(&state->frontend.ops, &af9005_fe_ops, diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 0c0b94767bc..ca99e439c97 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c @@ -501,7 +501,7 @@ static struct dvb_pll_desc dvb_pll_opera1 = { /* Philips FCV1236D */ -struct dvb_pll_desc dvb_pll_fcv1236d = { +static struct dvb_pll_desc dvb_pll_fcv1236d = { /* Bit_0: RF Input select * Bit_1: 0=digital, 1=analog */ diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 387cb2122d4..f6715007d40 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -33,6 +33,7 @@ #include <linux/pci.h> #include <linux/vmalloc.h> #include <linux/firmware.h> +#include <net/checksum.h> #include <asm/io.h> @@ -45,7 +46,7 @@ static void boot_msp34xx(struct bttv *btv, int pin); static void boot_bt832(struct bttv *btv); static void hauppauge_eeprom(struct bttv *btv); static void avermedia_eeprom(struct bttv *btv); -static void osprey_eeprom(struct bttv *btv); +static void osprey_eeprom(struct bttv *btv, const u8 ee[256]); static void modtec_eeprom(struct bttv *btv); static void init_PXC200(struct bttv *btv); static void init_RTV24(struct bttv *btv); @@ -2843,13 +2844,28 @@ struct tvcard bttv_tvcards[] = { .has_remote = 1, }, /* ---- card 0x8c ---------------------------------- */ + /* Has four Bt878 chips behind a PCI bridge, each chip has: + one external BNC composite input (mux 2) + three internal composite inputs (unknown muxes) + an 18-bit stereo A/D (CS5331A), which has: + one external stereo unblanced (RCA) audio connection + one (or 3?) internal stereo balanced (XLR) audio connection + input is selected via gpio to a 14052B mux + (mask=0x300, unbal=0x000, bal=0x100, ??=0x200,0x300) + gain is controlled via an X9221A chip on the I2C bus @0x28 + sample rate is controlled via gpio to an MK1413S + (mask=0x3, 32kHz=0x0, 44.1kHz=0x1, 48kHz=0x2, ??=0x3) + There is neither a tuner nor an svideo input. */ [BTTV_BOARD_OSPREY440] = { .name = "Osprey 440", - .video_inputs = 1, - .audio_inputs = 1, + .video_inputs = 4, + .audio_inputs = 2, /* this is meaningless */ .tuner = UNSET, - .svhs = 1, - .muxsel = { 2 }, + .svhs = UNSET, + .muxsel = { 2, 3, 0, 1 }, /* 3,0,1 are guesses */ + .gpiomask = 0x303, + .gpiomute = 0x000, /* int + 32kHz */ + .gpiomux = { 0, 0, 0x000, 0x100}, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -3453,11 +3469,12 @@ void __devinit bttv_init_card2(struct bttv *btv) case BTTV_BOARD_OSPREY2xx: case BTTV_BOARD_OSPREY2x0_SVID: case BTTV_BOARD_OSPREY2x0: + case BTTV_BOARD_OSPREY440: case BTTV_BOARD_OSPREY500: case BTTV_BOARD_OSPREY540: case BTTV_BOARD_OSPREY2000: bttv_readee(btv,eeprom_data,0xa0); - osprey_eeprom(btv); + osprey_eeprom(btv, eeprom_data); break; case BTTV_BOARD_IDS_EAGLE: init_ids_eagle(btv); @@ -3748,106 +3765,119 @@ static int __devinit pvr_boot(struct bttv *btv) /* ----------------------------------------------------------------------- */ /* some osprey specific stuff */ -static void __devinit osprey_eeprom(struct bttv *btv) +static void __devinit osprey_eeprom(struct bttv *btv, const u8 ee[256]) { - int i = 0; - unsigned char *ee = eeprom_data; - unsigned long serial = 0; - - if (btv->c.type == 0) { - /* this might be an antique... check for MMAC label in eeprom */ - if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) { - unsigned char checksum = 0; - for (i = 0; i < 21; i++) - checksum += ee[i]; - if (checksum != ee[21]) - return; - btv->c.type = BTTV_BOARD_OSPREY1x0_848; - for (i = 12; i < 21; i++) - serial *= 10, serial += ee[i] - '0'; - } + int i; + u32 serial = 0; + int cardid = -1; + + /* This code will nevery actually get called in this case.... */ + if (btv->c.type == BTTV_BOARD_UNKNOWN) { + /* this might be an antique... check for MMAC label in eeprom */ + if (!strncmp(ee, "MMAC", 4)) { + u8 checksum = 0; + for (i = 0; i < 21; i++) + checksum += ee[i]; + if (checksum != ee[21]) + return; + cardid = BTTV_BOARD_OSPREY1x0_848; + for (i = 12; i < 21; i++) + serial *= 10, serial += ee[i] - '0'; + } } else { - unsigned short type; - int offset = 4*16; - - for (; offset < 8*16; offset += 16) { - unsigned short checksum = 0; - /* verify the checksum */ - for (i = 0; i < 14; i++) - checksum += ee[i+offset]; - checksum = ~checksum; /* no idea why */ - if ((((checksum>>8)&0x0FF) == ee[offset+14]) && - ((checksum & 0x0FF) == ee[offset+15])) { - break; - } - } - - if (offset >= 8*16) - return; - - /* found a valid descriptor */ - type = (ee[offset+4]<<8) | (ee[offset+5]); - - switch(type) { - /* 848 based */ - case 0x0004: - btv->c.type = BTTV_BOARD_OSPREY1x0_848; - break; - case 0x0005: - btv->c.type = BTTV_BOARD_OSPREY101_848; - break; - - /* 878 based */ - case 0x0012: - case 0x0013: - btv->c.type = BTTV_BOARD_OSPREY1x0; - break; - case 0x0014: - case 0x0015: - btv->c.type = BTTV_BOARD_OSPREY1x1; - break; - case 0x0016: - case 0x0017: - case 0x0020: - btv->c.type = BTTV_BOARD_OSPREY1x1_SVID; - break; - case 0x0018: - case 0x0019: - case 0x001E: - case 0x001F: - btv->c.type = BTTV_BOARD_OSPREY2xx; - break; - case 0x001A: - case 0x001B: - btv->c.type = BTTV_BOARD_OSPREY2x0_SVID; - break; - case 0x0040: - btv->c.type = BTTV_BOARD_OSPREY500; - break; - case 0x0050: - case 0x0056: - btv->c.type = BTTV_BOARD_OSPREY540; - /* bttv_osprey_540_init(btv); */ - break; - case 0x0060: - case 0x0070: - case 0x00A0: - btv->c.type = BTTV_BOARD_OSPREY2x0; - /* enable output on select control lines */ - gpio_inout(0xffffff,0x000303); - break; - default: - /* unknown...leave generic, but get serial # */ - break; - } - serial = (ee[offset+6] << 24) - | (ee[offset+7] << 16) - | (ee[offset+8] << 8) - | (ee[offset+9]); - } - - printk(KERN_INFO "bttv%d: osprey eeprom: card=%d name=%s serial=%ld\n", - btv->c.nr, btv->c.type, bttv_tvcards[btv->c.type].name,serial); + unsigned short type; + + for (i = 4*16; i < 8*16; i += 16) { + u16 checksum = ip_compute_csum(ee + i, 16); + + if ((checksum&0xff) + (checksum>>8) == 0xff) + break; + } + if (i >= 8*16) + return; + ee += i; + + /* found a valid descriptor */ + type = be16_to_cpup((u16*)(ee+4)); + + switch(type) { + /* 848 based */ + case 0x0004: + cardid = BTTV_BOARD_OSPREY1x0_848; + break; + case 0x0005: + cardid = BTTV_BOARD_OSPREY101_848; + break; + + /* 878 based */ + case 0x0012: + case 0x0013: + cardid = BTTV_BOARD_OSPREY1x0; + break; + case 0x0014: + case 0x0015: + cardid = BTTV_BOARD_OSPREY1x1; + break; + case 0x0016: + case 0x0017: + case 0x0020: + cardid = BTTV_BOARD_OSPREY1x1_SVID; + break; + case 0x0018: + case 0x0019: + case 0x001E: + case 0x001F: + cardid = BTTV_BOARD_OSPREY2xx; + break; + case 0x001A: + case 0x001B: + cardid = BTTV_BOARD_OSPREY2x0_SVID; + break; + case 0x0040: + cardid = BTTV_BOARD_OSPREY500; + break; + case 0x0050: + case 0x0056: + cardid = BTTV_BOARD_OSPREY540; + /* bttv_osprey_540_init(btv); */ + break; + case 0x0060: + case 0x0070: + case 0x00A0: + cardid = BTTV_BOARD_OSPREY2x0; + /* enable output on select control lines */ + gpio_inout(0xffffff,0x000303); + break; + case 0x00D8: + cardid = BTTV_BOARD_OSPREY440; + break; + default: + /* unknown...leave generic, but get serial # */ + printk(KERN_INFO "bttv%d: " + "osprey eeprom: unknown card type 0x%04x\n", + btv->c.nr, type); + break; + } + serial = be32_to_cpup((u32*)(ee+6)); + } + + printk(KERN_INFO "bttv%d: osprey eeprom: card=%d '%s' serial=%u\n", + btv->c.nr, cardid, + cardid>0 ? bttv_tvcards[cardid].name : "Unknown", serial); + + if (cardid<0 || btv->c.type == cardid) + return; + + /* card type isn't set correctly */ + if (card[btv->c.nr] < bttv_num_tvcards) { + printk(KERN_WARNING "bttv%d: osprey eeprom: " + "Not overriding user specified card type\n", btv->c.nr); + } else { + printk(KERN_INFO "bttv%d: osprey eeprom: " + "Changing card type from %d to %d\n", btv->c.nr, + btv->c.type, cardid); + btv->c.type = cardid; + } } /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 91b588d261a..8abb34a3581 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -417,6 +417,7 @@ struct ivtv_mailbox_data { #define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */ #define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */ #define IVTV_F_I_PIO 19 /* PIO in progress */ +#define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */ /* Event notifications */ #define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 8e97a938398..5dd519caf81 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c @@ -757,6 +757,7 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) itv->output_mode = OUT_NONE; itv->speed = 0; + clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags); ivtv_release_stream(s); } @@ -799,7 +800,16 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp) ivtv_unmute(itv); ivtv_release_stream(s); } else if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { + struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT]; + ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); + + /* If all output streams are closed, and if the user doesn't have + IVTV_DEC_STREAM_TYPE_VOUT open, then disable VBI on TV-out. */ + if (itv->output_mode == OUT_NONE && !test_bit(IVTV_F_S_APPL_IO, &s_vout->s_flags)) { + /* disable VBI on TV-out */ + ivtv_disable_vbi(itv); + } } else { ivtv_stop_capture(id, 0); } diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c index d0feabf9308..425eb106390 100644 --- a/drivers/media/video/ivtv/ivtv-firmware.c +++ b/drivers/media/video/ivtv/ivtv-firmware.c @@ -72,8 +72,8 @@ retry: dst++; src++; } - release_firmware(fw); IVTV_INFO("Loaded %s firmware (%zd bytes)\n", fn, fw->size); + release_firmware(fw); return size; } IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size); diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 4773453e8da..047624b9e27 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -285,6 +285,10 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG) return -EBUSY; + if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) { + /* forces ivtv_set_speed to be called */ + itv->speed = 0; + } return ivtv_start_decoding(id, vc->play.speed); } @@ -309,6 +313,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, if (atomic_read(&itv->decoding) > 0) { ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0); + set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags); } break; @@ -317,8 +322,10 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, if (try) break; if (itv->output_mode != OUT_MPG) return -EBUSY; - if (atomic_read(&itv->decoding) > 0) { - ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 0); + if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) { + int speed = itv->speed; + itv->speed = 0; + return ivtv_start_decoding(id, speed); } break; diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c index 814a673712b..5e3b679202a 100644 --- a/drivers/media/video/ivtv/ivtv-mailbox.c +++ b/drivers/media/video/ivtv/ivtv-mailbox.c @@ -40,6 +40,7 @@ #define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */ #define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */ #define API_NO_WAIT_RES (1 << 5) /* Command may not wait for the result */ +#define API_NO_POLL (1 << 6) /* Avoid pointless polling */ struct ivtv_api_info { int flags; /* Flags, see above */ @@ -51,7 +52,7 @@ struct ivtv_api_info { static const struct ivtv_api_info api_info[256] = { /* MPEG encoder API */ API_ENTRY(CX2341X_ENC_PING_FW, API_FAST_RESULT), - API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT), + API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT | API_NO_POLL), API_ENTRY(CX2341X_ENC_STOP_CAPTURE, API_RESULT), API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, API_CACHE), API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, API_CACHE), @@ -96,7 +97,7 @@ static const struct ivtv_api_info api_info[256] = { /* MPEG decoder API */ API_ENTRY(CX2341X_DEC_PING_FW, API_FAST_RESULT), - API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT), + API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT | API_NO_POLL), API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, API_RESULT), API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, API_RESULT), API_ENTRY(CX2341X_DEC_STEP_VIDEO, API_RESULT), @@ -290,6 +291,13 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) /* Get results */ then = jiffies; + if (!(flags & API_NO_POLL)) { + /* First try to poll, then switch to delays */ + for (i = 0; i < 100; i++) { + if (readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE) + break; + } + } while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) { if (jiffies - then > api_timeout) { IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name); @@ -301,7 +309,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) if (flags & API_NO_WAIT_RES) mdelay(1); else - ivtv_msleep_timeout(10, 0); + ivtv_msleep_timeout(1, 0); } if (jiffies - then > msecs_to_jiffies(100)) IVTV_DEBUG_WARN("%s took %u jiffies\n", diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 322b347b67c..51df3f85503 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -603,10 +603,6 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); - /* disable VBI signals, if the MPEG stream contains VBI data, - then that data will be processed automatically for you. */ - ivtv_disable_vbi(itv); - /* set audio mode to left/stereo for dual/stereo mode. */ ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); @@ -639,7 +635,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) } if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, itv->params.width, itv->params.height, itv->params.audio_properties)) { - IVTV_DEBUG_WARN("COULDN'T INITIALIZE DECODER SOURCE\n"); + IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); } return 0; } @@ -909,11 +905,6 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) clear_bit(IVTV_F_S_STREAMING, &s->s_flags); ivtv_flush_queues(s); - if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) { - /* disable VBI on TV-out */ - ivtv_disable_vbi(itv); - } - /* decrement decoding */ atomic_dec(&itv->decoding); diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 868b6886fe7..e3371f97224 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -517,6 +517,7 @@ static int vidioc_g_register (struct file *file, void *priv, __FUNCTION__, errCode); return errCode; } + reg->val = errCode; return 0; } @@ -531,8 +532,8 @@ static int vidioc_s_register (struct file *file, void *priv, if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) return -EINVAL; /* NT100x has a 8-bit register space */ - reg->val = (u8)usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); - if (reg->val < 0) { + errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); + if (errCode < 0) { err("%s: VIDIOC_DBG_S_REGISTER failed: error %d", __FUNCTION__, errCode); return errCode; diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h index 8fb4a3414e0..937c4a616c0 100644 --- a/drivers/media/video/zoran.h +++ b/drivers/media/video/zoran.h @@ -240,11 +240,16 @@ enum gpcs_type { struct zoran_format { char *name; +#ifdef CONFIG_VIDEO_V4L1_COMPAT int palette; +#endif +#ifdef CONFIG_VIDEO_V4L2 __u32 fourcc; int colorspace; +#endif int depth; __u32 flags; + __u32 vfespfr; }; /* flags */ #define ZORAN_FORMAT_COMPRESSED 1<<0 diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c index b0752767ee4..ba2f4ed2948 100644 --- a/drivers/media/video/zoran_device.c +++ b/drivers/media/video/zoran_device.c @@ -429,8 +429,6 @@ zr36057_set_vfe (struct zoran *zr, reg |= (HorDcm << ZR36057_VFESPFR_HorDcm); reg |= (VerDcm << ZR36057_VFESPFR_VerDcm); reg |= (DispMode << ZR36057_VFESPFR_DispMode); - if (format->palette != VIDEO_PALETTE_YUV422 && format->palette != VIDEO_PALETTE_YUYV) - reg |= ZR36057_VFESPFR_LittleEndian; /* RJ: I don't know, why the following has to be the opposite * of the corresponding ZR36060 setting, but only this way * we get the correct colors when uncompressing to the screen */ @@ -439,36 +437,6 @@ zr36057_set_vfe (struct zoran *zr, if (zr->norm != VIDEO_MODE_NTSC) reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang reg |= ZR36057_VFESPFR_TopField; - switch (format->palette) { - - case VIDEO_PALETTE_YUYV: - case VIDEO_PALETTE_YUV422: - reg |= ZR36057_VFESPFR_YUV422; - break; - - case VIDEO_PALETTE_RGB555: - reg |= ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ErrDif; - break; - - case VIDEO_PALETTE_RGB565: - reg |= ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ErrDif; - break; - - case VIDEO_PALETTE_RGB24: - reg |= ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_Pack24; - break; - - case VIDEO_PALETTE_RGB32: - reg |= ZR36057_VFESPFR_RGB888; - break; - - default: - dprintk(1, - KERN_INFO "%s: set_vfe() - unknown color_fmt=%x\n", - ZR_DEVNAME(zr), format->palette); - return; - - } if (HorDcm >= 48) { reg |= 3 << ZR36057_VFESPFR_HFilter; /* 5 tap filter */ } else if (HorDcm >= 32) { @@ -476,6 +444,7 @@ zr36057_set_vfe (struct zoran *zr, } else if (HorDcm >= 16) { reg |= 1 << ZR36057_VFESPFR_HFilter; /* 3 tap filter */ } + reg |= format->vfespfr; btwrite(reg, ZR36057_VFESPFR); /* display configuration */ @@ -651,11 +620,17 @@ zr36057_set_memgrab (struct zoran *zr, int mode) { if (mode) { - if (btread(ZR36057_VSSFGR) & - (ZR36057_VSSFGR_SnapShot | ZR36057_VSSFGR_FrameGrab)) + /* We only check SnapShot and not FrameGrab here. SnapShot==1 + * means a capture is already in progress, but FrameGrab==1 + * doesn't necessary mean that. It's more correct to say a 1 + * to 0 transition indicates a capture completed. If a + * capture is pending when capturing is tuned off, FrameGrab + * will be stuck at 1 until capturing is turned back on. + */ + if (btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) dprintk(1, KERN_WARNING - "%s: zr36057_set_memgrab(1) with SnapShot or FrameGrab on!?\n", + "%s: zr36057_set_memgrab(1) with SnapShot on!?\n", ZR_DEVNAME(zr)); /* switch on VSync interrupts */ @@ -672,11 +647,12 @@ zr36057_set_memgrab (struct zoran *zr, zr->v4l_memgrab_active = 1; } else { - zr->v4l_memgrab_active = 0; - /* switch off VSync interrupts */ btand(~zr->card.vsync_int, ZR36057_ICR); // SW + zr->v4l_memgrab_active = 0; + zr->v4l_grab_frame = NO_GRAB_ACTIVE; + /* reenable grabbing to screen if it was running */ if (zr->v4l_overlay_active) { zr36057_overlay(zr, 1); diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index 17118a490f8..72a037b75d6 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c @@ -99,88 +99,103 @@ #include <asm/byteorder.h> -const struct zoran_format zoran_formats[] = { - { - .name = "15-bit RGB", - .palette = VIDEO_PALETTE_RGB555, -#ifdef CONFIG_VIDEO_V4L2 -#ifdef __LITTLE_ENDIAN - .fourcc = V4L2_PIX_FMT_RGB555, +#if defined(CONFIG_VIDEO_V4L2) && defined(CONFIG_VIDEO_V4L1_COMPAT) +#define ZFMT(pal, fcc, cs) \ + .palette = (pal), .fourcc = (fcc), .colorspace = (cs) +#elif defined(CONFIG_VIDEO_V4L2) +#define ZFMT(pal, fcc, cs) \ + .fourcc = (fcc), .colorspace = (cs) #else - .fourcc = V4L2_PIX_FMT_RGB555X, -#endif - .colorspace = V4L2_COLORSPACE_SRGB, +#define ZFMT(pal, fcc, cs) \ + .palette = (pal) #endif + +const struct zoran_format zoran_formats[] = { + { + .name = "15-bit RGB LE", + ZFMT(VIDEO_PALETTE_RGB555, + V4L2_PIX_FMT_RGB555, V4L2_COLORSPACE_SRGB), .depth = 15, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif| + ZR36057_VFESPFR_LittleEndian, }, { - .name = "16-bit RGB", - .palette = VIDEO_PALETTE_RGB565, -#ifdef CONFIG_VIDEO_V4L2 -#ifdef __LITTLE_ENDIAN - .fourcc = V4L2_PIX_FMT_RGB565, -#else - .fourcc = V4L2_PIX_FMT_RGB565X, -#endif - .colorspace = V4L2_COLORSPACE_SRGB, -#endif + .name = "15-bit RGB BE", + ZFMT(-1, + V4L2_PIX_FMT_RGB555X, V4L2_COLORSPACE_SRGB), + .depth = 15, + .flags = ZORAN_FORMAT_CAPTURE | + ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif, + }, { + .name = "16-bit RGB LE", + ZFMT(VIDEO_PALETTE_RGB565, + V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB), .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif| + ZR36057_VFESPFR_LittleEndian, + }, { + .name = "16-bit RGB BE", + ZFMT(-1, + V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB), + .depth = 16, + .flags = ZORAN_FORMAT_CAPTURE | + ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif, }, { .name = "24-bit RGB", - .palette = VIDEO_PALETTE_RGB24, -#ifdef CONFIG_VIDEO_V4L2 -#ifdef __LITTLE_ENDIAN - .fourcc = V4L2_PIX_FMT_BGR24, -#else - .fourcc = V4L2_PIX_FMT_RGB24, -#endif - .colorspace = V4L2_COLORSPACE_SRGB, -#endif + ZFMT(VIDEO_PALETTE_RGB24, + V4L2_PIX_FMT_BGR24, V4L2_COLORSPACE_SRGB), .depth = 24, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24, }, { - .name = "32-bit RGB", - .palette = VIDEO_PALETTE_RGB32, -#ifdef CONFIG_VIDEO_V4L2 -#ifdef __LITTLE_ENDIAN - .fourcc = V4L2_PIX_FMT_BGR32, -#else - .fourcc = V4L2_PIX_FMT_RGB32, -#endif - .colorspace = V4L2_COLORSPACE_SRGB, -#endif + .name = "32-bit RGB LE", + ZFMT(VIDEO_PALETTE_RGB32, + V4L2_PIX_FMT_BGR32, V4L2_COLORSPACE_SRGB), + .depth = 32, + .flags = ZORAN_FORMAT_CAPTURE | + ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian, + }, { + .name = "32-bit RGB BE", + ZFMT(-1, + V4L2_PIX_FMT_RGB32, V4L2_COLORSPACE_SRGB), .depth = 32, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_RGB888, }, { .name = "4:2:2, packed, YUYV", - .palette = VIDEO_PALETTE_YUV422, -#ifdef CONFIG_VIDEO_V4L2 - .fourcc = V4L2_PIX_FMT_YUYV, - .colorspace = V4L2_COLORSPACE_SMPTE170M, -#endif + ZFMT(VIDEO_PALETTE_YUV422, + V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_SMPTE170M), + .depth = 16, + .flags = ZORAN_FORMAT_CAPTURE | + ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_YUV422, + }, { + .name = "4:2:2, packed, UYVY", + ZFMT(VIDEO_PALETTE_UYVY, + V4L2_PIX_FMT_UYVY, V4L2_COLORSPACE_SMPTE170M), .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, + .vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian, }, { .name = "Hardware-encoded Motion-JPEG", - .palette = -1, -#ifdef CONFIG_VIDEO_V4L2 - .fourcc = V4L2_PIX_FMT_MJPEG, - .colorspace = V4L2_COLORSPACE_SMPTE170M, -#endif + ZFMT(-1, + V4L2_PIX_FMT_MJPEG, V4L2_COLORSPACE_SMPTE170M), .depth = 0, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_PLAYBACK | ZORAN_FORMAT_COMPRESSED, } }; -static const int zoran_num_formats = - (sizeof(zoran_formats) / sizeof(struct zoran_format)); +#define NUM_FORMATS ARRAY_SIZE(zoran_formats) // RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined @@ -768,13 +783,13 @@ v4l_grab (struct file *file, struct zoran *zr = fh->zr; int res = 0, i; - for (i = 0; i < zoran_num_formats; i++) { + for (i = 0; i < NUM_FORMATS; i++) { if (zoran_formats[i].palette == mp->format && zoran_formats[i].flags & ZORAN_FORMAT_CAPTURE && !(zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)) break; } - if (i == zoran_num_formats || zoran_formats[i].depth == 0) { + if (i == NUM_FORMATS || zoran_formats[i].depth == 0) { dprintk(1, KERN_ERR "%s: v4l_grab() - wrong bytes-per-pixel format\n", @@ -1173,10 +1188,14 @@ zoran_close_end_session (struct file *file) /* v4l capture */ if (fh->v4l_buffers.active != ZORAN_FREE) { + long flags; + + spin_lock_irqsave(&zr->spinlock, flags); zr36057_set_memgrab(zr, 0); zr->v4l_buffers.allocated = 0; zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_FREE; + spin_unlock_irqrestore(&zr->spinlock, flags); } /* v4l buffers */ @@ -2107,7 +2126,7 @@ zoran_do_ioctl (struct inode *inode, vpict->colour, vpict->contrast, vpict->depth, vpict->palette); - for (i = 0; i < zoran_num_formats; i++) { + for (i = 0; i < NUM_FORMATS; i++) { const struct zoran_format *fmt = &zoran_formats[i]; if (fmt->palette != -1 && @@ -2116,7 +2135,7 @@ zoran_do_ioctl (struct inode *inode, fmt->depth == vpict->depth) break; } - if (i == zoran_num_formats) { + if (i == NUM_FORMATS) { dprintk(1, KERN_ERR "%s: VIDIOCSPICT - Invalid palette %d\n", @@ -2220,10 +2239,10 @@ zoran_do_ioctl (struct inode *inode, ZR_DEVNAME(zr), vbuf->base, vbuf->width, vbuf->height, vbuf->depth, vbuf->bytesperline); - for (i = 0; i < zoran_num_formats; i++) + for (i = 0; i < NUM_FORMATS; i++) if (zoran_formats[i].depth == vbuf->depth) break; - if (i == zoran_num_formats) { + if (i == NUM_FORMATS) { dprintk(1, KERN_ERR "%s: VIDIOCSFBUF - invalid fbuf depth %d\n", @@ -2672,14 +2691,14 @@ zoran_do_ioctl (struct inode *inode, return -EINVAL; } - for (i = 0; i < zoran_num_formats; i++) { + for (i = 0; i < NUM_FORMATS; i++) { if (zoran_formats[i].flags & flag) num++; if (num == fmt->index) break; } if (fmt->index < 0 /* late, but not too late */ || - i == zoran_num_formats) + i == NUM_FORMATS) return -EINVAL; memset(fmt, 0, sizeof(*fmt)); @@ -2737,7 +2756,8 @@ zoran_do_ioctl (struct inode *inode, fmt->fmt.pix.height = fh->v4l_settings.height; fmt->fmt.pix.sizeimage = - fh->v4l_buffers.buffer_size; + fh->v4l_settings.bytesperline * + fh->v4l_settings.height; fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc; fmt->fmt.pix.colorspace = @@ -2941,11 +2961,11 @@ zoran_do_ioctl (struct inode *inode, sfmtjpg_unlock_and_return: mutex_unlock(&zr->resource_lock); } else { - for (i = 0; i < zoran_num_formats; i++) + for (i = 0; i < NUM_FORMATS; i++) if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc) break; - if (i == zoran_num_formats) { + if (i == NUM_FORMATS) { dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n", @@ -2984,8 +3004,9 @@ zoran_do_ioctl (struct inode *inode, /* tell the user the * results/missing stuff */ - fmt->fmt.pix.sizeimage = fh->v4l_buffers.buffer_size /*zr->gbpl * zr->gheight */ - ; + fmt->fmt.pix.sizeimage = + fh->v4l_settings.height * + fh->v4l_settings.bytesperline; if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) fmt->fmt.pix.field = @@ -3053,10 +3074,10 @@ zoran_do_ioctl (struct inode *inode, fb->fmt.bytesperline, fb->fmt.pixelformat, (char *) &printformat); - for (i = 0; i < zoran_num_formats; i++) + for (i = 0; i < NUM_FORMATS; i++) if (zoran_formats[i].fourcc == fb->fmt.pixelformat) break; - if (i == zoran_num_formats) { + if (i == NUM_FORMATS) { dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n", @@ -3439,8 +3460,13 @@ zoran_do_ioctl (struct inode *inode, goto strmoff_unlock_and_return; /* unload capture */ - if (zr->v4l_memgrab_active) + if (zr->v4l_memgrab_active) { + long flags; + + spin_lock_irqsave(&zr->spinlock, flags); zr36057_set_memgrab(zr, 0); + spin_unlock_irqrestore(&zr->spinlock, flags); + } for (i = 0; i < fh->v4l_buffers.num_buffers; i++) zr->v4l_buffers.buffer[i].state = @@ -3704,11 +3730,11 @@ zoran_do_ioctl (struct inode *inode, dprintk(3, KERN_DEBUG "%s: VIDIOC_S_STD - norm=0x%llx\n", ZR_DEVNAME(zr), (unsigned long long)*std); - if (*std == V4L2_STD_PAL) + if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL)) norm = VIDEO_MODE_PAL; - else if (*std == V4L2_STD_NTSC) + else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC)) norm = VIDEO_MODE_NTSC; - else if (*std == V4L2_STD_SECAM) + else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM)) norm = VIDEO_MODE_SECAM; else if (*std == V4L2_STD_ALL) norm = VIDEO_MODE_AUTO; @@ -4149,11 +4175,11 @@ zoran_do_ioctl (struct inode *inode, V4L2_BUF_TYPE_VIDEO_CAPTURE) { int i; - for (i = 0; i < zoran_num_formats; i++) + for (i = 0; i < NUM_FORMATS; i++) if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat) break; - if (i == zoran_num_formats) { + if (i == NUM_FORMATS) { res = -EINVAL; goto tryfmt_unlock_and_return; } @@ -4213,8 +4239,8 @@ zoran_poll (struct file *file, { struct zoran_fh *fh = file->private_data; struct zoran *zr = fh->zr; - wait_queue_head_t *queue = NULL; int res = 0, frame; + unsigned long flags; /* we should check whether buffers are ready to be synced on * (w/o waits - O_NONBLOCK) here @@ -4228,51 +4254,58 @@ zoran_poll (struct file *file, switch (fh->map_mode) { case ZORAN_MAP_MODE_RAW: - if (fh->v4l_buffers.active == ZORAN_FREE || - zr->v4l_pend_head == zr->v4l_pend_tail) { - dprintk(1, - "%s: zoran_poll() - no buffers queued\n", - ZR_DEVNAME(zr)); - res = POLLNVAL; - goto poll_unlock_and_return; - } - queue = &zr->v4l_capq; - frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME]; - poll_wait(file, queue, wait); - if (fh->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE) + poll_wait(file, &zr->v4l_capq, wait); + frame = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; + + spin_lock_irqsave(&zr->spinlock, flags); + dprintk(3, + KERN_DEBUG + "%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n", + ZR_DEVNAME(zr), __FUNCTION__, + "FAL"[fh->v4l_buffers.active], zr->v4l_sync_tail, + "UPMD"[zr->v4l_buffers.buffer[frame].state], + zr->v4l_pend_tail, zr->v4l_pend_head); + /* Process is the one capturing? */ + if (fh->v4l_buffers.active != ZORAN_FREE && + /* Buffer ready to DQBUF? */ + zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE) res = POLLIN | POLLRDNORM; + spin_unlock_irqrestore(&zr->spinlock, flags); + break; case ZORAN_MAP_MODE_JPG_REC: case ZORAN_MAP_MODE_JPG_PLAY: - if (fh->jpg_buffers.active == ZORAN_FREE || - zr->jpg_que_head == zr->jpg_que_tail) { - dprintk(1, - "%s: zoran_poll() - no buffers queued\n", - ZR_DEVNAME(zr)); - res = POLLNVAL; - goto poll_unlock_and_return; - } - queue = &zr->jpg_capq; + poll_wait(file, &zr->jpg_capq, wait); frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; - poll_wait(file, queue, wait); - if (fh->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) { + + spin_lock_irqsave(&zr->spinlock, flags); + dprintk(3, + KERN_DEBUG + "%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n", + ZR_DEVNAME(zr), __FUNCTION__, + "FAL"[fh->jpg_buffers.active], zr->jpg_que_tail, + "UPMD"[zr->jpg_buffers.buffer[frame].state], + zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head); + if (fh->jpg_buffers.active != ZORAN_FREE && + zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) { if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) res = POLLIN | POLLRDNORM; else res = POLLOUT | POLLWRNORM; } + spin_unlock_irqrestore(&zr->spinlock, flags); + break; default: dprintk(1, + KERN_ERR "%s: zoran_poll() - internal error, unknown map_mode=%d\n", ZR_DEVNAME(zr), fh->map_mode); res = POLLNVAL; - goto poll_unlock_and_return; } -poll_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; @@ -4368,11 +4401,15 @@ zoran_vm_close (struct vm_area_struct *vma) mutex_lock(&zr->resource_lock); if (fh->v4l_buffers.active != ZORAN_FREE) { + long flags; + + spin_lock_irqsave(&zr->spinlock, flags); zr36057_set_memgrab(zr, 0); zr->v4l_buffers.allocated = 0; zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_FREE; + spin_unlock_irqrestore(&zr->spinlock, flags); } //v4l_fbuffer_free(file); fh->v4l_buffers.allocated = 0; diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 661c747389e..51e1cb47273 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -178,6 +178,7 @@ #define DEV_HAS_STATISTICS_V2 0x0800 /* device supports hw statistics version 2 */ #define DEV_HAS_TEST_EXTENDED 0x1000 /* device supports extended diagnostic test */ #define DEV_HAS_MGMT_UNIT 0x2000 /* device supports management unit */ +#define DEV_HAS_CORRECT_MACADDR 0x4000 /* device supports correct mac address order */ enum { NvRegIrqStatus = 0x000, @@ -5172,7 +5173,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i /* check the workaround bit for correct mac address order */ txreg = readl(base + NvRegTransmitPoll); - if (txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) { + if ((txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) || + (id->driver_data & DEV_HAS_CORRECT_MACADDR)) { /* mac address is already in correct order */ dev->dev_addr[0] = (np->orig_mac[0] >> 0) & 0xff; dev->dev_addr[1] = (np->orig_mac[0] >> 8) & 0xff; @@ -5500,67 +5502,67 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, {0,}, }; diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index ac3596f45dd..100bf410bf5 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c @@ -245,7 +245,7 @@ int __init gfar_mdio_init(void) return driver_register(&gianfar_mdio_driver); } -void __exit gfar_mdio_exit(void) +void gfar_mdio_exit(void) { driver_unregister(&gianfar_mdio_driver); } diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h index 5d340046951..b373091c703 100644 --- a/drivers/net/gianfar_mii.h +++ b/drivers/net/gianfar_mii.h @@ -42,5 +42,5 @@ struct gfar_mii { int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum); int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value); int __init gfar_mdio_init(void); -void __exit gfar_mdio_exit(void); +void gfar_mdio_exit(void); #endif /* GIANFAR_PHY_H */ diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c index 721ee38d224..c429a5002dd 100644 --- a/drivers/net/lib8390.c +++ b/drivers/net/lib8390.c @@ -143,6 +143,52 @@ static void __NS8390_init(struct net_device *dev, int startp); * annoying the transmit function is called bh atomic. That places * restrictions on the user context callers as disable_irq won't save * them. + * + * Additional explanation of problems with locking by Alan Cox: + * + * "The author (me) didn't use spin_lock_irqsave because the slowness of the + * card means that approach caused horrible problems like losing serial data + * at 38400 baud on some chips. Rememeber many 8390 nics on PCI were ISA + * chips with FPGA front ends. + * + * Ok the logic behind the 8390 is very simple: + * + * Things to know + * - IRQ delivery is asynchronous to the PCI bus + * - Blocking the local CPU IRQ via spin locks was too slow + * - The chip has register windows needing locking work + * + * So the path was once (I say once as people appear to have changed it + * in the mean time and it now looks rather bogus if the changes to use + * disable_irq_nosync_irqsave are disabling the local IRQ) + * + * + * Take the page lock + * Mask the IRQ on chip + * Disable the IRQ (but not mask locally- someone seems to have + * broken this with the lock validator stuff) + * [This must be _nosync as the page lock may otherwise + * deadlock us] + * Drop the page lock and turn IRQs back on + * + * At this point an existing IRQ may still be running but we can't + * get a new one + * + * Take the lock (so we know the IRQ has terminated) but don't mask + * the IRQs on the processor + * Set irqlock [for debug] + * + * Transmit (slow as ****) + * + * re-enable the IRQ + * + * + * We have to use disable_irq because otherwise you will get delayed + * interrupts on the APIC bus deadlocking the transmit path. + * + * Quite hairy but the chip simply wasn't designed for SMP and you can't + * even ACK an interrupt without risking corrupting other parallel + * activities on the chip." [lkml, 25 Jul 2007] */ diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c index d0808fa3ec8..5b87183e62c 100644 --- a/drivers/net/mlx4/mr.c +++ b/drivers/net/mlx4/mr.c @@ -255,10 +255,8 @@ int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access, int err; index = mlx4_bitmap_alloc(&priv->mr_table.mpt_bitmap); - if (index == -1) { - err = -ENOMEM; - goto err; - } + if (index == -1) + return -ENOMEM; mr->iova = iova; mr->size = size; @@ -269,15 +267,8 @@ int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access, err = mlx4_mtt_init(dev, npages, page_shift, &mr->mtt); if (err) - goto err_index; - - return 0; - -err_index: - mlx4_bitmap_free(&priv->mr_table.mpt_bitmap, index); + mlx4_bitmap_free(&priv->mr_table.mpt_bitmap, index); -err: - kfree(mr); return err; } EXPORT_SYMBOL_GPL(mlx4_mr_alloc); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 19e2fa940ac..08a62acde8b 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -335,7 +335,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->ahw.pdev = pdev; adapter->ahw.pci_func = pci_func_id; spin_lock_init(&adapter->tx_lock); - spin_lock_init(&adapter->lock); /* remap phys address */ mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ @@ -895,8 +894,6 @@ static int netxen_nic_open(struct net_device *netdev) /* Done here again so that even if phantom sw overwrote it, * we set it */ - if (adapter->macaddr_set) - adapter->macaddr_set(adapter, netdev->dev_addr); if (adapter->init_port && adapter->init_port(adapter, adapter->portnum) != 0) { del_timer_sync(&adapter->watchdog_timer); @@ -904,6 +901,8 @@ static int netxen_nic_open(struct net_device *netdev) netxen_nic_driver_name, adapter->portnum); return -EIO; } + if (adapter->macaddr_set) + adapter->macaddr_set(adapter, netdev->dev_addr); netxen_nic_set_link_parameters(adapter); @@ -930,6 +929,8 @@ static int netxen_nic_close(struct net_device *netdev) netif_carrier_off(netdev); netif_stop_queue(netdev); + netxen_nic_disable_int(adapter); + cmd_buff = adapter->cmd_buf_arr; for (i = 0; i < adapter->max_tx_desc_count; i++) { buffrag = cmd_buff->frag_array; @@ -1226,15 +1227,12 @@ static void netxen_tx_timeout_task(struct work_struct *work) { struct netxen_adapter *adapter = container_of(work, struct netxen_adapter, tx_timeout_task); - unsigned long flags; printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", netxen_nic_driver_name, adapter->netdev->name); - spin_lock_irqsave(&adapter->lock, flags); netxen_nic_close(adapter->netdev); netxen_nic_open(adapter->netdev); - spin_unlock_irqrestore(&adapter->lock, flags); adapter->netdev->trans_start = jiffies; netif_wake_queue(adapter->netdev); } @@ -1243,28 +1241,12 @@ static int netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) { u32 ret = 0; - u32 our_int = 0; DPRINTK(INFO, "Entered handle ISR\n"); adapter->stats.ints++; - if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { - our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); - /* not our interrupt */ - if ((our_int & (0x80 << adapter->portnum)) == 0) - return ret; - } - netxen_nic_disable_int(adapter); - if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { - /* claim interrupt */ - if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { - writel(our_int & ~((u32)(0x80 << adapter->portnum)), - NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); - } - } - if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) { if (netif_rx_schedule_prep(netdev)) { /* @@ -1298,6 +1280,7 @@ irqreturn_t netxen_intr(int irq, void *data) { struct netxen_adapter *adapter; struct net_device *netdev; + u32 our_int = 0; if (unlikely(!irq)) { return IRQ_NONE; /* Not our interrupt */ @@ -1305,7 +1288,22 @@ irqreturn_t netxen_intr(int irq, void *data) adapter = (struct netxen_adapter *)data; netdev = adapter->netdev; - /* process our status queue (for all 4 ports) */ + + if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { + our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); + /* not our interrupt */ + if ((our_int & (0x80 << adapter->portnum)) == 0) + return IRQ_NONE; + } + + if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { + /* claim interrupt */ + if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { + writel(our_int & ~((u32)(0x80 << adapter->portnum)), + NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); + } + } + if (netif_running(netdev)) netxen_handle_int(adapter, netdev); diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 73da611fd53..997c2d0c83b 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -996,7 +996,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) { struct net_device *dev = (struct net_device *) dev_id; mace_private *lp = netdev_priv(dev); - kio_addr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr; int status; int IntrCnt = MACE_MAX_IR_ITERATIONS; @@ -1006,6 +1006,8 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) return IRQ_NONE; } + ioaddr = dev->base_addr; + if (lp->tx_irq_disabled) { printk( (lp->tx_irq_disabled? diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 7912dbd1425..af6728cb49c 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -1368,6 +1368,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) kio_addr_t ioaddr = dev->base_addr; u_short num_pages; short time_out, ir; + unsigned long flags; netif_stop_queue(dev); @@ -1395,6 +1396,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) /* A packet is now waiting. */ smc->packets_waiting++; + spin_lock_irqsave(&smc->lock, flags); SMC_SELECT_BANK(2); /* Paranoia, we should always be in window 2 */ /* need MC_RESET to keep the memory consistent. errata? */ @@ -1411,6 +1413,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Acknowledge the interrupt, send the packet. */ outw((ir&0xff00) | IM_ALLOC_INT, ioaddr + INTERRUPT); smc_hardware_send_packet(dev); /* Send the packet now.. */ + spin_unlock_irqrestore(&smc->lock, flags); return 0; } } @@ -1418,6 +1421,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Otherwise defer until the Tx-space-allocated interrupt. */ DEBUG(2, "%s: memory allocation deferred.\n", dev->name); outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT); + spin_unlock_irqrestore(&smc->lock, flags); return 0; } @@ -1523,6 +1527,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name, irq, ioaddr); + spin_lock(&smc->lock); smc->watchdog = 0; saved_bank = inw(ioaddr + BANK_SELECT); if ((saved_bank & 0xff00) != 0x3300) { @@ -1620,6 +1625,7 @@ irq_done: readb(smc->base+MEGAHERTZ_ISR); } #endif + spin_unlock(&smc->lock); return IRQ_RETVAL(handled); } @@ -1902,6 +1908,9 @@ static void media_check(u_long arg) kio_addr_t ioaddr = dev->base_addr; u_short i, media, saved_bank; u_short link; + unsigned long flags; + + spin_lock_irqsave(&smc->lock, flags); saved_bank = inw(ioaddr + BANK_SELECT); @@ -1934,6 +1943,7 @@ static void media_check(u_long arg) smc->media.expires = jiffies + HZ/100; add_timer(&smc->media); SMC_SELECT_BANK(saved_bank); + spin_unlock_irqrestore(&smc->lock, flags); return; } @@ -2007,6 +2017,7 @@ reschedule: smc->media.expires = jiffies + HZ; add_timer(&smc->media); SMC_SELECT_BANK(saved_bank); + spin_unlock_irqrestore(&smc->lock, flags); } static int smc_link_ok(struct net_device *dev) @@ -2094,14 +2105,14 @@ static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) u16 saved_bank = inw(ioaddr + BANK_SELECT); int ret; - SMC_SELECT_BANK(3); spin_lock_irq(&smc->lock); + SMC_SELECT_BANK(3); if (smc->cfg & CFG_MII_SELECT) ret = mii_ethtool_gset(&smc->mii_if, ecmd); else ret = smc_netdev_get_ecmd(dev, ecmd); - spin_unlock_irq(&smc->lock); SMC_SELECT_BANK(saved_bank); + spin_unlock_irq(&smc->lock); return ret; } @@ -2112,14 +2123,14 @@ static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) u16 saved_bank = inw(ioaddr + BANK_SELECT); int ret; - SMC_SELECT_BANK(3); spin_lock_irq(&smc->lock); + SMC_SELECT_BANK(3); if (smc->cfg & CFG_MII_SELECT) ret = mii_ethtool_sset(&smc->mii_if, ecmd); else ret = smc_netdev_set_ecmd(dev, ecmd); - spin_unlock_irq(&smc->lock); SMC_SELECT_BANK(saved_bank); + spin_unlock_irq(&smc->lock); return ret; } @@ -2130,11 +2141,11 @@ static u32 smc_get_link(struct net_device *dev) u16 saved_bank = inw(ioaddr + BANK_SELECT); u32 ret; - SMC_SELECT_BANK(3); spin_lock_irq(&smc->lock); + SMC_SELECT_BANK(3); ret = smc_link_ok(dev); - spin_unlock_irq(&smc->lock); SMC_SELECT_BANK(saved_bank); + spin_unlock_irq(&smc->lock); return ret; } diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h index 4cb710bbe72..cfa26791447 100644 --- a/drivers/net/s2io-regs.h +++ b/drivers/net/s2io-regs.h @@ -747,10 +747,9 @@ struct XENA_dev_config { #define MC_ERR_REG_MIRI_CRI_ERR_1 BIT(23) #define MC_ERR_REG_SM_ERR BIT(31) #define MC_ERR_REG_ECC_ALL_SNG (BIT(2) | BIT(3) | BIT(4) | BIT(5) |\ - BIT(6) | BIT(7) | BIT(17) | BIT(19)) + BIT(17) | BIT(19)) #define MC_ERR_REG_ECC_ALL_DBL (BIT(10) | BIT(11) | BIT(12) |\ - BIT(13) | BIT(14) | BIT(15) |\ - BIT(18) | BIT(20)) + BIT(13) | BIT(18) | BIT(20)) u64 mc_err_mask; u64 mc_err_alarm; diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index afef6c0c59f..2be0a0f1b48 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -32,12 +32,12 @@ * rx_ring_sz: This defines the number of receive blocks each ring can have. * This is also an array of size 8. * rx_ring_mode: This defines the operation mode of all 8 rings. The valid - * values are 1, 2 and 3. + * values are 1, 2. * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. * tx_fifo_len: This too is an array of 8. Each element defines the number of * Tx descriptors that can be associated with each corresponding FIFO. * intr_type: This defines the type of interrupt. The values can be 0(INTA), - * 1(MSI), 2(MSI_X). Default value is '0(INTA)' + * 2(MSI_X). Default value is '0(INTA)' * lro: Specifies whether to enable Large Receive Offload (LRO) or not. * Possible values '1' for enable '0' for disable. Default is '0' * lro_max_pkts: This parameter defines maximum number of packets can be @@ -84,14 +84,14 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.23.1" +#define DRV_VERSION "2.0.25.1" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; static char s2io_driver_version[] = DRV_VERSION; -static int rxd_size[4] = {32,48,48,64}; -static int rxd_count[4] = {127,85,85,63}; +static int rxd_size[2] = {32,48}; +static int rxd_count[2] = {127,85}; static inline int RXD_IS_UP2DT(struct RxD_t *rxdp) { @@ -282,6 +282,7 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = { ("lro_flush_due_to_max_pkts"), ("lro_avg_aggr_pkts"), ("mem_alloc_fail_cnt"), + ("pci_map_fail_cnt"), ("watchdog_timer_cnt"), ("mem_allocated"), ("mem_freed"), @@ -426,7 +427,7 @@ S2IO_PARM_INT(bimodal, 0); S2IO_PARM_INT(l3l4hdr_size, 128); /* Frequency of Rx desc syncs expressed as power of 2 */ S2IO_PARM_INT(rxsync_frequency, 3); -/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */ +/* Interrupt type. Values can be 0(INTA), 2(MSI_X) */ S2IO_PARM_INT(intr_type, 0); /* Large receive offload feature */ S2IO_PARM_INT(lro, 0); @@ -701,7 +702,7 @@ static int init_shared_mem(struct s2io_nic *nic) (u64) tmp_p_addr_next; } } - if (nic->rxd_mode >= RXD_MODE_3A) { + if (nic->rxd_mode == RXD_MODE_3B) { /* * Allocation of Storages for buffer addresses in 2BUFF mode * and the buffers as well. @@ -870,7 +871,7 @@ static void free_shared_mem(struct s2io_nic *nic) } } - if (nic->rxd_mode >= RXD_MODE_3A) { + if (nic->rxd_mode == RXD_MODE_3B) { /* Freeing buffer storage addresses in 2BUFF mode. */ for (i = 0; i < config->rx_ring_num; i++) { blk_cnt = config->rx_cfg[i].num_rxd / @@ -2233,44 +2234,6 @@ static void stop_nic(struct s2io_nic *nic) writeq(val64, &bar0->adapter_control); } -static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \ - sk_buff *skb) -{ - struct net_device *dev = nic->dev; - struct sk_buff *frag_list; - void *tmp; - - /* Buffer-1 receives L3/L4 headers */ - ((struct RxD3*)rxdp)->Buffer1_ptr = pci_map_single - (nic->pdev, skb->data, l3l4hdr_size + 4, - PCI_DMA_FROMDEVICE); - - /* skb_shinfo(skb)->frag_list will have L4 data payload */ - skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE); - if (skb_shinfo(skb)->frag_list == NULL) { - nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; - DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n ", dev->name); - return -ENOMEM ; - } - frag_list = skb_shinfo(skb)->frag_list; - skb->truesize += frag_list->truesize; - nic->mac_control.stats_info->sw_stat.mem_allocated - += frag_list->truesize; - frag_list->next = NULL; - tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1); - frag_list->data = tmp; - skb_reset_tail_pointer(frag_list); - - /* Buffer-2 receives L4 data payload */ - ((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev, - frag_list->data, dev->mtu, - PCI_DMA_FROMDEVICE); - rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4); - rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu); - - return SUCCESS; -} - /** * fill_rx_buffers - Allocates the Rx side skbs * @nic: device private variable @@ -2307,6 +2270,9 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) unsigned long flags; struct RxD_t *first_rxdp = NULL; u64 Buffer0_ptr = 0, Buffer1_ptr = 0; + struct RxD1 *rxdp1; + struct RxD3 *rxdp3; + struct swStat *stats = &nic->mac_control.stats_info->sw_stat; mac_control = &nic->mac_control; config = &nic->config; @@ -2359,7 +2325,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) (block_no * (rxd_count[nic->rxd_mode] + 1)) + off; } if ((rxdp->Control_1 & RXD_OWN_XENA) && - ((nic->rxd_mode >= RXD_MODE_3A) && + ((nic->rxd_mode == RXD_MODE_3B) && (rxdp->Control_2 & BIT(0)))) { mac_control->rings[ring_no].rx_curr_put_info. offset = off; @@ -2370,10 +2336,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) HEADER_802_2_SIZE + HEADER_SNAP_SIZE; if (nic->rxd_mode == RXD_MODE_1) size += NET_IP_ALIGN; - else if (nic->rxd_mode == RXD_MODE_3B) - size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4; else - size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4; + size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4; /* allocate skb */ skb = dev_alloc_skb(size); @@ -2392,33 +2356,35 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) += skb->truesize; if (nic->rxd_mode == RXD_MODE_1) { /* 1 buffer mode - normal operation mode */ + rxdp1 = (struct RxD1*)rxdp; memset(rxdp, 0, sizeof(struct RxD1)); skb_reserve(skb, NET_IP_ALIGN); - ((struct RxD1*)rxdp)->Buffer0_ptr = pci_map_single + rxdp1->Buffer0_ptr = pci_map_single (nic->pdev, skb->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); + if( (rxdp1->Buffer0_ptr == 0) || + (rxdp1->Buffer0_ptr == + DMA_ERROR_CODE)) + goto pci_map_failed; + rxdp->Control_2 = SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN); - } else if (nic->rxd_mode >= RXD_MODE_3A) { + } else if (nic->rxd_mode == RXD_MODE_3B) { /* - * 2 or 3 buffer mode - - * Both 2 buffer mode and 3 buffer mode provides 128 + * 2 buffer mode - + * 2 buffer mode provides 128 * byte aligned receive buffers. - * - * 3 buffer mode provides header separation where in - * skb->data will have L3/L4 headers where as - * skb_shinfo(skb)->frag_list will have the L4 data - * payload */ + rxdp3 = (struct RxD3*)rxdp; /* save buffer pointers to avoid frequent dma mapping */ - Buffer0_ptr = ((struct RxD3*)rxdp)->Buffer0_ptr; - Buffer1_ptr = ((struct RxD3*)rxdp)->Buffer1_ptr; + Buffer0_ptr = rxdp3->Buffer0_ptr; + Buffer1_ptr = rxdp3->Buffer1_ptr; memset(rxdp, 0, sizeof(struct RxD3)); /* restore the buffer pointers for dma sync*/ - ((struct RxD3*)rxdp)->Buffer0_ptr = Buffer0_ptr; - ((struct RxD3*)rxdp)->Buffer1_ptr = Buffer1_ptr; + rxdp3->Buffer0_ptr = Buffer0_ptr; + rxdp3->Buffer1_ptr = Buffer1_ptr; ba = &mac_control->rings[ring_no].ba[block_no][off]; skb_reserve(skb, BUF0_LEN); @@ -2428,14 +2394,18 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) skb->data = (void *) (unsigned long)tmp; skb_reset_tail_pointer(skb); - if (!(((struct RxD3*)rxdp)->Buffer0_ptr)) - ((struct RxD3*)rxdp)->Buffer0_ptr = + if (!(rxdp3->Buffer0_ptr)) + rxdp3->Buffer0_ptr = pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); else pci_dma_sync_single_for_device(nic->pdev, - (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr, + (dma_addr_t) rxdp3->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); + if( (rxdp3->Buffer0_ptr == 0) || + (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) + goto pci_map_failed; + rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); if (nic->rxd_mode == RXD_MODE_3B) { /* Two buffer mode */ @@ -2444,33 +2414,30 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) * Buffer2 will have L3/L4 header plus * L4 payload */ - ((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single + rxdp3->Buffer2_ptr = pci_map_single (nic->pdev, skb->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - /* Buffer-1 will be dummy buffer. Not used */ - if (!(((struct RxD3*)rxdp)->Buffer1_ptr)) { - ((struct RxD3*)rxdp)->Buffer1_ptr = + if( (rxdp3->Buffer2_ptr == 0) || + (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) + goto pci_map_failed; + + rxdp3->Buffer1_ptr = pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); + if( (rxdp3->Buffer1_ptr == 0) || + (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { + pci_unmap_single + (nic->pdev, + (dma_addr_t)skb->data, + dev->mtu + 4, + PCI_DMA_FROMDEVICE); + goto pci_map_failed; } rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); rxdp->Control_2 |= SET_BUFFER2_SIZE_3 (dev->mtu + 4); - } else { - /* 3 buffer mode */ - if (fill_rxd_3buf(nic, rxdp, skb) == -ENOMEM) { - nic->mac_control.stats_info->sw_stat.\ - mem_freed += skb->truesize; - dev_kfree_skb_irq(skb); - if (first_rxdp) { - wmb(); - first_rxdp->Control_1 |= - RXD_OWN_XENA; - } - return -ENOMEM ; - } } rxdp->Control_2 |= BIT(0); } @@ -2505,6 +2472,11 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) } return SUCCESS; +pci_map_failed: + stats->pci_map_fail_cnt++; + stats->mem_freed += skb->truesize; + dev_kfree_skb_irq(skb); + return -ENOMEM; } static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) @@ -2515,6 +2487,8 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) struct RxD_t *rxdp; struct mac_info *mac_control; struct buffAdd *ba; + struct RxD1 *rxdp1; + struct RxD3 *rxdp3; mac_control = &sp->mac_control; for (j = 0 ; j < rxd_count[sp->rxd_mode]; j++) { @@ -2526,40 +2500,30 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) continue; } if (sp->rxd_mode == RXD_MODE_1) { + rxdp1 = (struct RxD1*)rxdp; pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD1*)rxdp)->Buffer0_ptr, - dev->mtu + - HEADER_ETHERNET_II_802_3_SIZE - + HEADER_802_2_SIZE + - HEADER_SNAP_SIZE, - PCI_DMA_FROMDEVICE); + rxdp1->Buffer0_ptr, + dev->mtu + + HEADER_ETHERNET_II_802_3_SIZE + + HEADER_802_2_SIZE + + HEADER_SNAP_SIZE, + PCI_DMA_FROMDEVICE); memset(rxdp, 0, sizeof(struct RxD1)); } else if(sp->rxd_mode == RXD_MODE_3B) { + rxdp3 = (struct RxD3*)rxdp; ba = &mac_control->rings[ring_no]. ba[blk][j]; pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer0_ptr, - BUF0_LEN, - PCI_DMA_FROMDEVICE); - pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer1_ptr, - BUF1_LEN, - PCI_DMA_FROMDEVICE); - pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer2_ptr, - dev->mtu + 4, - PCI_DMA_FROMDEVICE); - memset(rxdp, 0, sizeof(struct RxD3)); - } else { - pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN, + rxdp3->Buffer0_ptr, + BUF0_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer1_ptr, - l3l4hdr_size + 4, + rxdp3->Buffer1_ptr, + BUF1_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(sp->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer2_ptr, dev->mtu, + rxdp3->Buffer2_ptr, + dev->mtu + 4, PCI_DMA_FROMDEVICE); memset(rxdp, 0, sizeof(struct RxD3)); } @@ -2756,6 +2720,8 @@ static void rx_intr_handler(struct ring_info *ring_data) struct sk_buff *skb; int pkt_cnt = 0; int i; + struct RxD1* rxdp1; + struct RxD3* rxdp3; spin_lock(&nic->rx_lock); if (atomic_read(&nic->card_state) == CARD_DOWN) { @@ -2796,32 +2762,23 @@ static void rx_intr_handler(struct ring_info *ring_data) return; } if (nic->rxd_mode == RXD_MODE_1) { + rxdp1 = (struct RxD1*)rxdp; pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD1*)rxdp)->Buffer0_ptr, - dev->mtu + - HEADER_ETHERNET_II_802_3_SIZE + - HEADER_802_2_SIZE + - HEADER_SNAP_SIZE, - PCI_DMA_FROMDEVICE); + rxdp1->Buffer0_ptr, + dev->mtu + + HEADER_ETHERNET_II_802_3_SIZE + + HEADER_802_2_SIZE + + HEADER_SNAP_SIZE, + PCI_DMA_FROMDEVICE); } else if (nic->rxd_mode == RXD_MODE_3B) { + rxdp3 = (struct RxD3*)rxdp; pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer0_ptr, - BUF0_LEN, PCI_DMA_FROMDEVICE); - pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer2_ptr, - dev->mtu + 4, - PCI_DMA_FROMDEVICE); - } else { - pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN, - PCI_DMA_FROMDEVICE); - pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer1_ptr, - l3l4hdr_size + 4, - PCI_DMA_FROMDEVICE); + rxdp3->Buffer0_ptr, + BUF0_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(nic->pdev, (dma_addr_t) - ((struct RxD3*)rxdp)->Buffer2_ptr, - dev->mtu, PCI_DMA_FROMDEVICE); + rxdp3->Buffer2_ptr, + dev->mtu + 4, + PCI_DMA_FROMDEVICE); } prefetch(skb->data); rx_osm_handler(ring_data, rxdp); @@ -3425,23 +3382,8 @@ static void s2io_reset(struct s2io_nic * sp) /* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */ pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd)); - if (sp->device_type == XFRAME_II_DEVICE) { - int ret; - ret = pci_set_power_state(sp->pdev, 3); - if (!ret) - ret = pci_set_power_state(sp->pdev, 0); - else { - DBG_PRINT(ERR_DBG,"%s PME based SW_Reset failed!\n", - __FUNCTION__); - goto old_way; - } - msleep(20); - goto new_way; - } -old_way: val64 = SW_RESET_ALL; writeq(val64, &bar0->sw_reset); -new_way: if (strstr(sp->product_name, "CX4")) { msleep(750); } @@ -3731,56 +3673,6 @@ static void store_xmsi_data(struct s2io_nic *nic) } } -int s2io_enable_msi(struct s2io_nic *nic) -{ - struct XENA_dev_config __iomem *bar0 = nic->bar0; - u16 msi_ctrl, msg_val; - struct config_param *config = &nic->config; - struct net_device *dev = nic->dev; - u64 val64, tx_mat, rx_mat; - int i, err; - - val64 = readq(&bar0->pic_control); - val64 &= ~BIT(1); - writeq(val64, &bar0->pic_control); - - err = pci_enable_msi(nic->pdev); - if (err) { - DBG_PRINT(ERR_DBG, "%s: enabling MSI failed\n", - nic->dev->name); - return err; - } - - /* - * Enable MSI and use MSI-1 in stead of the standard MSI-0 - * for interrupt handling. - */ - pci_read_config_word(nic->pdev, 0x4c, &msg_val); - msg_val ^= 0x1; - pci_write_config_word(nic->pdev, 0x4c, msg_val); - pci_read_config_word(nic->pdev, 0x4c, &msg_val); - - pci_read_config_word(nic->pdev, 0x42, &msi_ctrl); - msi_ctrl |= 0x10; - pci_write_config_word(nic->pdev, 0x42, msi_ctrl); - - /* program MSI-1 into all usable Tx_Mat and Rx_Mat fields */ - tx_mat = readq(&bar0->tx_mat0_n[0]); - for (i=0; i<config->tx_fifo_num; i++) { - tx_mat |= TX_MAT_SET(i, 1); - } - writeq(tx_mat, &bar0->tx_mat0_n[0]); - - rx_mat = readq(&bar0->rx_mat); - for (i=0; i<config->rx_ring_num; i++) { - rx_mat |= RX_MAT_SET(i, 1); - } - writeq(rx_mat, &bar0->rx_mat); - - dev->irq = nic->pdev->irq; - return 0; -} - static int s2io_enable_msi_x(struct s2io_nic *nic) { struct XENA_dev_config __iomem *bar0 = nic->bar0; @@ -4001,6 +3893,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) struct mac_info *mac_control; struct config_param *config; int offload_type; + struct swStat *stats = &sp->mac_control.stats_info->sw_stat; mac_control = &sp->mac_control; config = &sp->config; @@ -4085,11 +3978,18 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Buffer_Pointer = pci_map_single(sp->pdev, sp->ufo_in_band_v, sizeof(u64), PCI_DMA_TODEVICE); + if((txdp->Buffer_Pointer == 0) || + (txdp->Buffer_Pointer == DMA_ERROR_CODE)) + goto pci_map_failed; txdp++; } txdp->Buffer_Pointer = pci_map_single (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); + if((txdp->Buffer_Pointer == 0) || + (txdp->Buffer_Pointer == DMA_ERROR_CODE)) + goto pci_map_failed; + txdp->Host_Control = (unsigned long) skb; txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); if (offload_type == SKB_GSO_UDP) @@ -4146,6 +4046,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&sp->tx_lock, flags); return 0; +pci_map_failed: + stats->pci_map_fail_cnt++; + netif_stop_queue(dev); + stats->mem_freed += skb->truesize; + dev_kfree_skb(skb); + spin_unlock_irqrestore(&sp->tx_lock, flags); + return 0; } static void @@ -4186,39 +4093,6 @@ static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n) return 0; } -static irqreturn_t s2io_msi_handle(int irq, void *dev_id) -{ - struct net_device *dev = (struct net_device *) dev_id; - struct s2io_nic *sp = dev->priv; - int i; - struct mac_info *mac_control; - struct config_param *config; - - atomic_inc(&sp->isr_cnt); - mac_control = &sp->mac_control; - config = &sp->config; - DBG_PRINT(INTR_DBG, "%s: MSI handler\n", __FUNCTION__); - - /* If Intr is because of Rx Traffic */ - for (i = 0; i < config->rx_ring_num; i++) - rx_intr_handler(&mac_control->rings[i]); - - /* If Intr is because of Tx Traffic */ - for (i = 0; i < config->tx_fifo_num; i++) - tx_intr_handler(&mac_control->fifos[i]); - - /* - * If the Rx buffer count is below the panic threshold then - * reallocate the buffers from the interrupt handler itself, - * else schedule a tasklet to reallocate the buffers. - */ - for (i = 0; i < config->rx_ring_num; i++) - s2io_chk_rx_buffers(sp, i); - - atomic_dec(&sp->isr_cnt); - return IRQ_HANDLED; -} - static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) { struct ring_info *ring = (struct ring_info *)dev_id; @@ -4927,19 +4801,17 @@ static void s2io_ethtool_gringparam(struct net_device *dev, ering->rx_max_pending = MAX_RX_DESC_1; else if (sp->rxd_mode == RXD_MODE_3B) ering->rx_max_pending = MAX_RX_DESC_2; - else if (sp->rxd_mode == RXD_MODE_3A) - ering->rx_max_pending = MAX_RX_DESC_3; ering->tx_max_pending = MAX_TX_DESC; - for (i = 0 ; i < sp->config.tx_fifo_num ; i++) { + for (i = 0 ; i < sp->config.tx_fifo_num ; i++) tx_desc_count += sp->config.tx_cfg[i].fifo_len; - } + DBG_PRINT(INFO_DBG,"\nmax txds : %d\n",sp->config.max_txds); ering->tx_pending = tx_desc_count; rx_desc_count = 0; - for (i = 0 ; i < sp->config.rx_ring_num ; i++) { + for (i = 0 ; i < sp->config.rx_ring_num ; i++) rx_desc_count += sp->config.rx_cfg[i].num_rxd; - } + ering->rx_pending = rx_desc_count; ering->rx_mini_max_pending = 0; @@ -5923,6 +5795,7 @@ static void s2io_get_ethtool_stats(struct net_device *dev, else tmp_stats[i++] = 0; tmp_stats[i++] = stat_info->sw_stat.mem_alloc_fail_cnt; + tmp_stats[i++] = stat_info->sw_stat.pci_map_fail_cnt; tmp_stats[i++] = stat_info->sw_stat.watchdog_timer_cnt; tmp_stats[i++] = stat_info->sw_stat.mem_allocated; tmp_stats[i++] = stat_info->sw_stat.mem_freed; @@ -6266,9 +6139,10 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, u64 *temp2, int size) { struct net_device *dev = sp->dev; - struct sk_buff *frag_list; + struct swStat *stats = &sp->mac_control.stats_info->sw_stat; if ((sp->rxd_mode == RXD_MODE_1) && (rxdp->Host_Control == 0)) { + struct RxD1 *rxdp1 = (struct RxD1 *)rxdp; /* allocate skb */ if (*skb) { DBG_PRINT(INFO_DBG, "SKB is not NULL\n"); @@ -6277,7 +6151,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, * using same mapped address for the Rxd * buffer pointer */ - ((struct RxD1*)rxdp)->Buffer0_ptr = *temp0; + rxdp1->Buffer0_ptr = *temp0; } else { *skb = dev_alloc_skb(size); if (!(*skb)) { @@ -6294,18 +6168,23 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, * such it will be used for next rxd whose * Host Control is NULL */ - ((struct RxD1*)rxdp)->Buffer0_ptr = *temp0 = + rxdp1->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, (*skb)->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); + if( (rxdp1->Buffer0_ptr == 0) || + (rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) { + goto memalloc_failed; + } rxdp->Host_Control = (unsigned long) (*skb); } } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { + struct RxD3 *rxdp3 = (struct RxD3 *)rxdp; /* Two buffer Mode */ if (*skb) { - ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2; - ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0; - ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1; + rxdp3->Buffer2_ptr = *temp2; + rxdp3->Buffer0_ptr = *temp0; + rxdp3->Buffer1_ptr = *temp1; } else { *skb = dev_alloc_skb(size); if (!(*skb)) { @@ -6318,73 +6197,47 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, } sp->mac_control.stats_info->sw_stat.mem_allocated += (*skb)->truesize; - ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 = + rxdp3->Buffer2_ptr = *temp2 = pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 = + if( (rxdp3->Buffer2_ptr == 0) || + (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) { + goto memalloc_failed; + } + rxdp3->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); + if( (rxdp3->Buffer0_ptr == 0) || + (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) { + pci_unmap_single (sp->pdev, + (dma_addr_t)(*skb)->data, + dev->mtu + 4, PCI_DMA_FROMDEVICE); + goto memalloc_failed; + } rxdp->Host_Control = (unsigned long) (*skb); /* Buffer-1 will be dummy buffer not used */ - ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 = + rxdp3->Buffer1_ptr = *temp1 = pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, - PCI_DMA_FROMDEVICE); - } - } else if ((rxdp->Host_Control == 0)) { - /* Three buffer mode */ - if (*skb) { - ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0; - ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1; - ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2; - } else { - *skb = dev_alloc_skb(size); - if (!(*skb)) { - DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name); - DBG_PRINT(INFO_DBG, "memory to allocate "); - DBG_PRINT(INFO_DBG, "3 buf mode SKBs\n"); - sp->mac_control.stats_info->sw_stat. \ - mem_alloc_fail_cnt++; - return -ENOMEM; - } - sp->mac_control.stats_info->sw_stat.mem_allocated - += (*skb)->truesize; - ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 = - pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN, - PCI_DMA_FROMDEVICE); - /* Buffer-1 receives L3/L4 headers */ - ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 = - pci_map_single( sp->pdev, (*skb)->data, - l3l4hdr_size + 4, PCI_DMA_FROMDEVICE); - /* - * skb_shinfo(skb)->frag_list will have L4 - * data payload - */ - skb_shinfo(*skb)->frag_list = dev_alloc_skb(dev->mtu + - ALIGN_SIZE); - if (skb_shinfo(*skb)->frag_list == NULL) { - DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb \ - failed\n ", dev->name); - sp->mac_control.stats_info->sw_stat. \ - mem_alloc_fail_cnt++; - return -ENOMEM ; + if( (rxdp3->Buffer1_ptr == 0) || + (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { + pci_unmap_single (sp->pdev, + (dma_addr_t)(*skb)->data, + dev->mtu + 4, PCI_DMA_FROMDEVICE); + goto memalloc_failed; } - frag_list = skb_shinfo(*skb)->frag_list; - frag_list->next = NULL; - sp->mac_control.stats_info->sw_stat.mem_allocated - += frag_list->truesize; - /* - * Buffer-2 receives L4 data payload - */ - ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 = - pci_map_single( sp->pdev, frag_list->data, - dev->mtu, PCI_DMA_FROMDEVICE); } } return 0; + memalloc_failed: + stats->pci_map_fail_cnt++; + stats->mem_freed += (*skb)->truesize; + dev_kfree_skb(*skb); + return -ENOMEM; } + static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp, int size) { @@ -6395,10 +6248,6 @@ static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp, rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); rxdp->Control_2 |= SET_BUFFER2_SIZE_3( dev->mtu + 4); - } else { - rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); - rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4); - rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu); } } @@ -6420,8 +6269,6 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp) size += NET_IP_ALIGN; else if (sp->rxd_mode == RXD_MODE_3B) size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4; - else - size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4; for (i = 0; i < config->rx_ring_num; i++) { blk_cnt = config->rx_cfg[i].num_rxd / @@ -6431,7 +6278,7 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp) for (k = 0; k < rxd_count[sp->rxd_mode]; k++) { rxdp = mac_control->rings[i]. rx_blocks[j].rxds[k].virt_addr; - if(sp->rxd_mode >= RXD_MODE_3A) + if(sp->rxd_mode == RXD_MODE_3B) ba = &mac_control->rings[i].ba[j][k]; if (set_rxd_buffer_pointer(sp, rxdp, ba, &skb,(u64 *)&temp0_64, @@ -6458,9 +6305,7 @@ static int s2io_add_isr(struct s2io_nic * sp) struct net_device *dev = sp->dev; int err = 0; - if (sp->intr_type == MSI) - ret = s2io_enable_msi(sp); - else if (sp->intr_type == MSI_X) + if (sp->intr_type == MSI_X) ret = s2io_enable_msi_x(sp); if (ret) { DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name); @@ -6471,16 +6316,6 @@ static int s2io_add_isr(struct s2io_nic * sp) store_xmsi_data(sp); /* After proper initialization of H/W, register ISR */ - if (sp->intr_type == MSI) { - err = request_irq((int) sp->pdev->irq, s2io_msi_handle, - IRQF_SHARED, sp->name, dev); - if (err) { - pci_disable_msi(sp->pdev); - DBG_PRINT(ERR_DBG, "%s: MSI registration failed\n", - dev->name); - return -1; - } - } if (sp->intr_type == MSI_X) { int i, msix_tx_cnt=0,msix_rx_cnt=0; @@ -6567,14 +6402,6 @@ static void s2io_rem_isr(struct s2io_nic * sp) pci_disable_msix(sp->pdev); } else { free_irq(sp->pdev->irq, dev); - if (sp->intr_type == MSI) { - u16 val; - - pci_disable_msi(sp->pdev); - pci_read_config_word(sp->pdev, 0x4c, &val); - val ^= 0x1; - pci_write_config_word(sp->pdev, 0x4c, val); - } } /* Waiting till all Interrupt handlers are complete */ cnt = 0; @@ -6907,6 +6734,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) } /* Updating statistics */ + sp->stats.rx_packets++; rxdp->Host_Control = 0; if (sp->rxd_mode == RXD_MODE_1) { int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2); @@ -6914,7 +6742,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) sp->stats.rx_bytes += len; skb_put(skb, len); - } else if (sp->rxd_mode >= RXD_MODE_3A) { + } else if (sp->rxd_mode == RXD_MODE_3B) { int get_block = ring_data->rx_curr_get_info.block_index; int get_off = ring_data->rx_curr_get_info.offset; int buf0_len = RXD_GET_BUFFER0_SIZE_3(rxdp->Control_2); @@ -6924,18 +6752,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) struct buffAdd *ba = &ring_data->ba[get_block][get_off]; sp->stats.rx_bytes += buf0_len + buf2_len; memcpy(buff, ba->ba_0, buf0_len); - - if (sp->rxd_mode == RXD_MODE_3A) { - int buf1_len = RXD_GET_BUFFER1_SIZE_3(rxdp->Control_2); - - skb_put(skb, buf1_len); - skb->len += buf2_len; - skb->data_len += buf2_len; - skb_put(skb_shinfo(skb)->frag_list, buf2_len); - sp->stats.rx_bytes += buf1_len; - - } else - skb_put(skb, buf2_len); + skb_put(skb, buf2_len); } if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && ((!sp->lro) || @@ -7131,7 +6948,7 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) *dev_intr_type = INTA; } #else - if (*dev_intr_type > MSI_X) { + if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " "Defaulting to INTA\n"); *dev_intr_type = INTA; @@ -7145,10 +6962,10 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) *dev_intr_type = INTA; } - if (rx_ring_mode > 3) { + if ((rx_ring_mode != 1) && (rx_ring_mode != 2)) { DBG_PRINT(ERR_DBG, "s2io: Requested ring mode not supported\n"); - DBG_PRINT(ERR_DBG, "s2io: Defaulting to 3-buffer mode\n"); - rx_ring_mode = 3; + DBG_PRINT(ERR_DBG, "s2io: Defaulting to 1-buffer mode\n"); + rx_ring_mode = 1; } return SUCCESS; } @@ -7240,28 +7057,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) pci_disable_device(pdev); return -ENOMEM; } - if (dev_intr_type != MSI_X) { - if (pci_request_regions(pdev, s2io_driver_name)) { - DBG_PRINT(ERR_DBG, "Request Regions failed\n"); - pci_disable_device(pdev); - return -ENODEV; - } - } - else { - if (!(request_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0), s2io_driver_name))) { - DBG_PRINT(ERR_DBG, "bar0 Request Regions failed\n"); - pci_disable_device(pdev); - return -ENODEV; - } - if (!(request_mem_region(pci_resource_start(pdev, 2), - pci_resource_len(pdev, 2), s2io_driver_name))) { - DBG_PRINT(ERR_DBG, "bar1 Request Regions failed\n"); - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - pci_disable_device(pdev); - return -ENODEV; - } + if ((ret = pci_request_regions(pdev, s2io_driver_name))) { + DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __FUNCTION__, ret); + pci_disable_device(pdev); + return -ENODEV; } dev = alloc_etherdev(sizeof(struct s2io_nic)); @@ -7288,8 +7087,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) sp->rxd_mode = RXD_MODE_1; if (rx_ring_mode == 2) sp->rxd_mode = RXD_MODE_3B; - if (rx_ring_mode == 3) - sp->rxd_mode = RXD_MODE_3A; sp->intr_type = dev_intr_type; @@ -7565,10 +7362,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) DBG_PRINT(ERR_DBG, "%s: 2-Buffer receive mode enabled\n", dev->name); break; - case RXD_MODE_3A: - DBG_PRINT(ERR_DBG, "%s: 3-Buffer receive mode enabled\n", - dev->name); - break; } if (napi) @@ -7577,9 +7370,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) case INTA: DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name); break; - case MSI: - DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI\n", dev->name); - break; case MSI_X: DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name); break; @@ -7619,14 +7409,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) mem_alloc_failed: free_shared_mem(sp); pci_disable_device(pdev); - if (dev_intr_type != MSI_X) - pci_release_regions(pdev); - else { - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - release_mem_region(pci_resource_start(pdev, 2), - pci_resource_len(pdev, 2)); - } + pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); free_netdev(dev); @@ -7661,14 +7444,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev) free_shared_mem(sp); iounmap(sp->bar0); iounmap(sp->bar1); - if (sp->intr_type != MSI_X) - pci_release_regions(pdev); - else { - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - release_mem_region(pci_resource_start(pdev, 2), - pci_resource_len(pdev, 2)); - } + pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); free_netdev(dev); pci_disable_device(pdev); diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 3887fe63a90..92983ee7df8 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -74,6 +74,10 @@ static int debug_level = ERR_DBG; /* DEBUG message print. */ #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) +#ifndef DMA_ERROR_CODE +#define DMA_ERROR_CODE (~(dma_addr_t)0x0) +#endif + /* Protocol assist features of the NIC */ #define L3_CKSUM_OK 0xFFFF #define L4_CKSUM_OK 0xFFFF @@ -97,6 +101,7 @@ struct swStat { unsigned long long num_aggregations; /* Other statistics */ unsigned long long mem_alloc_fail_cnt; + unsigned long long pci_map_fail_cnt; unsigned long long watchdog_timer_cnt; unsigned long long mem_allocated; unsigned long long mem_freed; @@ -575,8 +580,7 @@ struct RxD_block { #define SIZE_OF_BLOCK 4096 #define RXD_MODE_1 0 /* One Buffer mode */ -#define RXD_MODE_3A 1 /* Three Buffer mode */ -#define RXD_MODE_3B 2 /* Two Buffer mode */ +#define RXD_MODE_3B 1 /* Two Buffer mode */ /* Structure to hold virtual addresses of Buf0 and Buf1 in * 2buf mode. */ @@ -876,7 +880,6 @@ struct s2io_nic { u16 lro_max_aggr_per_sess; #define INTA 0 -#define MSI 1 #define MSI_X 2 u8 intr_type; @@ -1020,8 +1023,6 @@ static int s2io_poll(struct net_device *dev, int *budget); static void s2io_init_pci(struct s2io_nic * sp); static int s2io_set_mac_addr(struct net_device *dev, u8 * addr); static void s2io_alarm_handle(unsigned long data); -static int s2io_enable_msi(struct s2io_nic *nic); -static irqreturn_t s2io_msi_handle(int irq, void *dev_id); static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id); static irqreturn_t diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index a05fd97e5bc..04cba6bf3d5 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -768,11 +768,13 @@ done: static void write_bulk_callback(struct urb *urb) { pegasus_t *pegasus = urb->context; - struct net_device *net = pegasus->net; + struct net_device *net; if (!pegasus) return; + net = pegasus->net; + if (!netif_device_present(net) || !netif_running(net)) return; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index fba319d6fcc..1ee9cd9c86e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1517,7 +1517,7 @@ EXPORT_SYMBOL(pcie_get_readrq); /** * pcie_set_readrq - set PCI Express maximum memory read request * @dev: PCI device to query - * @count: maximum memory read count in bytes + * @rq: maximum memory read count in bytes * valid values are 128, 256, 512, 1024, 2048, 4096 * * If possible sets maximum read byte count diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index befff5f9d58..ac49b15fa76 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_USB_SISUSBVGA) += misc/ obj-$(CONFIG_USB_TEST) += misc/ obj-$(CONFIG_USB_TRANCEVIBRATOR)+= misc/ obj-$(CONFIG_USB_USS720) += misc/ +obj-$(CONFIG_USB_IOWARRIOR) += misc/ obj-$(CONFIG_USB_ATM) += atm/ obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 25f63f1096b..b6bd05e3d43 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -18,9 +18,17 @@ #include "hcd.h" /* for usbcore internals */ #include "usb.h" +struct api_context { + struct completion done; + int status; +}; + static void usb_api_blocking_completion(struct urb *urb) { - complete((struct completion *)urb->context); + struct api_context *ctx = urb->context; + + ctx->status = urb->status; + complete(&ctx->done); } @@ -32,20 +40,21 @@ static void usb_api_blocking_completion(struct urb *urb) */ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) { - struct completion done; + struct api_context ctx; unsigned long expire; int retval; - int status = urb->status; - init_completion(&done); - urb->context = &done; + init_completion(&ctx.done); + urb->context = &ctx; urb->actual_length = 0; retval = usb_submit_urb(urb, GFP_NOIO); if (unlikely(retval)) goto out; expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; - if (!wait_for_completion_timeout(&done, expire)) { + if (!wait_for_completion_timeout(&ctx.done, expire)) { + usb_kill_urb(urb); + retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); dev_dbg(&urb->dev->dev, "%s timed out on ep%d%s len=%d/%d\n", @@ -54,11 +63,8 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) usb_pipein(urb->pipe) ? "in" : "out", urb->actual_length, urb->transfer_buffer_length); - - usb_kill_urb(urb); - retval = status == -ENOENT ? -ETIMEDOUT : status; } else - retval = status; + retval = ctx.status; out: if (actual_length) *actual_length = urb->actual_length; @@ -411,15 +417,22 @@ int usb_sg_init ( * Some systems need to revert to PIO when DMA is temporarily * unavailable. For their sakes, both transfer_buffer and * transfer_dma are set when possible. However this can only - * work on systems without HIGHMEM, since DMA buffers located - * in high memory are not directly addressable by the CPU for - * PIO ... so when HIGHMEM is in use, transfer_buffer is NULL + * work on systems without: + * + * - HIGHMEM, since DMA buffers located in high memory are + * not directly addressable by the CPU for PIO; + * + * - IOMMU, since dma_map_sg() is allowed to use an IOMMU to + * make virtually discontiguous buffers be "dma-contiguous" + * so that PIO and DMA need diferent numbers of URBs. + * + * So when HIGHMEM or IOMMU are in use, transfer_buffer is NULL * to prevent stale pointers and to help spot bugs. */ if (dma) { io->urbs [i]->transfer_dma = sg_dma_address (sg + i); len = sg_dma_len (sg + i); -#ifdef CONFIG_HIGHMEM +#if defined(CONFIG_HIGHMEM) || defined(CONFIG_IOMMU) io->urbs[i]->transfer_buffer = NULL; #else io->urbs[i]->transfer_buffer = diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index aa21b38a31c..b7917c5a3c6 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -30,18 +30,40 @@ static const struct usb_device_id usb_quirk_list[] = { /* HP 5300/5370C scanner */ { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, + /* Acer Peripherals Inc. (now BenQ Corp.) Prisa 640BU */ + { USB_DEVICE(0x04a5, 0x207e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Benq S2W 3300U */ { USB_DEVICE(0x04a5, 0x20b0), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Canon, Inc. CanoScan N1240U/LiDE30 */ + { USB_DEVICE(0x04a9, 0x220e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Canon, Inc. CanoScan N650U/N656U */ + { USB_DEVICE(0x04a9, 0x2206), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Canon, Inc. CanoScan 1220U */ + { USB_DEVICE(0x04a9, 0x2207), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Canon, Inc. CanoScan N670U/N676U/LiDE 20 */ + { USB_DEVICE(0x04a9, 0x220d), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* old Cannon scanner */ + { USB_DEVICE(0x04a9, 0x2220), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Seiko Epson Corp. Perfection 1200 */ { USB_DEVICE(0x04b8, 0x0104), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Seiko Epson Corp. Perfection 660 */ + { USB_DEVICE(0x04b8, 0x0114), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Epson Perfection 1260 Photo */ + { USB_DEVICE(0x04b8, 0x011d), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Seiko Epson Corp - Perfection 1670 */ { USB_DEVICE(0x04b8, 0x011f), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* EPSON Perfection 2480 */ + { USB_DEVICE(0x04b8, 0x0121), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Seiko Epson Corp.*/ + { USB_DEVICE(0x04b8, 0x0122), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Samsung ML-2510 Series printer */ { USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Elsa MicroLink 56k (V.250) */ { USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Ultima Electronics Corp.*/ { USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Agfa Snapscan1212u */ + { USB_DEVICE(0x06bd, 0x2061), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Umax [hex] Astra 3400U */ { USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index d18901b92cd..c6760aee1e5 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -50,7 +50,7 @@ usb_descriptor_fillbuf(void *buf, unsigned buflen, return -EINVAL; /* fill buffer from src[] until null descriptor ptr */ - for (; 0 != *src; src++) { + for (; NULL != *src; src++) { unsigned len = (*src)->bLength; if (len > buflen) diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 6042364402b..3aa46cfa66b 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -71,7 +71,7 @@ ep_matches ( u16 max; /* endpoint already claimed? */ - if (0 != ep->driver_data) + if (NULL != ep->driver_data) return 0; /* only support ep0 for portable CONTROL traffic */ diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index a3376739a81..593e23507b1 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -1723,7 +1723,8 @@ rx_submit (struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) size += sizeof (struct rndis_packet_msg_type); size -= size % dev->out_ep->maxpacket; - if ((skb = alloc_skb (size + NET_IP_ALIGN, gfp_flags)) == 0) { + skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags); + if (skb == NULL) { DEBUG (dev, "no rx skb\n"); goto enomem; } diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index e60745ffaf8..173004f60fe 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -964,7 +964,7 @@ static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len) } if (len > sizeof (dev->rbuf)) req->buf = kmalloc(len, GFP_ATOMIC); - if (req->buf == 0) { + if (req->buf == NULL) { req->buf = dev->rbuf; return -ENOMEM; } @@ -1394,7 +1394,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) dev->setup_abort = 0; if (dev->state == STATE_DEV_UNCONNECTED) { #ifdef CONFIG_USB_GADGET_DUALSPEED - if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == 0) { + if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == NULL) { spin_unlock(&dev->lock); ERROR (dev, "no high speed config??\n"); return -EINVAL; diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 700dda8a915..4b27d12f049 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1299,7 +1299,7 @@ static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req, req->req.actual = 0; req->req.status = -EINPROGRESS; - if (ep->desc == 0) /* control */ + if (ep->desc == NULL) /* control */ start_ep0(ep, req); else { if (request && !ep->busy) diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 63b9521c132..72b4ebbf132 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -93,8 +93,6 @@ static const char driver_name [] = "pxa2xx_udc"; static const char ep0name [] = "ep0"; -// #define DISABLE_TEST_MODE - #ifdef CONFIG_ARCH_IXP4XX /* cpu-specific register addresses are compiled in to this code */ @@ -113,17 +111,6 @@ static const char ep0name [] = "ep0"; #define SIZE_STR "" #endif -#ifdef DISABLE_TEST_MODE -/* (mode == 0) == no undocumented chip tweaks - * (mode & 1) == double buffer bulk IN - * (mode & 2) == double buffer bulk OUT - * ... so mode = 3 (or 7, 15, etc) does it for both - */ -static ushort fifo_mode = 0; -module_param(fifo_mode, ushort, 0); -MODULE_PARM_DESC (fifo_mode, "pxa2xx udc fifo mode"); -#endif - /* --------------------------------------------------------------------------- * endpoint related parts of the api to the usb controller hardware, * used by gadget driver; and the inner talker-to-hardware core. @@ -1252,23 +1239,6 @@ static void udc_enable (struct pxa2xx_udc *dev) UDC_RES2 = 0x00; } -#ifdef DISABLE_TEST_MODE - /* "test mode" seems to have become the default in later chip - * revs, preventing double buffering (and invalidating docs). - * this EXPERIMENT enables it for bulk endpoints by tweaking - * undefined/reserved register bits (that other drivers clear). - * Belcarra code comments noted this usage. - */ - if (fifo_mode & 1) { /* IN endpoints */ - UDC_RES1 |= USIR0_IR1|USIR0_IR6; - UDC_RES2 |= USIR1_IR11; - } - if (fifo_mode & 2) { /* OUT endpoints */ - UDC_RES1 |= USIR0_IR2|USIR0_IR7; - UDC_RES2 |= USIR1_IR12; - } -#endif - /* enable suspend/resume and reset irqs */ udc_clear_mask_UDCCR(UDCCR_SRM | UDCCR_REM); diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index a2e6e3fc8c8..fcfe869acb9 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -653,7 +653,8 @@ set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags) result = usb_ep_enable (ep, d); if (result == 0) { ep->driver_data = dev; - if (source_sink_start_ep (ep, gfp_flags) != 0) { + if (source_sink_start_ep(ep, gfp_flags) + != NULL) { dev->in_ep = ep; continue; } @@ -667,7 +668,8 @@ set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags) result = usb_ep_enable (ep, d); if (result == 0) { ep->driver_data = dev; - if (source_sink_start_ep (ep, gfp_flags) != 0) { + if (source_sink_start_ep(ep, gfp_flags) + != NULL) { dev->out_ep = ep; continue; } diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index e831cb7f64f..33f6ee50b8d 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -356,7 +356,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) dbg("%s - port %d", __FUNCTION__, port->number); - if ((!port->tty) || (!port->tty->termios)) { + if (!port->tty || !port->tty->termios) { dbg("%s - no tty structures", __FUNCTION__); return; } @@ -526,50 +526,35 @@ static void cp2101_set_termios (struct usb_serial_port *port, return; } cflag = port->tty->termios->c_cflag; - - /* Check that they really want us to change something */ - if (old_termios) { - if ((cflag == old_termios->c_cflag) && - (RELEVANT_IFLAG(port->tty->termios->c_iflag) - == RELEVANT_IFLAG(old_termios->c_iflag))) { - dbg("%s - nothing to change...", __FUNCTION__); - return; - } - - old_cflag = old_termios->c_cflag; - } + old_cflag = old_termios->c_cflag; + baud = tty_get_baud_rate(port->tty); /* If the baud rate is to be updated*/ - if ((cflag & CBAUD) != (old_cflag & CBAUD)) { - switch (cflag & CBAUD) { - /* - * The baud rates which are commented out below - * appear to be supported by the device - * but are non-standard - */ - case B0: baud = 0; break; - case B600: baud = 600; break; - case B1200: baud = 1200; break; - case B1800: baud = 1800; break; - case B2400: baud = 2400; break; - case B4800: baud = 4800; break; - /*case B7200: baud = 7200; break;*/ - case B9600: baud = 9600; break; - /*ase B14400: baud = 14400; break;*/ - case B19200: baud = 19200; break; - /*case B28800: baud = 28800; break;*/ - case B38400: baud = 38400; break; - /*case B55854: baud = 55054; break;*/ - case B57600: baud = 57600; break; - case B115200: baud = 115200; break; - /*case B127117: baud = 127117; break;*/ - case B230400: baud = 230400; break; - case B460800: baud = 460800; break; - case B921600: baud = 921600; break; - /*case B3686400: baud = 3686400; break;*/ + if (baud != tty_termios_baud_rate(old_termios)) { + switch (baud) { + case 0: + case 600: + case 1200: + case 1800: + case 2400: + case 4800: + case 7200: + case 9600: + case 14400: + case 19200: + case 28800: + case 38400: + case 55854: + case 57600: + case 115200: + case 127117: + case 230400: + case 460800: + case 921600: + case 3686400: + break; default: - dev_err(&port->dev, "cp2101 driver does not " - "support the baudrate requested\n"); + baud = 9600; break; } diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 976f54ec26e..dab2e66d111 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -433,38 +433,38 @@ struct digi_port { /* Local Function Declarations */ -static void digi_wakeup_write( struct usb_serial_port *port ); +static void digi_wakeup_write(struct usb_serial_port *port); static void digi_wakeup_write_lock(struct work_struct *work); -static int digi_write_oob_command( struct usb_serial_port *port, - unsigned char *buf, int count, int interruptible ); -static int digi_write_inb_command( struct usb_serial_port *port, - unsigned char *buf, int count, unsigned long timeout ); -static int digi_set_modem_signals( struct usb_serial_port *port, - unsigned int modem_signals, int interruptible ); -static int digi_transmit_idle( struct usb_serial_port *port, - unsigned long timeout ); +static int digi_write_oob_command(struct usb_serial_port *port, + unsigned char *buf, int count, int interruptible); +static int digi_write_inb_command(struct usb_serial_port *port, + unsigned char *buf, int count, unsigned long timeout); +static int digi_set_modem_signals(struct usb_serial_port *port, + unsigned int modem_signals, int interruptible); +static int digi_transmit_idle(struct usb_serial_port *port, + unsigned long timeout); static void digi_rx_throttle (struct usb_serial_port *port); static void digi_rx_unthrottle (struct usb_serial_port *port); -static void digi_set_termios( struct usb_serial_port *port, - struct ktermios *old_termios ); -static void digi_break_ctl( struct usb_serial_port *port, int break_state ); -static int digi_ioctl( struct usb_serial_port *port, struct file *file, - unsigned int cmd, unsigned long arg ); -static int digi_tiocmget( struct usb_serial_port *port, struct file *file ); -static int digi_tiocmset( struct usb_serial_port *port, struct file *file, - unsigned int set, unsigned int clear ); -static int digi_write( struct usb_serial_port *port, const unsigned char *buf, int count ); -static void digi_write_bulk_callback( struct urb *urb ); -static int digi_write_room( struct usb_serial_port *port ); -static int digi_chars_in_buffer( struct usb_serial_port *port ); -static int digi_open( struct usb_serial_port *port, struct file *filp ); -static void digi_close( struct usb_serial_port *port, struct file *filp ); -static int digi_startup_device( struct usb_serial *serial ); -static int digi_startup( struct usb_serial *serial ); -static void digi_shutdown( struct usb_serial *serial ); -static void digi_read_bulk_callback( struct urb *urb ); -static int digi_read_inb_callback( struct urb *urb ); -static int digi_read_oob_callback( struct urb *urb ); +static void digi_set_termios(struct usb_serial_port *port, + struct ktermios *old_termios); +static void digi_break_ctl(struct usb_serial_port *port, int break_state); +static int digi_ioctl(struct usb_serial_port *port, struct file *file, + unsigned int cmd, unsigned long arg); +static int digi_tiocmget(struct usb_serial_port *port, struct file *file); +static int digi_tiocmset(struct usb_serial_port *port, struct file *file, + unsigned int set, unsigned int clear); +static int digi_write(struct usb_serial_port *port, const unsigned char *buf, int count); +static void digi_write_bulk_callback(struct urb *urb); +static int digi_write_room(struct usb_serial_port *port); +static int digi_chars_in_buffer(struct usb_serial_port *port); +static int digi_open(struct usb_serial_port *port, struct file *filp); +static void digi_close(struct usb_serial_port *port, struct file *filp); +static int digi_startup_device(struct usb_serial *serial); +static int digi_startup(struct usb_serial *serial); +static void digi_shutdown(struct usb_serial *serial); +static void digi_read_bulk_callback(struct urb *urb); +static int digi_read_inb_callback(struct urb *urb); +static int digi_read_oob_callback(struct urb *urb); /* Statics */ @@ -576,9 +576,9 @@ static struct usb_serial_driver digi_acceleport_4_device = { * with the equivalent code. */ -static inline long cond_wait_interruptible_timeout_irqrestore( +static long cond_wait_interruptible_timeout_irqrestore( wait_queue_head_t *q, long timeout, - spinlock_t *lock, unsigned long flags ) + spinlock_t *lock, unsigned long flags) { DEFINE_WAIT(wait); @@ -600,18 +600,16 @@ static inline long cond_wait_interruptible_timeout_irqrestore( static void digi_wakeup_write_lock(struct work_struct *work) { - struct digi_port *priv = - container_of(work, struct digi_port, dp_wakeup_work); + struct digi_port *priv = container_of(work, struct digi_port, dp_wakeup_work); struct usb_serial_port *port = priv->dp_port; unsigned long flags; - - spin_lock_irqsave( &priv->dp_port_lock, flags ); - digi_wakeup_write( port ); - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); + digi_wakeup_write(port); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); } -static void digi_wakeup_write( struct usb_serial_port *port ) +static void digi_wakeup_write(struct usb_serial_port *port) { tty_wakeup(port->tty); } @@ -628,8 +626,8 @@ static void digi_wakeup_write( struct usb_serial_port *port ) * returned by usb_submit_urb. */ -static int digi_write_oob_command( struct usb_serial_port *port, - unsigned char *buf, int count, int interruptible ) +static int digi_write_oob_command(struct usb_serial_port *port, + unsigned char *buf, int count, int interruptible) { int ret = 0; @@ -638,49 +636,37 @@ static int digi_write_oob_command( struct usb_serial_port *port, struct digi_port *oob_priv = usb_get_serial_port_data(oob_port); unsigned long flags = 0; + dbg("digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, count); -dbg( "digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, count ); - - spin_lock_irqsave( &oob_priv->dp_port_lock, flags ); - - while( count > 0 ) { - - while( oob_port->write_urb->status == -EINPROGRESS - || oob_priv->dp_write_urb_in_use ) { + spin_lock_irqsave(&oob_priv->dp_port_lock, flags); + while(count > 0) { + while(oob_port->write_urb->status == -EINPROGRESS + || oob_priv->dp_write_urb_in_use) { cond_wait_interruptible_timeout_irqrestore( &oob_port->write_wait, DIGI_RETRY_TIMEOUT, - &oob_priv->dp_port_lock, flags ); - if( interruptible && signal_pending(current) ) { - return( -EINTR ); - } - spin_lock_irqsave( &oob_priv->dp_port_lock, flags ); + &oob_priv->dp_port_lock, flags); + if (interruptible && signal_pending(current)) + return -EINTR; + spin_lock_irqsave(&oob_priv->dp_port_lock, flags); } /* len must be a multiple of 4, so commands are not split */ - len = min(count, oob_port->bulk_out_size ); - if( len > 4 ) + len = min(count, oob_port->bulk_out_size); + if (len > 4) len &= ~3; - - memcpy( oob_port->write_urb->transfer_buffer, buf, len ); + memcpy(oob_port->write_urb->transfer_buffer, buf, len); oob_port->write_urb->transfer_buffer_length = len; oob_port->write_urb->dev = port->serial->dev; - - if( (ret=usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0 ) { + if ((ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0) { oob_priv->dp_write_urb_in_use = 1; count -= len; buf += len; } - - } - - spin_unlock_irqrestore( &oob_priv->dp_port_lock, flags ); - - if( ret ) { - err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, - ret ); } - - return( ret ); + spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags); + if (ret) + err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, ret); + return ret; } @@ -697,63 +683,58 @@ dbg( "digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, co * error returned by digi_write. */ -static int digi_write_inb_command( struct usb_serial_port *port, - unsigned char *buf, int count, unsigned long timeout ) +static int digi_write_inb_command(struct usb_serial_port *port, + unsigned char *buf, int count, unsigned long timeout) { - int ret = 0; int len; struct digi_port *priv = usb_get_serial_port_data(port); unsigned char *data = port->write_urb->transfer_buffer; unsigned long flags = 0; + dbg("digi_write_inb_command: TOP: port=%d, count=%d", + priv->dp_port_num, count); -dbg( "digi_write_inb_command: TOP: port=%d, count=%d", priv->dp_port_num, -count ); - - if( timeout ) + if (timeout) timeout += jiffies; else timeout = ULONG_MAX; - spin_lock_irqsave( &priv->dp_port_lock, flags ); - - while( count > 0 && ret == 0 ) { - - while( (port->write_urb->status == -EINPROGRESS - || priv->dp_write_urb_in_use) && time_before(jiffies, timeout)) { + spin_lock_irqsave(&priv->dp_port_lock, flags); + while(count > 0 && ret == 0) { + while((port->write_urb->status == -EINPROGRESS + || priv->dp_write_urb_in_use) && time_before(jiffies, timeout)) { cond_wait_interruptible_timeout_irqrestore( &port->write_wait, DIGI_RETRY_TIMEOUT, - &priv->dp_port_lock, flags ); - if( signal_pending(current) ) { - return( -EINTR ); - } - spin_lock_irqsave( &priv->dp_port_lock, flags ); + &priv->dp_port_lock, flags); + if (signal_pending(current)) + return -EINTR; + spin_lock_irqsave(&priv->dp_port_lock, flags); } /* len must be a multiple of 4 and small enough to */ /* guarantee the write will send buffered data first, */ /* so commands are in order with data and not split */ - len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len ); - if( len > 4 ) + len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len); + if (len > 4) len &= ~3; /* write any buffered data first */ - if( priv->dp_out_buf_len > 0 ) { + if (priv->dp_out_buf_len > 0) { data[0] = DIGI_CMD_SEND_DATA; data[1] = priv->dp_out_buf_len; - memcpy( data+2, priv->dp_out_buf, - priv->dp_out_buf_len ); - memcpy( data+2+priv->dp_out_buf_len, buf, len ); + memcpy(data + 2, priv->dp_out_buf, + priv->dp_out_buf_len); + memcpy(data + 2 + priv->dp_out_buf_len, buf, len); port->write_urb->transfer_buffer_length - = priv->dp_out_buf_len+2+len; + = priv->dp_out_buf_len + 2 + len; } else { - memcpy( data, buf, len ); + memcpy(data, buf, len); port->write_urb->transfer_buffer_length = len; } port->write_urb->dev = port->serial->dev; - if( (ret=usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0 ) { + if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) { priv->dp_write_urb_in_use = 1; priv->dp_out_buf_len = 0; count -= len; @@ -761,16 +742,12 @@ count ); } } + spin_unlock_irqrestore(&priv->dp_port_lock, flags); - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - - if( ret ) { - err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, - ret, priv->dp_port_num ); - } - - return( ret ); - + if (ret) + err("%s: usb_submit_urb failed, ret=%d, port=%d", + __FUNCTION__, ret, priv->dp_port_num); + return ret; } @@ -784,8 +761,8 @@ count ); * returned by usb_submit_urb. */ -static int digi_set_modem_signals( struct usb_serial_port *port, - unsigned int modem_signals, int interruptible ) +static int digi_set_modem_signals(struct usb_serial_port *port, + unsigned int modem_signals, int interruptible) { int ret; @@ -796,60 +773,47 @@ static int digi_set_modem_signals( struct usb_serial_port *port, unsigned long flags = 0; -dbg( "digi_set_modem_signals: TOP: port=%d, modem_signals=0x%x", -port_priv->dp_port_num, modem_signals ); + dbg("digi_set_modem_signals: TOP: port=%d, modem_signals=0x%x", + port_priv->dp_port_num, modem_signals); - spin_lock_irqsave( &oob_priv->dp_port_lock, flags ); - spin_lock( &port_priv->dp_port_lock ); + spin_lock_irqsave(&oob_priv->dp_port_lock, flags); + spin_lock(&port_priv->dp_port_lock); - while( oob_port->write_urb->status == -EINPROGRESS - || oob_priv->dp_write_urb_in_use ) { - spin_unlock( &port_priv->dp_port_lock ); + while(oob_port->write_urb->status == -EINPROGRESS || oob_priv->dp_write_urb_in_use) { + spin_unlock(&port_priv->dp_port_lock); cond_wait_interruptible_timeout_irqrestore( &oob_port->write_wait, DIGI_RETRY_TIMEOUT, - &oob_priv->dp_port_lock, flags ); - if( interruptible && signal_pending(current) ) { - return( -EINTR ); - } - spin_lock_irqsave( &oob_priv->dp_port_lock, flags ); - spin_lock( &port_priv->dp_port_lock ); + &oob_priv->dp_port_lock, flags); + if (interruptible && signal_pending(current)) + return -EINTR; + spin_lock_irqsave(&oob_priv->dp_port_lock, flags); + spin_lock(&port_priv->dp_port_lock); } - data[0] = DIGI_CMD_SET_DTR_SIGNAL; data[1] = port_priv->dp_port_num; - data[2] = (modem_signals&TIOCM_DTR) ? - DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE; + data[2] = (modem_signals&TIOCM_DTR) ? DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE; data[3] = 0; - data[4] = DIGI_CMD_SET_RTS_SIGNAL; data[5] = port_priv->dp_port_num; - data[6] = (modem_signals&TIOCM_RTS) ? - DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE; + data[6] = (modem_signals&TIOCM_RTS) ? DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE; data[7] = 0; oob_port->write_urb->transfer_buffer_length = 8; oob_port->write_urb->dev = port->serial->dev; - if( (ret=usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0 ) { + if ((ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0) { oob_priv->dp_write_urb_in_use = 1; port_priv->dp_modem_signals = (port_priv->dp_modem_signals&~(TIOCM_DTR|TIOCM_RTS)) | (modem_signals&(TIOCM_DTR|TIOCM_RTS)); } - - spin_unlock( &port_priv->dp_port_lock ); - spin_unlock_irqrestore( &oob_priv->dp_port_lock, flags ); - - if( ret ) { - err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, - ret ); - } - - return( ret ); - + spin_unlock(&port_priv->dp_port_lock); + spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags); + if (ret) + err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, ret); + return ret; } - /* * Digi Transmit Idle * @@ -862,203 +826,182 @@ port_priv->dp_port_num, modem_signals ); * port at a time, so its ok. */ -static int digi_transmit_idle( struct usb_serial_port *port, - unsigned long timeout ) +static int digi_transmit_idle(struct usb_serial_port *port, + unsigned long timeout) { - int ret; unsigned char buf[2]; struct digi_port *priv = usb_get_serial_port_data(port); unsigned long flags = 0; - - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); priv->dp_transmit_idle = 0; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); buf[0] = DIGI_CMD_TRANSMIT_IDLE; buf[1] = 0; timeout += jiffies; - if( (ret=digi_write_inb_command( port, buf, 2, timeout-jiffies )) != 0 ) - return( ret ); + if ((ret = digi_write_inb_command(port, buf, 2, timeout - jiffies)) != 0) + return ret; - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); - while( time_before(jiffies, timeout) && !priv->dp_transmit_idle ) { + while(time_before(jiffies, timeout) && !priv->dp_transmit_idle) { cond_wait_interruptible_timeout_irqrestore( &priv->dp_transmit_idle_wait, DIGI_RETRY_TIMEOUT, - &priv->dp_port_lock, flags ); - if( signal_pending(current) ) { - return( -EINTR ); - } - spin_lock_irqsave( &priv->dp_port_lock, flags ); + &priv->dp_port_lock, flags); + if (signal_pending(current)) + return -EINTR; + spin_lock_irqsave(&priv->dp_port_lock, flags); } - priv->dp_transmit_idle = 0; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - - return( 0 ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + return 0; } -static void digi_rx_throttle( struct usb_serial_port *port ) +static void digi_rx_throttle(struct usb_serial_port *port) { - unsigned long flags; struct digi_port *priv = usb_get_serial_port_data(port); -dbg( "digi_rx_throttle: TOP: port=%d", priv->dp_port_num ); + dbg("digi_rx_throttle: TOP: port=%d", priv->dp_port_num); /* stop receiving characters by not resubmitting the read urb */ - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); priv->dp_throttled = 1; priv->dp_throttle_restart = 0; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - + spin_unlock_irqrestore(&priv->dp_port_lock, flags); } -static void digi_rx_unthrottle( struct usb_serial_port *port ) +static void digi_rx_unthrottle(struct usb_serial_port *port) { - int ret = 0; unsigned long flags; struct digi_port *priv = usb_get_serial_port_data(port); -dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num ); + dbg("digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num); - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); /* turn throttle off */ priv->dp_throttled = 0; priv->dp_throttle_restart = 0; /* restart read chain */ - if( priv->dp_throttle_restart ) { + if (priv->dp_throttle_restart) { port->read_urb->dev = port->serial->dev; - ret = usb_submit_urb( port->read_urb, GFP_ATOMIC ); + ret = usb_submit_urb(port->read_urb, GFP_ATOMIC); } - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - - if( ret ) { - err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, - ret, priv->dp_port_num ); - } + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + if (ret) + err("%s: usb_submit_urb failed, ret=%d, port=%d", + __FUNCTION__, ret, priv->dp_port_num); } -static void digi_set_termios( struct usb_serial_port *port, - struct ktermios *old_termios ) +static void digi_set_termios(struct usb_serial_port *port, + struct ktermios *old_termios) { struct digi_port *priv = usb_get_serial_port_data(port); - unsigned int iflag = port->tty->termios->c_iflag; - unsigned int cflag = port->tty->termios->c_cflag; + struct tty_struct *tty = port->tty; + unsigned int iflag = tty->termios->c_iflag; + unsigned int cflag = tty->termios->c_cflag; unsigned int old_iflag = old_termios->c_iflag; unsigned int old_cflag = old_termios->c_cflag; unsigned char buf[32]; unsigned int modem_signals; int arg,ret; int i = 0; + speed_t baud; - -dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, old_cflag=0x%x", priv->dp_port_num, iflag, old_iflag, cflag, old_cflag ); + dbg("digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, old_cflag=0x%x", priv->dp_port_num, iflag, old_iflag, cflag, old_cflag); /* set baud rate */ - if( (cflag&CBAUD) != (old_cflag&CBAUD) ) { - + if ((baud = tty_get_baud_rate(tty)) != tty_termios_baud_rate(old_termios)) { arg = -1; /* reassert DTR and (maybe) RTS on transition from B0 */ - if( (old_cflag&CBAUD) == B0 ) { + if ((old_cflag&CBAUD) == B0) { /* don't set RTS if using hardware flow control */ /* and throttling input */ modem_signals = TIOCM_DTR; - if( !(port->tty->termios->c_cflag & CRTSCTS) || - !test_bit(TTY_THROTTLED, &port->tty->flags) ) { + if (!(tty->termios->c_cflag & CRTSCTS) || + !test_bit(TTY_THROTTLED, &tty->flags)) modem_signals |= TIOCM_RTS; - } - digi_set_modem_signals( port, modem_signals, 1 ); + digi_set_modem_signals(port, modem_signals, 1); } - - switch( (cflag&CBAUD) ) { + switch (baud) { /* drop DTR and RTS on transition to B0 */ - case B0: digi_set_modem_signals( port, 0, 1 ); break; - case B50: arg = DIGI_BAUD_50; break; - case B75: arg = DIGI_BAUD_75; break; - case B110: arg = DIGI_BAUD_110; break; - case B150: arg = DIGI_BAUD_150; break; - case B200: arg = DIGI_BAUD_200; break; - case B300: arg = DIGI_BAUD_300; break; - case B600: arg = DIGI_BAUD_600; break; - case B1200: arg = DIGI_BAUD_1200; break; - case B1800: arg = DIGI_BAUD_1800; break; - case B2400: arg = DIGI_BAUD_2400; break; - case B4800: arg = DIGI_BAUD_4800; break; - case B9600: arg = DIGI_BAUD_9600; break; - case B19200: arg = DIGI_BAUD_19200; break; - case B38400: arg = DIGI_BAUD_38400; break; - case B57600: arg = DIGI_BAUD_57600; break; - case B115200: arg = DIGI_BAUD_115200; break; - case B230400: arg = DIGI_BAUD_230400; break; - case B460800: arg = DIGI_BAUD_460800; break; - default: - dbg( "digi_set_termios: can't handle baud rate 0x%x", - (cflag&CBAUD) ); - break; + case 0: digi_set_modem_signals(port, 0, 1); break; + case 50: arg = DIGI_BAUD_50; break; + case 75: arg = DIGI_BAUD_75; break; + case 110: arg = DIGI_BAUD_110; break; + case 150: arg = DIGI_BAUD_150; break; + case 200: arg = DIGI_BAUD_200; break; + case 300: arg = DIGI_BAUD_300; break; + case 600: arg = DIGI_BAUD_600; break; + case 1200: arg = DIGI_BAUD_1200; break; + case 1800: arg = DIGI_BAUD_1800; break; + case 2400: arg = DIGI_BAUD_2400; break; + case 4800: arg = DIGI_BAUD_4800; break; + case 9600: arg = DIGI_BAUD_9600; break; + case 19200: arg = DIGI_BAUD_19200; break; + case 38400: arg = DIGI_BAUD_38400; break; + case 57600: arg = DIGI_BAUD_57600; break; + case 115200: arg = DIGI_BAUD_115200; break; + case 230400: arg = DIGI_BAUD_230400; break; + case 460800: arg = DIGI_BAUD_460800; break; + default: + arg = DIGI_BAUD_9600; + baud = 9600; + break; } - - if( arg != -1 ) { + if (arg != -1) { buf[i++] = DIGI_CMD_SET_BAUD_RATE; buf[i++] = priv->dp_port_num; buf[i++] = arg; buf[i++] = 0; } - } - /* set parity */ - if( (cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD)) ) { - - if( (cflag&PARENB) ) { - if( (cflag&PARODD) ) + if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) { + if (cflag&PARENB) { + if (cflag&PARODD) arg = DIGI_PARITY_ODD; else arg = DIGI_PARITY_EVEN; } else { arg = DIGI_PARITY_NONE; } - buf[i++] = DIGI_CMD_SET_PARITY; buf[i++] = priv->dp_port_num; buf[i++] = arg; buf[i++] = 0; - } - /* set word size */ - if( (cflag&CSIZE) != (old_cflag&CSIZE) ) { - + if ((cflag&CSIZE) != (old_cflag&CSIZE)) { arg = -1; - - switch( (cflag&CSIZE) ) { + switch (cflag&CSIZE) { case CS5: arg = DIGI_WORD_SIZE_5; break; case CS6: arg = DIGI_WORD_SIZE_6; break; case CS7: arg = DIGI_WORD_SIZE_7; break; case CS8: arg = DIGI_WORD_SIZE_8; break; default: - dbg( "digi_set_termios: can't handle word size %d", - (cflag&CSIZE) ); + dbg("digi_set_termios: can't handle word size %d", + (cflag&CSIZE)); break; } - if( arg != -1 ) { + if (arg != -1) { buf[i++] = DIGI_CMD_SET_WORD_SIZE; buf[i++] = priv->dp_port_num; buf[i++] = arg; @@ -1068,9 +1011,9 @@ dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, ol } /* set stop bits */ - if( (cflag&CSTOPB) != (old_cflag&CSTOPB) ) { + if ((cflag&CSTOPB) != (old_cflag&CSTOPB)) { - if( (cflag&CSTOPB) ) + if ((cflag&CSTOPB)) arg = DIGI_STOP_BITS_2; else arg = DIGI_STOP_BITS_1; @@ -1083,18 +1026,15 @@ dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, ol } /* set input flow control */ - if( (iflag&IXOFF) != (old_iflag&IXOFF) - || (cflag&CRTSCTS) != (old_cflag&CRTSCTS) ) { - + if ((iflag&IXOFF) != (old_iflag&IXOFF) + || (cflag&CRTSCTS) != (old_cflag&CRTSCTS)) { arg = 0; - - if( (iflag&IXOFF) ) + if (iflag&IXOFF) arg |= DIGI_INPUT_FLOW_CONTROL_XON_XOFF; else arg &= ~DIGI_INPUT_FLOW_CONTROL_XON_XOFF; - if( (cflag&CRTSCTS) ) { - + if (cflag&CRTSCTS) { arg |= DIGI_INPUT_FLOW_CONTROL_RTS; /* On USB-4 it is necessary to assert RTS prior */ @@ -1107,43 +1047,37 @@ dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, ol } else { arg &= ~DIGI_INPUT_FLOW_CONTROL_RTS; } - buf[i++] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; buf[i++] = priv->dp_port_num; buf[i++] = arg; buf[i++] = 0; - } /* set output flow control */ - if( (iflag&IXON) != (old_iflag&IXON) - || (cflag&CRTSCTS) != (old_cflag&CRTSCTS) ) { - + if ((iflag&IXON) != (old_iflag&IXON) + || (cflag&CRTSCTS) != (old_cflag&CRTSCTS)) { arg = 0; - - if( (iflag&IXON) ) + if (iflag&IXON) arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; else arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; - if( (cflag&CRTSCTS) ) { + if (cflag&CRTSCTS) { arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS; } else { arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS; - port->tty->hw_stopped = 0; + tty->hw_stopped = 0; } buf[i++] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL; buf[i++] = priv->dp_port_num; buf[i++] = arg; buf[i++] = 0; - } /* set receive enable/disable */ - if( (cflag&CREAD) != (old_cflag&CREAD) ) { - - if( (cflag&CREAD) ) + if ((cflag&CREAD) != (old_cflag&CREAD)) { + if (cflag&CREAD) arg = DIGI_ENABLE; else arg = DIGI_DISABLE; @@ -1152,32 +1086,26 @@ dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, ol buf[i++] = priv->dp_port_num; buf[i++] = arg; buf[i++] = 0; - } - - if( (ret=digi_write_oob_command( port, buf, i, 1 )) != 0 ) - dbg( "digi_set_termios: write oob failed, ret=%d", ret ); + if ((ret = digi_write_oob_command(port, buf, i, 1)) != 0) + dbg("digi_set_termios: write oob failed, ret=%d", ret); } -static void digi_break_ctl( struct usb_serial_port *port, int break_state ) +static void digi_break_ctl(struct usb_serial_port *port, int break_state) { - unsigned char buf[4]; - buf[0] = DIGI_CMD_BREAK_CONTROL; buf[1] = 2; /* length */ buf[2] = break_state ? 1 : 0; buf[3] = 0; /* pad */ - - digi_write_inb_command( port, buf, 4, 0 ); - + digi_write_inb_command(port, buf, 4, 0); } -static int digi_tiocmget( struct usb_serial_port *port, struct file *file ) +static int digi_tiocmget(struct usb_serial_port *port, struct file *file) { struct digi_port *priv = usb_get_serial_port_data(port); unsigned int val; @@ -1185,15 +1113,15 @@ static int digi_tiocmget( struct usb_serial_port *port, struct file *file ) dbg("%s: TOP: port=%d", __FUNCTION__, priv->dp_port_num); - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); val = priv->dp_modem_signals; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); return val; } -static int digi_tiocmset( struct usb_serial_port *port, struct file *file, - unsigned int set, unsigned int clear ) +static int digi_tiocmset(struct usb_serial_port *port, struct file *file, + unsigned int set, unsigned int clear) { struct digi_port *priv = usb_get_serial_port_data(port); unsigned int val; @@ -1201,41 +1129,34 @@ static int digi_tiocmset( struct usb_serial_port *port, struct file *file, dbg("%s: TOP: port=%d", __FUNCTION__, priv->dp_port_num); - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); val = (priv->dp_modem_signals & ~clear) | set; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - return digi_set_modem_signals( port, val, 1 ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + return digi_set_modem_signals(port, val, 1); } -static int digi_ioctl( struct usb_serial_port *port, struct file *file, - unsigned int cmd, unsigned long arg ) +static int digi_ioctl(struct usb_serial_port *port, struct file *file, + unsigned int cmd, unsigned long arg) { - struct digi_port *priv = usb_get_serial_port_data(port); - -dbg( "digi_ioctl: TOP: port=%d, cmd=0x%x", priv->dp_port_num, cmd ); + dbg("digi_ioctl: TOP: port=%d, cmd=0x%x", priv->dp_port_num, cmd); switch (cmd) { - case TIOCMIWAIT: /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/ /* TODO */ - return( 0 ); - + return 0; case TIOCGICOUNT: /* return count of modemline transitions */ /* TODO */ return 0; - } - - return( -ENOIOCTLCMD ); + return -ENOIOCTLCMD; } - -static int digi_write( struct usb_serial_port *port, const unsigned char *buf, int count ) +static int digi_write(struct usb_serial_port *port, const unsigned char *buf, int count) { int ret,data_len,new_len; @@ -1243,35 +1164,29 @@ static int digi_write( struct usb_serial_port *port, const unsigned char *buf, i unsigned char *data = port->write_urb->transfer_buffer; unsigned long flags = 0; - -dbg( "digi_write: TOP: port=%d, count=%d, in_interrupt=%ld", -priv->dp_port_num, count, in_interrupt() ); + dbg("digi_write: TOP: port=%d, count=%d, in_interrupt=%ld", + priv->dp_port_num, count, in_interrupt()); /* copy user data (which can sleep) before getting spin lock */ - count = min( count, port->bulk_out_size-2 ); - count = min( 64, count); + count = min(count, port->bulk_out_size-2); + count = min(64, count); /* be sure only one write proceeds at a time */ /* there are races on the port private buffer */ /* and races to check write_urb->status */ - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); /* wait for urb status clear to submit another urb */ - if( port->write_urb->status == -EINPROGRESS - || priv->dp_write_urb_in_use ) { - + if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use) { /* buffer data if count is 1 (probably put_char) if possible */ - if( count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE ) { + if (count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE) { priv->dp_out_buf[priv->dp_out_buf_len++] = *buf; new_len = 1; } else { new_len = 0; } - - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - - return( new_len ); - + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + return new_len; } /* allow space for any buffered data and for new data, up to */ @@ -1279,9 +1194,9 @@ priv->dp_port_num, count, in_interrupt() ); new_len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len); data_len = new_len + priv->dp_out_buf_len; - if( data_len == 0 ) { - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - return( 0 ); + if (data_len == 0) { + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + return 0; } port->write_urb->transfer_buffer_length = data_len+2; @@ -1291,32 +1206,29 @@ priv->dp_port_num, count, in_interrupt() ); *data++ = data_len; /* copy in buffered data first */ - memcpy( data, priv->dp_out_buf, priv->dp_out_buf_len ); + memcpy(data, priv->dp_out_buf, priv->dp_out_buf_len); data += priv->dp_out_buf_len; /* copy in new data */ - memcpy( data, buf, new_len ); + memcpy(data, buf, new_len); - if( (ret=usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0 ) { + if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) { priv->dp_write_urb_in_use = 1; ret = new_len; priv->dp_out_buf_len = 0; } /* return length of new data written, or error */ - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - if( ret < 0 ) { - err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, - ret, priv->dp_port_num ); - } - -dbg( "digi_write: returning %d", ret ); - return( ret ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + if (ret < 0) + err("%s: usb_submit_urb failed, ret=%d, port=%d", + __FUNCTION__, ret, priv->dp_port_num); + dbg("digi_write: returning %d", ret); + return ret; } - -static void digi_write_bulk_callback( struct urb *urb ) +static void digi_write_bulk_callback(struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -1326,153 +1238,136 @@ static void digi_write_bulk_callback( struct urb *urb ) int ret = 0; int status = urb->status; - - dbg("digi_write_bulk_callback: TOP, urb status=%d", status); + dbg("digi_write_bulk_callback: TOP, urb->status=%d", status); /* port and serial sanity check */ - if( port == NULL || (priv=usb_get_serial_port_data(port)) == NULL ) { + if (port == NULL || (priv=usb_get_serial_port_data(port)) == NULL) { err("%s: port or port->private is NULL, status=%d", __FUNCTION__, status); return; } serial = port->serial; - if( serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL ) { + if (serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL) { err("%s: serial or serial->private is NULL, status=%d", __FUNCTION__, status); return; } /* handle oob callback */ - if( priv->dp_port_num == serial_priv->ds_oob_port_num ) { - dbg( "digi_write_bulk_callback: oob callback" ); - spin_lock( &priv->dp_port_lock ); + if (priv->dp_port_num == serial_priv->ds_oob_port_num) { + dbg("digi_write_bulk_callback: oob callback"); + spin_lock(&priv->dp_port_lock); priv->dp_write_urb_in_use = 0; - wake_up_interruptible( &port->write_wait ); - spin_unlock( &priv->dp_port_lock ); + wake_up_interruptible(&port->write_wait); + spin_unlock(&priv->dp_port_lock); return; } /* try to send any buffered data on this port, if it is open */ - spin_lock( &priv->dp_port_lock ); + spin_lock(&priv->dp_port_lock); priv->dp_write_urb_in_use = 0; - if( port->open_count && port->write_urb->status != -EINPROGRESS - && priv->dp_out_buf_len > 0 ) { - + if (port->open_count && port->write_urb->status != -EINPROGRESS + && priv->dp_out_buf_len > 0) { *((unsigned char *)(port->write_urb->transfer_buffer)) = (unsigned char)DIGI_CMD_SEND_DATA; *((unsigned char *)(port->write_urb->transfer_buffer)+1) = (unsigned char)priv->dp_out_buf_len; - - port->write_urb->transfer_buffer_length - = priv->dp_out_buf_len+2; + port->write_urb->transfer_buffer_length = priv->dp_out_buf_len+2; port->write_urb->dev = serial->dev; - - memcpy( port->write_urb->transfer_buffer+2, priv->dp_out_buf, - priv->dp_out_buf_len ); - - if( (ret=usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0 ) { + memcpy(port->write_urb->transfer_buffer+2, priv->dp_out_buf, + priv->dp_out_buf_len); + if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) { priv->dp_write_urb_in_use = 1; priv->dp_out_buf_len = 0; } - } - /* wake up processes sleeping on writes immediately */ - digi_wakeup_write( port ); - + digi_wakeup_write(port); /* also queue up a wakeup at scheduler time, in case we */ /* lost the race in write_chan(). */ schedule_work(&priv->dp_wakeup_work); - spin_unlock( &priv->dp_port_lock ); - - if( ret ) { - err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, - ret, priv->dp_port_num ); - } - + spin_unlock(&priv->dp_port_lock); + if (ret) + err("%s: usb_submit_urb failed, ret=%d, port=%d", + __FUNCTION__, ret, priv->dp_port_num); } - -static int digi_write_room( struct usb_serial_port *port ) +static int digi_write_room(struct usb_serial_port *port) { int room; struct digi_port *priv = usb_get_serial_port_data(port); unsigned long flags = 0; + spin_lock_irqsave(&priv->dp_port_lock, flags); - spin_lock_irqsave( &priv->dp_port_lock, flags ); - - if( port->write_urb->status == -EINPROGRESS - || priv->dp_write_urb_in_use ) + if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use) room = 0; else room = port->bulk_out_size - 2 - priv->dp_out_buf_len; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - -dbg( "digi_write_room: port=%d, room=%d", priv->dp_port_num, room ); - return( room ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + dbg("digi_write_room: port=%d, room=%d", priv->dp_port_num, room); + return room; } - -static int digi_chars_in_buffer( struct usb_serial_port *port ) +static int digi_chars_in_buffer(struct usb_serial_port *port) { struct digi_port *priv = usb_get_serial_port_data(port); - if( port->write_urb->status == -EINPROGRESS - || priv->dp_write_urb_in_use ) { -dbg( "digi_chars_in_buffer: port=%d, chars=%d", priv->dp_port_num, port->bulk_out_size - 2 ); - /* return( port->bulk_out_size - 2 ); */ - return( 256 ); + if (port->write_urb->status == -EINPROGRESS + || priv->dp_write_urb_in_use) { + dbg("digi_chars_in_buffer: port=%d, chars=%d", + priv->dp_port_num, port->bulk_out_size - 2); + /* return(port->bulk_out_size - 2); */ + return 256; } else { -dbg( "digi_chars_in_buffer: port=%d, chars=%d", priv->dp_port_num, priv->dp_out_buf_len ); - return( priv->dp_out_buf_len ); + dbg("digi_chars_in_buffer: port=%d, chars=%d", + priv->dp_port_num, priv->dp_out_buf_len); + return priv->dp_out_buf_len; } } -static int digi_open( struct usb_serial_port *port, struct file *filp ) +static int digi_open(struct usb_serial_port *port, struct file *filp) { - int ret; unsigned char buf[32]; struct digi_port *priv = usb_get_serial_port_data(port); struct ktermios not_termios; unsigned long flags = 0; - -dbg( "digi_open: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count ); + dbg("digi_open: TOP: port=%d, open_count=%d", + priv->dp_port_num, port->open_count); /* be sure the device is started up */ - if( digi_startup_device( port->serial ) != 0 ) - return( -ENXIO ); + if (digi_startup_device(port->serial) != 0) + return -ENXIO; - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); /* don't wait on a close in progress for non-blocking opens */ - if( priv->dp_in_close && (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) { - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - return( -EAGAIN ); + if (priv->dp_in_close && (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) { + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + return -EAGAIN; } /* wait for a close in progress to finish */ - while( priv->dp_in_close ) { + while(priv->dp_in_close) { cond_wait_interruptible_timeout_irqrestore( &priv->dp_close_wait, DIGI_RETRY_TIMEOUT, - &priv->dp_port_lock, flags ); - if( signal_pending(current) ) { - return( -EINTR ); - } - spin_lock_irqsave( &priv->dp_port_lock, flags ); + &priv->dp_port_lock, flags); + if (signal_pending(current)) + return -EINTR; + spin_lock_irqsave(&priv->dp_port_lock, flags); } - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); /* read modem signals automatically whenever they change */ buf[0] = DIGI_CMD_READ_INPUT_SIGNALS; @@ -1486,23 +1381,22 @@ dbg( "digi_open: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_cou buf[6] = DIGI_FLUSH_TX | DIGI_FLUSH_RX; buf[7] = 0; - if( (ret=digi_write_oob_command( port, buf, 8, 1 )) != 0 ) - dbg( "digi_open: write oob failed, ret=%d", ret ); + if ((ret = digi_write_oob_command(port, buf, 8, 1)) != 0) + dbg("digi_open: write oob failed, ret=%d", ret); /* set termios settings */ not_termios.c_cflag = ~port->tty->termios->c_cflag; not_termios.c_iflag = ~port->tty->termios->c_iflag; - digi_set_termios( port, ¬_termios ); + digi_set_termios(port, ¬_termios); /* set DTR and RTS */ - digi_set_modem_signals( port, TIOCM_DTR|TIOCM_RTS, 1 ); - - return( 0 ); + digi_set_modem_signals(port, TIOCM_DTR|TIOCM_RTS, 1); + return 0; } -static void digi_close( struct usb_serial_port *port, struct file *filp ) +static void digi_close(struct usb_serial_port *port, struct file *filp) { DEFINE_WAIT(wait); int ret; @@ -1511,40 +1405,37 @@ static void digi_close( struct usb_serial_port *port, struct file *filp ) struct digi_port *priv = usb_get_serial_port_data(port); unsigned long flags = 0; - -dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count ); - + dbg("digi_close: TOP: port=%d, open_count=%d", + priv->dp_port_num, port->open_count); /* if disconnected, just clear flags */ if (!usb_get_intfdata(port->serial->interface)) goto exit; /* do cleanup only after final close on this port */ - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); priv->dp_in_close = 1; - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); /* tell line discipline to process only XON/XOFF */ tty->closing = 1; /* wait for output to drain */ - if( (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) { - tty_wait_until_sent( tty, DIGI_CLOSE_TIMEOUT ); - } + if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) + tty_wait_until_sent(tty, DIGI_CLOSE_TIMEOUT); /* flush driver and line discipline buffers */ - if( tty->driver->flush_buffer ) - tty->driver->flush_buffer( tty ); + if (tty->driver->flush_buffer) + tty->driver->flush_buffer(tty); tty_ldisc_flush(tty); if (port->serial->dev) { /* wait for transmit idle */ - if( (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) { - digi_transmit_idle( port, DIGI_CLOSE_TIMEOUT ); + if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) { + digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT); } - /* drop DTR and RTS */ - digi_set_modem_signals( port, 0, 0 ); + digi_set_modem_signals(port, 0, 0); /* disable input flow control */ buf[0] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; @@ -1576,8 +1467,8 @@ dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_co buf[18] = DIGI_FLUSH_TX | DIGI_FLUSH_RX; buf[19] = 0; - if( (ret=digi_write_oob_command( port, buf, 20, 0 )) != 0 ) - dbg( "digi_close: write oob failed, ret=%d", ret ); + if ((ret = digi_write_oob_command(port, buf, 20, 0)) != 0) + dbg("digi_close: write oob failed, ret=%d", ret); /* wait for final commands on oob port to complete */ prepare_to_wait(&priv->dp_flush_wait, &wait, TASK_INTERRUPTIBLE); @@ -1587,17 +1478,14 @@ dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_co /* shutdown any outstanding bulk writes */ usb_kill_urb(port->write_urb); } - tty->closing = 0; - exit: - spin_lock_irqsave( &priv->dp_port_lock, flags ); + spin_lock_irqsave(&priv->dp_port_lock, flags); priv->dp_write_urb_in_use = 0; priv->dp_in_close = 0; - wake_up_interruptible( &priv->dp_close_wait ); - spin_unlock_irqrestore( &priv->dp_port_lock, flags ); - -dbg( "digi_close: done" ); + wake_up_interruptible(&priv->dp_close_wait); + spin_unlock_irqrestore(&priv->dp_port_lock, flags); + dbg("digi_close: done"); } @@ -1608,155 +1496,136 @@ dbg( "digi_close: done" ); * urbs initialized. Returns 0 if successful, non-zero error otherwise. */ -static int digi_startup_device( struct usb_serial *serial ) +static int digi_startup_device(struct usb_serial *serial) { - int i,ret = 0; struct digi_serial *serial_priv = usb_get_serial_data(serial); struct usb_serial_port *port; - /* be sure this happens exactly once */ - spin_lock( &serial_priv->ds_serial_lock ); - if( serial_priv->ds_device_started ) { - spin_unlock( &serial_priv->ds_serial_lock ); - return( 0 ); + spin_lock(&serial_priv->ds_serial_lock); + if (serial_priv->ds_device_started) { + spin_unlock(&serial_priv->ds_serial_lock); + return 0; } serial_priv->ds_device_started = 1; - spin_unlock( &serial_priv->ds_serial_lock ); + spin_unlock(&serial_priv->ds_serial_lock); /* start reading from each bulk in endpoint for the device */ /* set USB_DISABLE_SPD flag for write bulk urbs */ - for( i=0; i<serial->type->num_ports+1; i++ ) { - + for (i = 0; i < serial->type->num_ports + 1; i++) { port = serial->port[i]; - port->write_urb->dev = port->serial->dev; - - if( (ret=usb_submit_urb(port->read_urb, GFP_KERNEL)) != 0 ) { - err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, - ret, i ); + if ((ret = usb_submit_urb(port->read_urb, GFP_KERNEL)) != 0) { + err("%s: usb_submit_urb failed, ret=%d, port=%d", + __FUNCTION__, ret, i); break; } - } - - return( ret ); - + return ret; } -static int digi_startup( struct usb_serial *serial ) +static int digi_startup(struct usb_serial *serial) { int i; struct digi_port *priv; struct digi_serial *serial_priv; - -dbg( "digi_startup: TOP" ); + dbg("digi_startup: TOP"); /* allocate the private data structures for all ports */ /* number of regular ports + 1 for the out-of-band port */ - for( i=0; i<serial->type->num_ports+1; i++ ) { - + for(i = 0; i < serial->type->num_ports + 1; i++) { /* allocate port private structure */ - priv = kmalloc( sizeof(struct digi_port), - GFP_KERNEL ); - if( priv == (struct digi_port *)0 ) { - while( --i >= 0 ) - kfree( usb_get_serial_port_data(serial->port[i]) ); - return( 1 ); /* error */ + priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL); + if (priv == NULL) { + while (--i >= 0) + kfree(usb_get_serial_port_data(serial->port[i])); + return 1; /* error */ } /* initialize port private structure */ - spin_lock_init( &priv->dp_port_lock ); + spin_lock_init(&priv->dp_port_lock); priv->dp_port_num = i; priv->dp_out_buf_len = 0; priv->dp_write_urb_in_use = 0; priv->dp_modem_signals = 0; - init_waitqueue_head( &priv->dp_modem_change_wait ); + init_waitqueue_head(&priv->dp_modem_change_wait); priv->dp_transmit_idle = 0; - init_waitqueue_head( &priv->dp_transmit_idle_wait ); + init_waitqueue_head(&priv->dp_transmit_idle_wait); priv->dp_throttled = 0; priv->dp_throttle_restart = 0; - init_waitqueue_head( &priv->dp_flush_wait ); + init_waitqueue_head(&priv->dp_flush_wait); priv->dp_in_close = 0; - init_waitqueue_head( &priv->dp_close_wait ); + init_waitqueue_head(&priv->dp_close_wait); INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); priv->dp_port = serial->port[i]; - /* initialize write wait queue for this port */ - init_waitqueue_head( &serial->port[i]->write_wait ); + init_waitqueue_head(&serial->port[i]->write_wait); usb_set_serial_port_data(serial->port[i], priv); } /* allocate serial private structure */ - serial_priv = kmalloc( sizeof(struct digi_serial), - GFP_KERNEL ); - if( serial_priv == (struct digi_serial *)0 ) { - for( i=0; i<serial->type->num_ports+1; i++ ) - kfree( usb_get_serial_port_data(serial->port[i]) ); - return( 1 ); /* error */ + serial_priv = kmalloc(sizeof(struct digi_serial), GFP_KERNEL); + if (serial_priv == NULL) { + for (i = 0; i < serial->type->num_ports + 1; i++) + kfree(usb_get_serial_port_data(serial->port[i])); + return 1; /* error */ } /* initialize serial private structure */ - spin_lock_init( &serial_priv->ds_serial_lock ); + spin_lock_init(&serial_priv->ds_serial_lock); serial_priv->ds_oob_port_num = serial->type->num_ports; serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; serial_priv->ds_device_started = 0; usb_set_serial_data(serial, serial_priv); - return( 0 ); - + return 0; } -static void digi_shutdown( struct usb_serial *serial ) +static void digi_shutdown(struct usb_serial *serial) { - int i; - - -dbg( "digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt() ); + dbg("digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt()); /* stop reads and writes on all ports */ - for( i=0; i<serial->type->num_ports+1; i++ ) { + for (i = 0; i < serial->type->num_ports + 1; i++) { usb_kill_urb(serial->port[i]->read_urb); usb_kill_urb(serial->port[i]->write_urb); } /* free the private data structures for all ports */ /* number of regular ports + 1 for the out-of-band port */ - for( i=0; i<serial->type->num_ports+1; i++ ) - kfree( usb_get_serial_port_data(serial->port[i]) ); - kfree( usb_get_serial_data(serial) ); + for(i = 0; i < serial->type->num_ports + 1; i++) + kfree(usb_get_serial_port_data(serial->port[i])); + kfree(usb_get_serial_data(serial)); } -static void digi_read_bulk_callback( struct urb *urb ) +static void digi_read_bulk_callback(struct urb *urb) { - struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct digi_port *priv; struct digi_serial *serial_priv; int ret; int status = urb->status; - -dbg( "digi_read_bulk_callback: TOP" ); + dbg("digi_read_bulk_callback: TOP"); /* port sanity check, do not resubmit if port is not valid */ - if( port == NULL || (priv=usb_get_serial_port_data(port)) == NULL ) { + if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) { err("%s: port or port->private is NULL, status=%d", __FUNCTION__, status); return; } - if( port->serial == NULL - || (serial_priv=usb_get_serial_data(port->serial)) == NULL ) { + if (port->serial == NULL || + (serial_priv=usb_get_serial_data(port->serial)) == NULL) { err("%s: serial is bad or serial->private is NULL, status=%d", - __FUNCTION__, status); + __FUNCTION__, status); return; } @@ -1768,24 +1637,23 @@ dbg( "digi_read_bulk_callback: TOP" ); } /* handle oob or inb callback, do not resubmit if error */ - if( priv->dp_port_num == serial_priv->ds_oob_port_num ) { - if( digi_read_oob_callback( urb ) != 0 ) + if (priv->dp_port_num == serial_priv->ds_oob_port_num) { + if (digi_read_oob_callback(urb) != 0) return; } else { - if( digi_read_inb_callback( urb ) != 0 ) + if (digi_read_inb_callback(urb) != 0) return; } /* continue read */ urb->dev = port->serial->dev; - if( (ret=usb_submit_urb(urb, GFP_ATOMIC)) != 0 ) { - err("%s: failed resubmitting urb, ret=%d, port=%d", __FUNCTION__, - ret, priv->dp_port_num ); + if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { + err("%s: failed resubmitting urb, ret=%d, port=%d", + __FUNCTION__, ret, priv->dp_port_num); } } - /* * Digi Read INB Callback * @@ -1796,7 +1664,7 @@ dbg( "digi_read_bulk_callback: TOP" ); * throttled, and -1 if the sanity checks failed. */ -static int digi_read_inb_callback( struct urb *urb ) +static int digi_read_inb_callback(struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -1812,72 +1680,67 @@ static int digi_read_inb_callback( struct urb *urb ) /* do not process callbacks on closed ports */ /* but do continue the read chain */ - if( port->open_count == 0 ) - return( 0 ); + if (port->open_count == 0) + return 0; /* short/multiple packet check */ - if( urb->actual_length != len + 2 ) { - err("%s: INCOMPLETE OR MULTIPLE PACKET, urb status=%d, " + if (urb->actual_length != len + 2) { + err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, " "port=%d, opcode=%d, len=%d, actual_length=%d, " - "port_status=%d", __FUNCTION__, status, priv->dp_port_num, + "status=%d", __FUNCTION__, status, priv->dp_port_num, opcode, len, urb->actual_length, port_status); - return( -1 ); + return -1; } - spin_lock( &priv->dp_port_lock ); + spin_lock(&priv->dp_port_lock); /* check for throttle; if set, do not resubmit read urb */ /* indicate the read chain needs to be restarted on unthrottle */ throttled = priv->dp_throttled; - if( throttled ) + if (throttled) priv->dp_throttle_restart = 1; /* receive data */ - if( opcode == DIGI_CMD_RECEIVE_DATA ) { - + if (opcode == DIGI_CMD_RECEIVE_DATA) { /* get flag from port_status */ flag = 0; /* overrun is special, not associated with a char */ - if (port_status & DIGI_OVERRUN_ERROR) { - tty_insert_flip_char( tty, 0, TTY_OVERRUN ); - } + if (port_status & DIGI_OVERRUN_ERROR) + tty_insert_flip_char(tty, 0, TTY_OVERRUN); /* break takes precedence over parity, */ /* which takes precedence over framing errors */ - if (port_status & DIGI_BREAK_ERROR) { + if (port_status & DIGI_BREAK_ERROR) flag = TTY_BREAK; - } else if (port_status & DIGI_PARITY_ERROR) { + else if (port_status & DIGI_PARITY_ERROR) flag = TTY_PARITY; - } else if (port_status & DIGI_FRAMING_ERROR) { + else if (port_status & DIGI_FRAMING_ERROR) flag = TTY_FRAME; - } /* data length is len-1 (one byte of len is port_status) */ --len; len = tty_buffer_request_room(tty, len); - if( len > 0 ) { + if (len > 0) { /* Hot path */ - if(flag == TTY_NORMAL) + if (flag == TTY_NORMAL) tty_insert_flip_string(tty, data, len); else { for(i = 0; i < len; i++) tty_insert_flip_char(tty, data[i], flag); } - tty_flip_buffer_push( tty ); + tty_flip_buffer_push(tty); } } + spin_unlock(&priv->dp_port_lock); - spin_unlock( &priv->dp_port_lock ); - - if( opcode == DIGI_CMD_RECEIVE_DISABLE ) { - dbg("%s: got RECEIVE_DISABLE", __FUNCTION__ ); - } else if( opcode != DIGI_CMD_RECEIVE_DATA ) { - dbg("%s: unknown opcode: %d", __FUNCTION__, opcode ); - } + if (opcode == DIGI_CMD_RECEIVE_DISABLE) + dbg("%s: got RECEIVE_DISABLE", __FUNCTION__); + else if (opcode != DIGI_CMD_RECEIVE_DATA) + dbg("%s: unknown opcode: %d", __FUNCTION__, opcode); - return( throttled ? 1 : 0 ); + return(throttled ? 1 : 0); } @@ -1891,7 +1754,7 @@ static int digi_read_inb_callback( struct urb *urb ) * -1 if the sanity checks failed. */ -static int digi_read_oob_callback( struct urb *urb ) +static int digi_read_oob_callback(struct urb *urb) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; @@ -1900,87 +1763,75 @@ static int digi_read_oob_callback( struct urb *urb ) int opcode, line, status, val; int i; - -dbg( "digi_read_oob_callback: port=%d, len=%d", priv->dp_port_num, -urb->actual_length ); + dbg("digi_read_oob_callback: port=%d, len=%d", + priv->dp_port_num, urb->actual_length); /* handle each oob command */ - for( i=0; i<urb->actual_length-3; ) { - + for(i = 0; i < urb->actual_length - 3;) { opcode = ((unsigned char *)urb->transfer_buffer)[i++]; line = ((unsigned char *)urb->transfer_buffer)[i++]; status = ((unsigned char *)urb->transfer_buffer)[i++]; val = ((unsigned char *)urb->transfer_buffer)[i++]; -dbg( "digi_read_oob_callback: opcode=%d, line=%d, status=%d, val=%d", -opcode, line, status, val ); + dbg("digi_read_oob_callback: opcode=%d, line=%d, status=%d, val=%d", + opcode, line, status, val); - if( status != 0 || line >= serial->type->num_ports ) + if (status != 0 || line >= serial->type->num_ports) continue; port = serial->port[line]; - if ((priv=usb_get_serial_port_data(port)) == NULL ) + if ((priv=usb_get_serial_port_data(port)) == NULL) return -1; - if( opcode == DIGI_CMD_READ_INPUT_SIGNALS ) { - - spin_lock( &priv->dp_port_lock ); - + if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) { + spin_lock(&priv->dp_port_lock); /* convert from digi flags to termiox flags */ - if( val & DIGI_READ_INPUT_SIGNALS_CTS ) { + if (val & DIGI_READ_INPUT_SIGNALS_CTS) { priv->dp_modem_signals |= TIOCM_CTS; /* port must be open to use tty struct */ - if( port->open_count - && port->tty->termios->c_cflag & CRTSCTS ) { + if (port->open_count + && port->tty->termios->c_cflag & CRTSCTS) { port->tty->hw_stopped = 0; - digi_wakeup_write( port ); + digi_wakeup_write(port); } } else { priv->dp_modem_signals &= ~TIOCM_CTS; /* port must be open to use tty struct */ - if( port->open_count - && port->tty->termios->c_cflag & CRTSCTS ) { + if (port->open_count + && port->tty->termios->c_cflag & CRTSCTS) { port->tty->hw_stopped = 1; } } - if( val & DIGI_READ_INPUT_SIGNALS_DSR ) + if (val & DIGI_READ_INPUT_SIGNALS_DSR) priv->dp_modem_signals |= TIOCM_DSR; else priv->dp_modem_signals &= ~TIOCM_DSR; - if( val & DIGI_READ_INPUT_SIGNALS_RI ) + if (val & DIGI_READ_INPUT_SIGNALS_RI) priv->dp_modem_signals |= TIOCM_RI; else priv->dp_modem_signals &= ~TIOCM_RI; - if( val & DIGI_READ_INPUT_SIGNALS_DCD ) + if (val & DIGI_READ_INPUT_SIGNALS_DCD) priv->dp_modem_signals |= TIOCM_CD; else priv->dp_modem_signals &= ~TIOCM_CD; - wake_up_interruptible( &priv->dp_modem_change_wait ); - spin_unlock( &priv->dp_port_lock ); - - } else if( opcode == DIGI_CMD_TRANSMIT_IDLE ) { - - spin_lock( &priv->dp_port_lock ); + wake_up_interruptible(&priv->dp_modem_change_wait); + spin_unlock(&priv->dp_port_lock); + } else if (opcode == DIGI_CMD_TRANSMIT_IDLE) { + spin_lock(&priv->dp_port_lock); priv->dp_transmit_idle = 1; - wake_up_interruptible( &priv->dp_transmit_idle_wait ); - spin_unlock( &priv->dp_port_lock ); - - } else if( opcode == DIGI_CMD_IFLUSH_FIFO ) { - - wake_up_interruptible( &priv->dp_flush_wait ); - + wake_up_interruptible(&priv->dp_transmit_idle_wait); + spin_unlock(&priv->dp_port_lock); + } else if (opcode == DIGI_CMD_IFLUSH_FIFO) { + wake_up_interruptible(&priv->dp_flush_wait); } - } - - return( 0 ); + return 0; } - -static int __init digi_init (void) +static int __init digi_init(void) { int retval; retval = usb_serial_register(&digi_acceleport_2_device); @@ -2002,12 +1853,11 @@ failed_acceleport_2_device: return retval; } - static void __exit digi_exit (void) { - usb_deregister (&digi_driver); - usb_serial_deregister (&digi_acceleport_2_device); - usb_serial_deregister (&digi_acceleport_4_device); + usb_deregister(&digi_driver); + usb_serial_deregister(&digi_acceleport_2_device); + usb_serial_deregister(&digi_acceleport_4_device); } @@ -2015,8 +1865,8 @@ module_init(digi_init); module_exit(digi_exit); -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); module_param(debug, bool, S_IRUGO | S_IWUSR); diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index dd42f57089f..2ecb1d2a034 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -2366,9 +2366,8 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa int status; unsigned char number = edge_port->port->number - edge_port->port->serial->minor; - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (!edge_serial->epic_descriptor.Supports.IOSPSetBaudRate))) { + if (edge_serial->is_epic && + !edge_serial->epic_descriptor.Supports.IOSPSetBaudRate) { dbg("SendCmdWriteBaudRate - NOT Setting baud rate for port = %d, baud = %d", edge_port->port->number, baudRate); return 0; @@ -2461,18 +2460,16 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue); - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (!edge_serial->epic_descriptor.Supports.IOSPWriteMCR) && - (regNum == MCR))) { + if (edge_serial->is_epic && + !edge_serial->epic_descriptor.Supports.IOSPWriteMCR && + regNum == MCR) { dbg("SendCmdWriteUartReg - Not writing to MCR Register"); return 0; } - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (!edge_serial->epic_descriptor.Supports.IOSPWriteLCR) && - (regNum == LCR))) { + if (edge_serial->is_epic && + !edge_serial->epic_descriptor.Supports.IOSPWriteLCR && + regNum == LCR) { dbg ("SendCmdWriteUartReg - Not writing to LCR Register"); return 0; } diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 2a3fabcf518..e08c9bb403d 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -184,21 +184,21 @@ struct mct_u232_private { * we do not know how to support. We ignore them for the moment. * XXX Rate-limit the error message, it's user triggerable. */ -static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) +static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value) { if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) { switch (value) { - case B300: return 0x01; - case B600: return 0x02; /* this one not tested */ - case B1200: return 0x03; - case B2400: return 0x04; - case B4800: return 0x06; - case B9600: return 0x08; - case B19200: return 0x09; - case B38400: return 0x0a; - case B57600: return 0x0b; - case B115200: return 0x0c; + case 300: return 0x01; + case 600: return 0x02; /* this one not tested */ + case 1200: return 0x03; + case 2400: return 0x04; + case 4800: return 0x06; + case 9600: return 0x08; + case 19200: return 0x09; + case 38400: return 0x0a; + case 57600: return 0x0b; + case 115200: return 0x0c; default: err("MCT USB-RS232: unsupported baudrate request 0x%x," " using default of B9600", value); @@ -206,27 +206,27 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) } } else { switch (value) { - case B300: value = 300; break; - case B600: value = 600; break; - case B1200: value = 1200; break; - case B2400: value = 2400; break; - case B4800: value = 4800; break; - case B9600: value = 9600; break; - case B19200: value = 19200; break; - case B38400: value = 38400; break; - case B57600: value = 57600; break; - case B115200: value = 115200; break; - default: - err("MCT USB-RS232: unsupported baudrate request 0x%x," - " using default of B9600", value); - value = 9600; + case 300: break; + case 600: break; + case 1200: break; + case 2400: break; + case 4800: break; + case 9600: break; + case 19200: break; + case 38400: break; + case 57600: break; + case 115200: break; + default: + err("MCT USB-RS232: unsupported baudrate request 0x%x," + " using default of B9600", value); + value = 9600; } return 115200/value; } } static int mct_u232_set_baud_rate(struct usb_serial *serial, struct usb_serial_port *port, - int value) + speed_t value) { __le32 divisor; int rc; @@ -634,7 +634,7 @@ static void mct_u232_set_termios (struct usb_serial_port *port, mct_u232_set_modem_ctrl(serial, control_state); } - mct_u232_set_baud_rate(serial, port, cflag & CBAUD); + mct_u232_set_baud_rate(serial, port, tty_get_baud_rate(port->tty)); if ((cflag & CBAUD) == B0 ) { dbg("%s: baud is B0", __FUNCTION__); diff --git a/drivers/usb/serial/mct_u232.h b/drivers/usb/serial/mct_u232.h index a61bac8f224..aae10c8174d 100644 --- a/drivers/usb/serial/mct_u232.h +++ b/drivers/usb/serial/mct_u232.h @@ -79,7 +79,7 @@ * and "Intel solution". They are the regular MCT and "Sitecom" for us. * This is pointless to document in the header, see the code for the bits. */ -static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value); +static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value); /* * Line Control Register (LCR) diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 0794ccdebfd..0bb8de4cc52 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -45,7 +45,7 @@ enum devicetype { DEVICE_INSTALLER = 2, }; -int sierra_set_power_state(struct usb_device *udev, __u16 swiState) +static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) { int result; dev_dbg(&udev->dev, "%s", "SET POWER STATE"); @@ -60,7 +60,7 @@ int sierra_set_power_state(struct usb_device *udev, __u16 swiState) return result; } -int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) +static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) { int result; dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH"); @@ -75,7 +75,8 @@ int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) return result; } -int sierra_probe(struct usb_interface *iface, const struct usb_device_id *id) +static int sierra_probe(struct usb_interface *iface, + const struct usb_device_id *id) { int result; struct usb_device *udev; diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index a3665659d13..9bf01a5efc8 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -60,19 +60,19 @@ static struct usb_driver usb_serial_driver = { static int debug; static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ -static spinlock_t table_lock; +static DEFINE_MUTEX(table_lock); static LIST_HEAD(usb_serial_driver_list); struct usb_serial *usb_serial_get_by_index(unsigned index) { struct usb_serial *serial; - spin_lock(&table_lock); + mutex_lock(&table_lock); serial = serial_table[index]; if (serial) kref_get(&serial->kref); - spin_unlock(&table_lock); + mutex_unlock(&table_lock); return serial; } @@ -84,7 +84,7 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po dbg("%s %d", __FUNCTION__, num_ports); *minor = 0; - spin_lock(&table_lock); + mutex_lock(&table_lock); for (i = 0; i < SERIAL_TTY_MINORS; ++i) { if (serial_table[i]) continue; @@ -106,10 +106,10 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po serial_table[i] = serial; serial->port[j++]->number = i; } - spin_unlock(&table_lock); + mutex_unlock(&table_lock); return serial; } - spin_unlock(&table_lock); + mutex_unlock(&table_lock); return NULL; } @@ -172,9 +172,9 @@ static void destroy_serial(struct kref *kref) void usb_serial_put(struct usb_serial *serial) { - spin_lock(&table_lock); + mutex_lock(&table_lock); kref_put(&serial->kref, destroy_serial); - spin_unlock(&table_lock); + mutex_unlock(&table_lock); } /***************************************************************************** @@ -1077,16 +1077,17 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) struct usb_serial_port *port; int i, r = 0; - if (serial) { - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - if (port) - kill_traffic(port); - } + if (!serial) /* device has been disconnected */ + return 0; + + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; + if (port) + kill_traffic(port); } if (serial->type->suspend) - serial->type->suspend(serial, message); + r = serial->type->suspend(serial, message); return r; } @@ -1128,7 +1129,6 @@ static int __init usb_serial_init(void) return -ENOMEM; /* Initialize our global data */ - spin_lock_init(&table_lock); for (i = 0; i < SERIAL_TTY_MINORS; ++i) { serial_table[i] = NULL; } diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index a624e72f81d..d8d008d4294 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -320,6 +320,13 @@ UNUSUAL_DEV( 0x04b0, 0x0401, 0x0200, 0x0200, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY), +/* Reported by Milinevsky Dmitry <niam.niam@gmail.com> */ +UNUSUAL_DEV( 0x04b0, 0x0409, 0x0100, 0x0100, + "NIKON", + "NIKON DSC D50", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + /* Reported by Andreas Bockhold <andreas@bockionline.de> */ UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, "NIKON", @@ -1357,6 +1364,20 @@ UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), +/* Jeremy Katz <katzj@redhat.com>: + * The Blackberry Pearl can run in two modes; a usb-storage only mode + * and a mode that allows access via mass storage and to its database. + * The berry_charge module will set the device to dual mode and thus we + * should ignore its native mode if that module is built + */ +#ifdef CONFIG_USB_BERRY_CHARGE +UNUSUAL_DEV( 0x0fca, 0x0006, 0x0001, 0x0001, + "RIM", + "Blackberry Pearl", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_DEVICE ), +#endif + /* Reported by Michael Stattmann <michael@stattmann.com> */ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, "Sony Ericsson", diff --git a/include/linux/dvb/video.h b/include/linux/dvb/video.h index 93e4c3a6d19..50839fe9e39 100644 --- a/include/linux/dvb/video.h +++ b/include/linux/dvb/video.h @@ -29,6 +29,7 @@ #ifdef __KERNEL__ #include <linux/types.h> #else +#include <asm/types.h> #include <stdint.h> #include <time.h> #endif diff --git a/include/linux/kobject.h b/include/linux/kobject.h index aa2fe22b1ba..949706c3362 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -56,6 +56,9 @@ enum kobject_action { KOBJ_MAX }; +/* The list of strings defining the valid kobject actions as specified above */ +extern const char *kobject_actions[]; + struct kobject { const char * k_name; char name[KOBJ_NAME_LEN]; @@ -108,9 +111,15 @@ struct kobj_type { struct attribute ** default_attrs; }; +struct kset_uevent_ops { + int (*filter)(struct kset *kset, struct kobject *kobj); + const char *(*name)(struct kset *kset, struct kobject *kobj); + int (*uevent)(struct kset *kset, struct kobject *kobj, char **envp, + int num_envp, char *buffer, int buffer_size); +}; -/** - * kset - a set of kobjects of a specific type, belonging +/* + * struct kset - a set of kobjects of a specific type, belonging * to a specific subsystem. * * All kobjects of a kset should be embedded in an identical @@ -126,13 +135,6 @@ struct kobj_type { * supress the event generation or add subsystem specific * variables carried with the event. */ -struct kset_uevent_ops { - int (*filter)(struct kset *kset, struct kobject *kobj); - const char *(*name)(struct kset *kset, struct kobject *kobj); - int (*uevent)(struct kset *kset, struct kobject *kobj, char **envp, - int num_envp, char *buffer, int buffer_size); -}; - struct kset { struct kobj_type * ktype; struct list_head list; @@ -173,7 +175,7 @@ static inline struct kobj_type * get_ktype(struct kobject * k) extern struct kobject * kset_find_obj(struct kset *, const char *); -/** +/* * Use this when initializing an embedded kset with no other * fields to initialize. */ @@ -198,7 +200,7 @@ extern struct kset kernel_subsys; /* The global /sys/hypervisor/ subsystem */ extern struct kset hypervisor_subsys; -/** +/* * Helpers for setting the kset of registered objects. * Often, a registered object belongs to a kset embedded in a * subsystem. These do no magic, just make the resulting code @@ -233,7 +235,7 @@ extern struct kset hypervisor_subsys; /** * subsys_set_kset(obj,subsys) - set kset for subsystem * @obj: ptr to some object type. - * @subsys: a subsystem object (not a ptr). + * @_subsys: a subsystem object (not a ptr). * * Can be used for any object type with an embedded ->subsys. * Sets the kset of @obj's kobject to @subsys.kset. This makes diff --git a/include/linux/usb.h b/include/linux/usb.h index 7a60946df3b..4f33a58fa9d 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -94,6 +94,7 @@ enum usb_interface_condition { * endpoint configurations. They will be in no particular order. * @num_altsetting: number of altsettings defined. * @cur_altsetting: the current altsetting. + * @intf_assoc: interface association descriptor * @driver: the USB driver that is bound to this interface. * @minor: the minor number assigned to this interface, if this * interface is bound to a driver that uses the USB major number. @@ -213,6 +214,7 @@ struct usb_interface_cache { * @desc: the device's configuration descriptor. * @string: pointer to the cached version of the iConfiguration string, if * present for this configuration. + * @intf_assoc: list of any interface association descriptors in this config * @interface: array of pointers to usb_interface structures, one for each * interface in the configuration. The number of interfaces is stored * in desc.bNumInterfaces. These pointers are valid only while the diff --git a/kernel/params.c b/kernel/params.c index effbaaedd7f..4e57732fcfb 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -567,7 +567,12 @@ static void __init kernel_param_sysfs_setup(const char *name, kobject_set_name(&mk->kobj, name); kobject_init(&mk->kobj); ret = kobject_add(&mk->kobj); - BUG_ON(ret < 0); + if (ret) { + printk(KERN_ERR "Module '%s' failed to be added to sysfs, " + "error number %d\n", name, ret); + printk(KERN_ERR "The system will be unstable now.\n"); + return; + } param_sysfs_setup(mk, kparam, num_params, name_skip); kobject_uevent(&mk->kobj, KOBJ_ADD); } diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 6a80c784a8f..df02814699d 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -25,14 +25,6 @@ #define BUFFER_SIZE 2048 /* buffer for the variables */ #define NUM_ENVP 32 /* number of env pointers */ -#if defined(CONFIG_HOTPLUG) -u64 uevent_seqnum; -char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug"; -static DEFINE_SPINLOCK(sequence_lock); -#if defined(CONFIG_NET) -static struct sock *uevent_sock; -#endif - /* the strings here must match the enum in include/linux/kobject.h */ const char *kobject_actions[] = { "add", @@ -43,6 +35,14 @@ const char *kobject_actions[] = { "offline", }; +#if defined(CONFIG_HOTPLUG) +u64 uevent_seqnum; +char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug"; +static DEFINE_SPINLOCK(sequence_lock); +#if defined(CONFIG_NET) +static struct sock *uevent_sock; +#endif + /** * kobject_uevent_env - send an uevent with environmental data * diff --git a/mm/slub.c b/mm/slub.c index 9b2d6178d06..6c6d74ff069 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1131,6 +1131,7 @@ static void __free_slab(struct kmem_cache *s, struct page *page) slab_pad_check(s, page); for_each_object(p, s, page_address(page)) check_object(s, page, p, 0); + ClearSlabDebug(page); } mod_zone_page_state(page_zone(page), @@ -1169,7 +1170,6 @@ static void discard_slab(struct kmem_cache *s, struct page *page) atomic_long_dec(&n->nr_slabs); reset_page_mapcount(page); - ClearSlabDebug(page); __ClearPageSlab(page); free_slab(s, page); } @@ -1656,6 +1656,7 @@ static void __always_inline slab_free(struct kmem_cache *s, unsigned long flags; local_irq_save(flags); + debug_check_no_locks_freed(object, s->objsize); if (likely(page == s->cpu_slab[smp_processor_id()] && !SlabDebug(page))) { object[page->offset] = page->lockless_freelist; diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 6523ba07db9..188c7cf21b8 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -781,6 +781,8 @@ static struct pci_device_id snd_bt87x_ids[] = { BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000), /* Viewcast Osprey 200 */ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), + /* Viewcast Osprey 440 (rate is configurable via gpio) */ + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff07, 32000), /* ATI TV-Wonder */ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000), /* Leadtek Winfast tv 2000xp delux */ |