diff --git a/[refs] b/[refs]
index a50eee942c9e..d19d93b29b5b 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 6c59f9d9fb95934bf3d7d64249b338ce79953b5b
+refs/heads/master: 7063fbf2261194f72ee75afca67b3b38b554b5fa
diff --git a/trunk/.gitignore b/trunk/.gitignore
index a4b576eb9c00..5014bfa48ac1 100644
--- a/trunk/.gitignore
+++ b/trunk/.gitignore
@@ -23,7 +23,6 @@ Module.symvers
# Generated include files
#
include/asm
-include/asm-*/asm-offsets.h
include/config
include/linux/autoconf.h
include/linux/compile.h
diff --git a/trunk/CREDITS b/trunk/CREDITS
index 521f00d1b549..1b4f8694fa48 100644
--- a/trunk/CREDITS
+++ b/trunk/CREDITS
@@ -1883,7 +1883,6 @@ N: Jaya Kumar
E: jayalk@intworks.biz
W: http://www.intworks.biz
D: Arc monochrome LCD framebuffer driver, x86 reboot fixups
-D: pirq addr, CS5535 alsa audio driver
S: Gurgaon, India
S: Kuala Lumpur, Malaysia
diff --git a/trunk/Documentation/DocBook/usb.tmpl b/trunk/Documentation/DocBook/usb.tmpl
index 320af25de3a2..15ce0f21e5e0 100644
--- a/trunk/Documentation/DocBook/usb.tmpl
+++ b/trunk/Documentation/DocBook/usb.tmpl
@@ -253,7 +253,6 @@
!Edrivers/usb/core/urb.c
!Edrivers/usb/core/message.c
!Edrivers/usb/core/file.c
-!Edrivers/usb/core/driver.c
!Edrivers/usb/core/usb.c
!Edrivers/usb/core/hub.c
diff --git a/trunk/Documentation/SubmittingPatches b/trunk/Documentation/SubmittingPatches
index 1d47e6c09dc6..237d54c44bc5 100644
--- a/trunk/Documentation/SubmittingPatches
+++ b/trunk/Documentation/SubmittingPatches
@@ -158,7 +158,7 @@ Even if the maintainer did not respond in step #4, make sure to ALWAYS
copy the maintainer when you change their code.
For small patches you may want to CC the Trivial Patch Monkey
-trivial@kernel.org managed by Adrian Bunk; which collects "trivial"
+trivial@rustcorp.com.au set up by Rusty Russell; which collects "trivial"
patches. Trivial patches must qualify for one of the following rules:
Spelling fixes in documentation
Spelling fixes which could break grep(1).
@@ -171,7 +171,7 @@ patches. Trivial patches must qualify for one of the following rules:
since people copy, as long as it's trivial)
Any fix by the author/maintainer of the file. (ie. patch monkey
in re-transmission mode)
-URL:
+URL:
diff --git a/trunk/Documentation/block/biodoc.txt b/trunk/Documentation/block/biodoc.txt
index 303c57a7fad9..0fe01c805480 100644
--- a/trunk/Documentation/block/biodoc.txt
+++ b/trunk/Documentation/block/biodoc.txt
@@ -31,7 +31,7 @@ The following people helped with review comments and inputs for this
document:
Christoph Hellwig
Arjan van de Ven
- Randy Dunlap
+ Randy Dunlap
Andre Hedrick
The following people helped with fixes/contributions to the bio patches
diff --git a/trunk/Documentation/cpu-freq/governors.txt b/trunk/Documentation/cpu-freq/governors.txt
index f4b8dc4237e6..933fae74c337 100644
--- a/trunk/Documentation/cpu-freq/governors.txt
+++ b/trunk/Documentation/cpu-freq/governors.txt
@@ -27,7 +27,6 @@ Contents:
2.2 Powersave
2.3 Userspace
2.4 Ondemand
-2.5 Conservative
3. The Governor Interface in the CPUfreq Core
@@ -111,64 +110,9 @@ directory.
The CPUfreq govenor "ondemand" sets the CPU depending on the
current usage. To do this the CPU must have the capability to
-switch the frequency very quickly. There are a number of sysfs file
-accessible parameters:
-
-sampling_rate: measured in uS (10^-6 seconds), this is how often you
-want the kernel to look at the CPU usage and to make decisions on
-what to do about the frequency. Typically this is set to values of
-around '10000' or more.
-
-show_sampling_rate_(min|max): the minimum and maximum sampling rates
-available that you may set 'sampling_rate' to.
-
-up_threshold: defines what the average CPU usaged between the samplings
-of 'sampling_rate' needs to be for the kernel to make a decision on
-whether it should increase the frequency. For example when it is set
-to its default value of '80' it means that between the checking
-intervals the CPU needs to be on average more than 80% in use to then
-decide that the CPU frequency needs to be increased.
-
-sampling_down_factor: this parameter controls the rate that the CPU
-makes a decision on when to decrease the frequency. When set to its
-default value of '5' it means that at 1/5 the sampling_rate the kernel
-makes a decision to lower the frequency. Five "lower rate" decisions
-have to be made in a row before the CPU frequency is actually lower.
-If set to '1' then the frequency decreases as quickly as it increases,
-if set to '2' it decreases at half the rate of the increase.
-
-ignore_nice_load: this parameter takes a value of '0' or '1', when set
-to '0' (its default) then all processes are counted towards towards the
-'cpu utilisation' value. When set to '1' then processes that are
-run with a 'nice' value will not count (and thus be ignored) in the
-overal usage calculation. This is useful if you are running a CPU
-intensive calculation on your laptop that you do not care how long it
-takes to complete as you can 'nice' it and prevent it from taking part
-in the deciding process of whether to increase your CPU frequency.
-
-
-2.5 Conservative
-----------------
-
-The CPUfreq governor "conservative", much like the "ondemand"
-governor, sets the CPU depending on the current usage. It differs in
-behaviour in that it gracefully increases and decreases the CPU speed
-rather than jumping to max speed the moment there is any load on the
-CPU. This behaviour more suitable in a battery powered environment.
-The governor is tweaked in the same manner as the "ondemand" governor
-through sysfs with the addition of:
-
-freq_step: this describes what percentage steps the cpu freq should be
-increased and decreased smoothly by. By default the cpu frequency will
-increase in 5% chunks of your maximum cpu frequency. You can change this
-value to anywhere between 0 and 100 where '0' will effectively lock your
-CPU at a speed regardless of its load whilst '100' will, in theory, make
-it behave identically to the "ondemand" governor.
-
-down_threshold: same as the 'up_threshold' found for the "ondemand"
-governor but for the opposite direction. For example when set to its
-default value of '20' it means that if the CPU usage needs to be below
-20% between samples to have the frequency decreased.
+switch the frequency very fast.
+
+
3. The Governor Interface in the CPUfreq Core
=============================================
diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt
index 8ae8dad8e150..9b743198f77a 100644
--- a/trunk/Documentation/feature-removal-schedule.txt
+++ b/trunk/Documentation/feature-removal-schedule.txt
@@ -47,6 +47,17 @@ Who: Paul E. McKenney
---------------------------
+What: IEEE1394 Audio and Music Data Transmission Protocol driver,
+ Connection Management Procedures driver
+When: November 2005
+Files: drivers/ieee1394/{amdtp,cmp}*
+Why: These are incomplete, have never worked, and are better implemented
+ in userland via raw1394 (see http://freebob.sourceforge.net/ for
+ example.)
+Who: Jody McIntyre
+
+---------------------------
+
What: raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
When: November 2005
Why: Deprecated in favour of the new ioctl-based rawiso interface, which is
diff --git a/trunk/Documentation/filesystems/00-INDEX b/trunk/Documentation/filesystems/00-INDEX
index 7e17712f3229..628f8a7adb85 100644
--- a/trunk/Documentation/filesystems/00-INDEX
+++ b/trunk/Documentation/filesystems/00-INDEX
@@ -12,12 +12,16 @@ cifs.txt
- description of the CIFS filesystem
coda.txt
- description of the CODA filesystem.
+configfs/
+ - directory containing configfs documentation and example code.
cramfs.txt
- info on the cram filesystem for small storage (ROMs etc)
devfs/
- directory containing devfs documentation.
ext2.txt
- info, mount options and specifications for the Ext2 filesystem.
+fat_cvf.txt
+ - info on the Compressed Volume Files extension to the FAT filesystem
hpfs.txt
- info and mount options for the OS/2 HPFS.
isofs.txt
diff --git a/trunk/Documentation/filesystems/configfs/configfs.txt b/trunk/Documentation/filesystems/configfs/configfs.txt
new file mode 100644
index 000000000000..c4ff96b7c4e0
--- /dev/null
+++ b/trunk/Documentation/filesystems/configfs/configfs.txt
@@ -0,0 +1,434 @@
+
+configfs - Userspace-driven kernel object configuation.
+
+Joel Becker
+
+Updated: 31 March 2005
+
+Copyright (c) 2005 Oracle Corporation,
+ Joel Becker
+
+
+[What is configfs?]
+
+configfs is a ram-based filesystem that provides the converse of
+sysfs's functionality. Where sysfs is a filesystem-based view of
+kernel objects, configfs is a filesystem-based manager of kernel
+objects, or config_items.
+
+With sysfs, an object is created in kernel (for example, when a device
+is discovered) and it is registered with sysfs. Its attributes then
+appear in sysfs, allowing userspace to read the attributes via
+readdir(3)/read(2). It may allow some attributes to be modified via
+write(2). The important point is that the object is created and
+destroyed in kernel, the kernel controls the lifecycle of the sysfs
+representation, and sysfs is merely a window on all this.
+
+A configfs config_item is created via an explicit userspace operation:
+mkdir(2). It is destroyed via rmdir(2). The attributes appear at
+mkdir(2) time, and can be read or modified via read(2) and write(2).
+As with sysfs, readdir(3) queries the list of items and/or attributes.
+symlink(2) can be used to group items together. Unlike sysfs, the
+lifetime of the representation is completely driven by userspace. The
+kernel modules backing the items must respond to this.
+
+Both sysfs and configfs can and should exist together on the same
+system. One is not a replacement for the other.
+
+[Using configfs]
+
+configfs can be compiled as a module or into the kernel. You can access
+it by doing
+
+ mount -t configfs none /config
+
+The configfs tree will be empty unless client modules are also loaded.
+These are modules that register their item types with configfs as
+subsystems. Once a client subsystem is loaded, it will appear as a
+subdirectory (or more than one) under /config. Like sysfs, the
+configfs tree is always there, whether mounted on /config or not.
+
+An item is created via mkdir(2). The item's attributes will also
+appear at this time. readdir(3) can determine what the attributes are,
+read(2) can query their default values, and write(2) can store new
+values. Like sysfs, attributes should be ASCII text files, preferably
+with only one value per file. The same efficiency caveats from sysfs
+apply. Don't mix more than one attribute in one attribute file.
+
+Like sysfs, configfs expects write(2) to store the entire buffer at
+once. When writing to configfs attributes, userspace processes should
+first read the entire file, modify the portions they wish to change, and
+then write the entire buffer back. Attribute files have a maximum size
+of one page (PAGE_SIZE, 4096 on i386).
+
+When an item needs to be destroyed, remove it with rmdir(2). An
+item cannot be destroyed if any other item has a link to it (via
+symlink(2)). Links can be removed via unlink(2).
+
+[Configuring FakeNBD: an Example]
+
+Imagine there's a Network Block Device (NBD) driver that allows you to
+access remote block devices. Call it FakeNBD. FakeNBD uses configfs
+for its configuration. Obviously, there will be a nice program that
+sysadmins use to configure FakeNBD, but somehow that program has to tell
+the driver about it. Here's where configfs comes in.
+
+When the FakeNBD driver is loaded, it registers itself with configfs.
+readdir(3) sees this just fine:
+
+ # ls /config
+ fakenbd
+
+A fakenbd connection can be created with mkdir(2). The name is
+arbitrary, but likely the tool will make some use of the name. Perhaps
+it is a uuid or a disk name:
+
+ # mkdir /config/fakenbd/disk1
+ # ls /config/fakenbd/disk1
+ target device rw
+
+The target attribute contains the IP address of the server FakeNBD will
+connect to. The device attribute is the device on the server.
+Predictably, the rw attribute determines whether the connection is
+read-only or read-write.
+
+ # echo 10.0.0.1 > /config/fakenbd/disk1/target
+ # echo /dev/sda1 > /config/fakenbd/disk1/device
+ # echo 1 > /config/fakenbd/disk1/rw
+
+That's it. That's all there is. Now the device is configured, via the
+shell no less.
+
+[Coding With configfs]
+
+Every object in configfs is a config_item. A config_item reflects an
+object in the subsystem. It has attributes that match values on that
+object. configfs handles the filesystem representation of that object
+and its attributes, allowing the subsystem to ignore all but the
+basic show/store interaction.
+
+Items are created and destroyed inside a config_group. A group is a
+collection of items that share the same attributes and operations.
+Items are created by mkdir(2) and removed by rmdir(2), but configfs
+handles that. The group has a set of operations to perform these tasks
+
+A subsystem is the top level of a client module. During initialization,
+the client module registers the subsystem with configfs, the subsystem
+appears as a directory at the top of the configfs filesystem. A
+subsystem is also a config_group, and can do everything a config_group
+can.
+
+[struct config_item]
+
+ struct config_item {
+ char *ci_name;
+ char ci_namebuf[UOBJ_NAME_LEN];
+ struct kref ci_kref;
+ struct list_head ci_entry;
+ struct config_item *ci_parent;
+ struct config_group *ci_group;
+ struct config_item_type *ci_type;
+ struct dentry *ci_dentry;
+ };
+
+ void config_item_init(struct config_item *);
+ void config_item_init_type_name(struct config_item *,
+ const char *name,
+ struct config_item_type *type);
+ struct config_item *config_item_get(struct config_item *);
+ void config_item_put(struct config_item *);
+
+Generally, struct config_item is embedded in a container structure, a
+structure that actually represents what the subsystem is doing. The
+config_item portion of that structure is how the object interacts with
+configfs.
+
+Whether statically defined in a source file or created by a parent
+config_group, a config_item must have one of the _init() functions
+called on it. This initializes the reference count and sets up the
+appropriate fields.
+
+All users of a config_item should have a reference on it via
+config_item_get(), and drop the reference when they are done via
+config_item_put().
+
+By itself, a config_item cannot do much more than appear in configfs.
+Usually a subsystem wants the item to display and/or store attributes,
+among other things. For that, it needs a type.
+
+[struct config_item_type]
+
+ struct configfs_item_operations {
+ void (*release)(struct config_item *);
+ ssize_t (*show_attribute)(struct config_item *,
+ struct configfs_attribute *,
+ char *);
+ ssize_t (*store_attribute)(struct config_item *,
+ struct configfs_attribute *,
+ const char *, size_t);
+ int (*allow_link)(struct config_item *src,
+ struct config_item *target);
+ int (*drop_link)(struct config_item *src,
+ struct config_item *target);
+ };
+
+ struct config_item_type {
+ struct module *ct_owner;
+ struct configfs_item_operations *ct_item_ops;
+ struct configfs_group_operations *ct_group_ops;
+ struct configfs_attribute **ct_attrs;
+ };
+
+The most basic function of a config_item_type is to define what
+operations can be performed on a config_item. All items that have been
+allocated dynamically will need to provide the ct_item_ops->release()
+method. This method is called when the config_item's reference count
+reaches zero. Items that wish to display an attribute need to provide
+the ct_item_ops->show_attribute() method. Similarly, storing a new
+attribute value uses the store_attribute() method.
+
+[struct configfs_attribute]
+
+ struct configfs_attribute {
+ char *ca_name;
+ struct module *ca_owner;
+ mode_t ca_mode;
+ };
+
+When a config_item wants an attribute to appear as a file in the item's
+configfs directory, it must define a configfs_attribute describing it.
+It then adds the attribute to the NULL-terminated array
+config_item_type->ct_attrs. When the item appears in configfs, the
+attribute file will appear with the configfs_attribute->ca_name
+filename. configfs_attribute->ca_mode specifies the file permissions.
+
+If an attribute is readable and the config_item provides a
+ct_item_ops->show_attribute() method, that method will be called
+whenever userspace asks for a read(2) on the attribute. The converse
+will happen for write(2).
+
+[struct config_group]
+
+A config_item cannot live in a vaccum. The only way one can be created
+is via mkdir(2) on a config_group. This will trigger creation of a
+child item.
+
+ struct config_group {
+ struct config_item cg_item;
+ struct list_head cg_children;
+ struct configfs_subsystem *cg_subsys;
+ struct config_group **default_groups;
+ };
+
+ void config_group_init(struct config_group *group);
+ void config_group_init_type_name(struct config_group *group,
+ const char *name,
+ struct config_item_type *type);
+
+
+The config_group structure contains a config_item. Properly configuring
+that item means that a group can behave as an item in its own right.
+However, it can do more: it can create child items or groups. This is
+accomplished via the group operations specified on the group's
+config_item_type.
+
+ struct configfs_group_operations {
+ struct config_item *(*make_item)(struct config_group *group,
+ const char *name);
+ struct config_group *(*make_group)(struct config_group *group,
+ const char *name);
+ int (*commit_item)(struct config_item *item);
+ void (*drop_item)(struct config_group *group,
+ struct config_item *item);
+ };
+
+A group creates child items by providing the
+ct_group_ops->make_item() method. If provided, this method is called from mkdir(2) in the group's directory. The subsystem allocates a new
+config_item (or more likely, its container structure), initializes it,
+and returns it to configfs. Configfs will then populate the filesystem
+tree to reflect the new item.
+
+If the subsystem wants the child to be a group itself, the subsystem
+provides ct_group_ops->make_group(). Everything else behaves the same,
+using the group _init() functions on the group.
+
+Finally, when userspace calls rmdir(2) on the item or group,
+ct_group_ops->drop_item() is called. As a config_group is also a
+config_item, it is not necessary for a seperate drop_group() method.
+The subsystem must config_item_put() the reference that was initialized
+upon item allocation. If a subsystem has no work to do, it may omit
+the ct_group_ops->drop_item() method, and configfs will call
+config_item_put() on the item on behalf of the subsystem.
+
+IMPORTANT: drop_item() is void, and as such cannot fail. When rmdir(2)
+is called, configfs WILL remove the item from the filesystem tree
+(assuming that it has no children to keep it busy). The subsystem is
+responsible for responding to this. If the subsystem has references to
+the item in other threads, the memory is safe. It may take some time
+for the item to actually disappear from the subsystem's usage. But it
+is gone from configfs.
+
+A config_group cannot be removed while it still has child items. This
+is implemented in the configfs rmdir(2) code. ->drop_item() will not be
+called, as the item has not been dropped. rmdir(2) will fail, as the
+directory is not empty.
+
+[struct configfs_subsystem]
+
+A subsystem must register itself, ususally at module_init time. This
+tells configfs to make the subsystem appear in the file tree.
+
+ struct configfs_subsystem {
+ struct config_group su_group;
+ struct semaphore su_sem;
+ };
+
+ int configfs_register_subsystem(struct configfs_subsystem *subsys);
+ void configfs_unregister_subsystem(struct configfs_subsystem *subsys);
+
+ A subsystem consists of a toplevel config_group and a semaphore.
+The group is where child config_items are created. For a subsystem,
+this group is usually defined statically. Before calling
+configfs_register_subsystem(), the subsystem must have initialized the
+group via the usual group _init() functions, and it must also have
+initialized the semaphore.
+ When the register call returns, the subsystem is live, and it
+will be visible via configfs. At that point, mkdir(2) can be called and
+the subsystem must be ready for it.
+
+[An Example]
+
+The best example of these basic concepts is the simple_children
+subsystem/group and the simple_child item in configfs_example.c It
+shows a trivial object displaying and storing an attribute, and a simple
+group creating and destroying these children.
+
+[Hierarchy Navigation and the Subsystem Semaphore]
+
+There is an extra bonus that configfs provides. The config_groups and
+config_items are arranged in a hierarchy due to the fact that they
+appear in a filesystem. A subsystem is NEVER to touch the filesystem
+parts, but the subsystem might be interested in this hierarchy. For
+this reason, the hierarchy is mirrored via the config_group->cg_children
+and config_item->ci_parent structure members.
+
+A subsystem can navigate the cg_children list and the ci_parent pointer
+to see the tree created by the subsystem. This can race with configfs'
+management of the hierarchy, so configfs uses the subsystem semaphore to
+protect modifications. Whenever a subsystem wants to navigate the
+hierarchy, it must do so under the protection of the subsystem
+semaphore.
+
+A subsystem will be prevented from acquiring the semaphore while a newly
+allocated item has not been linked into this hierarchy. Similarly, it
+will not be able to acquire the semaphore while a dropping item has not
+yet been unlinked. This means that an item's ci_parent pointer will
+never be NULL while the item is in configfs, and that an item will only
+be in its parent's cg_children list for the same duration. This allows
+a subsystem to trust ci_parent and cg_children while they hold the
+semaphore.
+
+[Item Aggregation Via symlink(2)]
+
+configfs provides a simple group via the group->item parent/child
+relationship. Often, however, a larger environment requires aggregation
+outside of the parent/child connection. This is implemented via
+symlink(2).
+
+A config_item may provide the ct_item_ops->allow_link() and
+ct_item_ops->drop_link() methods. If the ->allow_link() method exists,
+symlink(2) may be called with the config_item as the source of the link.
+These links are only allowed between configfs config_items. Any
+symlink(2) attempt outside the configfs filesystem will be denied.
+
+When symlink(2) is called, the source config_item's ->allow_link()
+method is called with itself and a target item. If the source item
+allows linking to target item, it returns 0. A source item may wish to
+reject a link if it only wants links to a certain type of object (say,
+in its own subsystem).
+
+When unlink(2) is called on the symbolic link, the source item is
+notified via the ->drop_link() method. Like the ->drop_item() method,
+this is a void function and cannot return failure. The subsystem is
+responsible for responding to the change.
+
+A config_item cannot be removed while it links to any other item, nor
+can it be removed while an item links to it. Dangling symlinks are not
+allowed in configfs.
+
+[Automatically Created Subgroups]
+
+A new config_group may want to have two types of child config_items.
+While this could be codified by magic names in ->make_item(), it is much
+more explicit to have a method whereby userspace sees this divergence.
+
+Rather than have a group where some items behave differently than
+others, configfs provides a method whereby one or many subgroups are
+automatically created inside the parent at its creation. Thus,
+mkdir("parent) results in "parent", "parent/subgroup1", up through
+"parent/subgroupN". Items of type 1 can now be created in
+"parent/subgroup1", and items of type N can be created in
+"parent/subgroupN".
+
+These automatic subgroups, or default groups, do not preclude other
+children of the parent group. If ct_group_ops->make_group() exists,
+other child groups can be created on the parent group directly.
+
+A configfs subsystem specifies default groups by filling in the
+NULL-terminated array default_groups on the config_group structure.
+Each group in that array is populated in the configfs tree at the same
+time as the parent group. Similarly, they are removed at the same time
+as the parent. No extra notification is provided. When a ->drop_item()
+method call notifies the subsystem the parent group is going away, it
+also means every default group child associated with that parent group.
+
+As a consequence of this, default_groups cannot be removed directly via
+rmdir(2). They also are not considered when rmdir(2) on the parent
+group is checking for children.
+
+[Committable Items]
+
+NOTE: Committable items are currently unimplemented.
+
+Some config_items cannot have a valid initial state. That is, no
+default values can be specified for the item's attributes such that the
+item can do its work. Userspace must configure one or more attributes,
+after which the subsystem can start whatever entity this item
+represents.
+
+Consider the FakeNBD device from above. Without a target address *and*
+a target device, the subsystem has no idea what block device to import.
+The simple example assumes that the subsystem merely waits until all the
+appropriate attributes are configured, and then connects. This will,
+indeed, work, but now every attribute store must check if the attributes
+are initialized. Every attribute store must fire off the connection if
+that condition is met.
+
+Far better would be an explicit action notifying the subsystem that the
+config_item is ready to go. More importantly, an explicit action allows
+the subsystem to provide feedback as to whether the attibutes are
+initialized in a way that makes sense. configfs provides this as
+committable items.
+
+configfs still uses only normal filesystem operations. An item is
+committed via rename(2). The item is moved from a directory where it
+can be modified to a directory where it cannot.
+
+Any group that provides the ct_group_ops->commit_item() method has
+committable items. When this group appears in configfs, mkdir(2) will
+not work directly in the group. Instead, the group will have two
+subdirectories: "live" and "pending". The "live" directory does not
+support mkdir(2) or rmdir(2) either. It only allows rename(2). The
+"pending" directory does allow mkdir(2) and rmdir(2). An item is
+created in the "pending" directory. Its attributes can be modified at
+will. Userspace commits the item by renaming it into the "live"
+directory. At this point, the subsystem recieves the ->commit_item()
+callback. If all required attributes are filled to satisfaction, the
+method returns zero and the item is moved to the "live" directory.
+
+As rmdir(2) does not work in the "live" directory, an item must be
+shutdown, or "uncommitted". Again, this is done via rename(2), this
+time from the "live" directory back to the "pending" one. The subsystem
+is notified by the ct_group_ops->uncommit_object() method.
+
+
diff --git a/trunk/Documentation/filesystems/configfs/configfs_example.c b/trunk/Documentation/filesystems/configfs/configfs_example.c
new file mode 100644
index 000000000000..f3c6e4946f98
--- /dev/null
+++ b/trunk/Documentation/filesystems/configfs/configfs_example.c
@@ -0,0 +1,474 @@
+/*
+ * vim: noexpandtab ts=8 sts=0 sw=8:
+ *
+ * configfs_example.c - This file is a demonstration module containing
+ * a number of configfs subsystems.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Based on sysfs:
+ * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
+ *
+ * configfs Copyright (C) 2005 Oracle. All rights reserved.
+ */
+
+#include
+#include
+#include
+
+#include
+
+
+
+/*
+ * 01-childless
+ *
+ * This first example is a childless subsystem. It cannot create
+ * any config_items. It just has attributes.
+ *
+ * Note that we are enclosing the configfs_subsystem inside a container.
+ * This is not necessary if a subsystem has no attributes directly
+ * on the subsystem. See the next example, 02-simple-children, for
+ * such a subsystem.
+ */
+
+struct childless {
+ struct configfs_subsystem subsys;
+ int showme;
+ int storeme;
+};
+
+struct childless_attribute {
+ struct configfs_attribute attr;
+ ssize_t (*show)(struct childless *, char *);
+ ssize_t (*store)(struct childless *, const char *, size_t);
+};
+
+static inline struct childless *to_childless(struct config_item *item)
+{
+ return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
+}
+
+static ssize_t childless_showme_read(struct childless *childless,
+ char *page)
+{
+ ssize_t pos;
+
+ pos = sprintf(page, "%d\n", childless->showme);
+ childless->showme++;
+
+ return pos;
+}
+
+static ssize_t childless_storeme_read(struct childless *childless,
+ char *page)
+{
+ return sprintf(page, "%d\n", childless->storeme);
+}
+
+static ssize_t childless_storeme_write(struct childless *childless,
+ const char *page,
+ size_t count)
+{
+ unsigned long tmp;
+ char *p = (char *) page;
+
+ tmp = simple_strtoul(p, &p, 10);
+ if (!p || (*p && (*p != '\n')))
+ return -EINVAL;
+
+ if (tmp > INT_MAX)
+ return -ERANGE;
+
+ childless->storeme = tmp;
+
+ return count;
+}
+
+static ssize_t childless_description_read(struct childless *childless,
+ char *page)
+{
+ return sprintf(page,
+"[01-childless]\n"
+"\n"
+"The childless subsystem is the simplest possible subsystem in\n"
+"configfs. It does not support the creation of child config_items.\n"
+"It only has a few attributes. In fact, it isn't much different\n"
+"than a directory in /proc.\n");
+}
+
+static struct childless_attribute childless_attr_showme = {
+ .attr = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO },
+ .show = childless_showme_read,
+};
+static struct childless_attribute childless_attr_storeme = {
+ .attr = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR },
+ .show = childless_storeme_read,
+ .store = childless_storeme_write,
+};
+static struct childless_attribute childless_attr_description = {
+ .attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO },
+ .show = childless_description_read,
+};
+
+static struct configfs_attribute *childless_attrs[] = {
+ &childless_attr_showme.attr,
+ &childless_attr_storeme.attr,
+ &childless_attr_description.attr,
+ NULL,
+};
+
+static ssize_t childless_attr_show(struct config_item *item,
+ struct configfs_attribute *attr,
+ char *page)
+{
+ struct childless *childless = to_childless(item);
+ struct childless_attribute *childless_attr =
+ container_of(attr, struct childless_attribute, attr);
+ ssize_t ret = 0;
+
+ if (childless_attr->show)
+ ret = childless_attr->show(childless, page);
+ return ret;
+}
+
+static ssize_t childless_attr_store(struct config_item *item,
+ struct configfs_attribute *attr,
+ const char *page, size_t count)
+{
+ struct childless *childless = to_childless(item);
+ struct childless_attribute *childless_attr =
+ container_of(attr, struct childless_attribute, attr);
+ ssize_t ret = -EINVAL;
+
+ if (childless_attr->store)
+ ret = childless_attr->store(childless, page, count);
+ return ret;
+}
+
+static struct configfs_item_operations childless_item_ops = {
+ .show_attribute = childless_attr_show,
+ .store_attribute = childless_attr_store,
+};
+
+static struct config_item_type childless_type = {
+ .ct_item_ops = &childless_item_ops,
+ .ct_attrs = childless_attrs,
+ .ct_owner = THIS_MODULE,
+};
+
+static struct childless childless_subsys = {
+ .subsys = {
+ .su_group = {
+ .cg_item = {
+ .ci_namebuf = "01-childless",
+ .ci_type = &childless_type,
+ },
+ },
+ },
+};
+
+
+/* ----------------------------------------------------------------- */
+
+/*
+ * 02-simple-children
+ *
+ * This example merely has a simple one-attribute child. Note that
+ * there is no extra attribute structure, as the child's attribute is
+ * known from the get-go. Also, there is no container for the
+ * subsystem, as it has no attributes of its own.
+ */
+
+struct simple_child {
+ struct config_item item;
+ int storeme;
+};
+
+static inline struct simple_child *to_simple_child(struct config_item *item)
+{
+ return item ? container_of(item, struct simple_child, item) : NULL;
+}
+
+static struct configfs_attribute simple_child_attr_storeme = {
+ .ca_owner = THIS_MODULE,
+ .ca_name = "storeme",
+ .ca_mode = S_IRUGO | S_IWUSR,
+};
+
+static struct configfs_attribute *simple_child_attrs[] = {
+ &simple_child_attr_storeme,
+ NULL,
+};
+
+static ssize_t simple_child_attr_show(struct config_item *item,
+ struct configfs_attribute *attr,
+ char *page)
+{
+ ssize_t count;
+ struct simple_child *simple_child = to_simple_child(item);
+
+ count = sprintf(page, "%d\n", simple_child->storeme);
+
+ return count;
+}
+
+static ssize_t simple_child_attr_store(struct config_item *item,
+ struct configfs_attribute *attr,
+ const char *page, size_t count)
+{
+ struct simple_child *simple_child = to_simple_child(item);
+ unsigned long tmp;
+ char *p = (char *) page;
+
+ tmp = simple_strtoul(p, &p, 10);
+ if (!p || (*p && (*p != '\n')))
+ return -EINVAL;
+
+ if (tmp > INT_MAX)
+ return -ERANGE;
+
+ simple_child->storeme = tmp;
+
+ return count;
+}
+
+static void simple_child_release(struct config_item *item)
+{
+ kfree(to_simple_child(item));
+}
+
+static struct configfs_item_operations simple_child_item_ops = {
+ .release = simple_child_release,
+ .show_attribute = simple_child_attr_show,
+ .store_attribute = simple_child_attr_store,
+};
+
+static struct config_item_type simple_child_type = {
+ .ct_item_ops = &simple_child_item_ops,
+ .ct_attrs = simple_child_attrs,
+ .ct_owner = THIS_MODULE,
+};
+
+
+static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
+{
+ struct simple_child *simple_child;
+
+ simple_child = kmalloc(sizeof(struct simple_child), GFP_KERNEL);
+ if (!simple_child)
+ return NULL;
+
+ memset(simple_child, 0, sizeof(struct simple_child));
+
+ config_item_init_type_name(&simple_child->item, name,
+ &simple_child_type);
+
+ simple_child->storeme = 0;
+
+ return &simple_child->item;
+}
+
+static struct configfs_attribute simple_children_attr_description = {
+ .ca_owner = THIS_MODULE,
+ .ca_name = "description",
+ .ca_mode = S_IRUGO,
+};
+
+static struct configfs_attribute *simple_children_attrs[] = {
+ &simple_children_attr_description,
+ NULL,
+};
+
+static ssize_t simple_children_attr_show(struct config_item *item,
+ struct configfs_attribute *attr,
+ char *page)
+{
+ return sprintf(page,
+"[02-simple-children]\n"
+"\n"
+"This subsystem allows the creation of child config_items. These\n"
+"items have only one attribute that is readable and writeable.\n");
+}
+
+static struct configfs_item_operations simple_children_item_ops = {
+ .show_attribute = simple_children_attr_show,
+};
+
+/*
+ * Note that, since no extra work is required on ->drop_item(),
+ * no ->drop_item() is provided.
+ */
+static struct configfs_group_operations simple_children_group_ops = {
+ .make_item = simple_children_make_item,
+};
+
+static struct config_item_type simple_children_type = {
+ .ct_item_ops = &simple_children_item_ops,
+ .ct_group_ops = &simple_children_group_ops,
+ .ct_attrs = simple_children_attrs,
+};
+
+static struct configfs_subsystem simple_children_subsys = {
+ .su_group = {
+ .cg_item = {
+ .ci_namebuf = "02-simple-children",
+ .ci_type = &simple_children_type,
+ },
+ },
+};
+
+
+/* ----------------------------------------------------------------- */
+
+/*
+ * 03-group-children
+ *
+ * This example reuses the simple_children group from above. However,
+ * the simple_children group is not the subsystem itself, it is a
+ * child of the subsystem. Creation of a group in the subsystem creates
+ * a new simple_children group. That group can then have simple_child
+ * children of its own.
+ */
+
+struct simple_children {
+ struct config_group group;
+};
+
+static struct config_group *group_children_make_group(struct config_group *group, const char *name)
+{
+ struct simple_children *simple_children;
+
+ simple_children = kmalloc(sizeof(struct simple_children),
+ GFP_KERNEL);
+ if (!simple_children)
+ return NULL;
+
+ memset(simple_children, 0, sizeof(struct simple_children));
+
+ config_group_init_type_name(&simple_children->group, name,
+ &simple_children_type);
+
+ return &simple_children->group;
+}
+
+static struct configfs_attribute group_children_attr_description = {
+ .ca_owner = THIS_MODULE,
+ .ca_name = "description",
+ .ca_mode = S_IRUGO,
+};
+
+static struct configfs_attribute *group_children_attrs[] = {
+ &group_children_attr_description,
+ NULL,
+};
+
+static ssize_t group_children_attr_show(struct config_item *item,
+ struct configfs_attribute *attr,
+ char *page)
+{
+ return sprintf(page,
+"[03-group-children]\n"
+"\n"
+"This subsystem allows the creation of child config_groups. These\n"
+"groups are like the subsystem simple-children.\n");
+}
+
+static struct configfs_item_operations group_children_item_ops = {
+ .show_attribute = group_children_attr_show,
+};
+
+/*
+ * Note that, since no extra work is required on ->drop_item(),
+ * no ->drop_item() is provided.
+ */
+static struct configfs_group_operations group_children_group_ops = {
+ .make_group = group_children_make_group,
+};
+
+static struct config_item_type group_children_type = {
+ .ct_item_ops = &group_children_item_ops,
+ .ct_group_ops = &group_children_group_ops,
+ .ct_attrs = group_children_attrs,
+};
+
+static struct configfs_subsystem group_children_subsys = {
+ .su_group = {
+ .cg_item = {
+ .ci_namebuf = "03-group-children",
+ .ci_type = &group_children_type,
+ },
+ },
+};
+
+/* ----------------------------------------------------------------- */
+
+/*
+ * We're now done with our subsystem definitions.
+ * For convenience in this module, here's a list of them all. It
+ * allows the init function to easily register them. Most modules
+ * will only have one subsystem, and will only call register_subsystem
+ * on it directly.
+ */
+static struct configfs_subsystem *example_subsys[] = {
+ &childless_subsys.subsys,
+ &simple_children_subsys,
+ &group_children_subsys,
+ NULL,
+};
+
+static int __init configfs_example_init(void)
+{
+ int ret;
+ int i;
+ struct configfs_subsystem *subsys;
+
+ for (i = 0; example_subsys[i]; i++) {
+ subsys = example_subsys[i];
+
+ config_group_init(&subsys->su_group);
+ init_MUTEX(&subsys->su_sem);
+ ret = configfs_register_subsystem(subsys);
+ if (ret) {
+ printk(KERN_ERR "Error %d while registering subsystem %s\n",
+ ret,
+ subsys->su_group.cg_item.ci_namebuf);
+ goto out_unregister;
+ }
+ }
+
+ return 0;
+
+out_unregister:
+ for (; i >= 0; i--) {
+ configfs_unregister_subsystem(example_subsys[i]);
+ }
+
+ return ret;
+}
+
+static void __exit configfs_example_exit(void)
+{
+ int i;
+
+ for (i = 0; example_subsys[i]; i++) {
+ configfs_unregister_subsystem(example_subsys[i]);
+ }
+}
+
+module_init(configfs_example_init);
+module_exit(configfs_example_exit);
+MODULE_LICENSE("GPL");
diff --git a/trunk/Documentation/filesystems/vfs.txt b/trunk/Documentation/filesystems/vfs.txt
index e56e842847d3..ee4c0a8b8db7 100644
--- a/trunk/Documentation/filesystems/vfs.txt
+++ b/trunk/Documentation/filesystems/vfs.txt
@@ -162,8 +162,9 @@ get_sb() method fills in is the "s_op" field. This is a pointer to
a "struct super_operations" which describes the next level of the
filesystem implementation.
-Usually, a filesystem uses one of the generic get_sb() implementations
-and provides a fill_super() method instead. The generic methods are:
+Usually, a filesystem uses generic one of the generic get_sb()
+implementations and provides a fill_super() method instead. The
+generic methods are:
get_sb_bdev: mount a filesystem residing on a block device
diff --git a/trunk/Documentation/kbuild/modules.txt b/trunk/Documentation/kbuild/modules.txt
index 1c0db652b366..c91caf7eb303 100644
--- a/trunk/Documentation/kbuild/modules.txt
+++ b/trunk/Documentation/kbuild/modules.txt
@@ -38,7 +38,7 @@ included in the kernel tree.
What is covered within this file is mainly information to authors
of modules. The author of an external modules should supply
a makefile that hides most of the complexity so one only has to type
-'make' to build the module. A complete example will be present in
+'make' to buld the module. A complete example will be present in
chapter ¤. Creating a kbuild file for an external module".
@@ -69,7 +69,7 @@ when building an external module.
--- 2.2 Available targets
- $KDIR refers to the path to the kernel source top-level directory
+ $KDIR refers to path to kernel source top-level directory
make -C $KDIR M=`pwd`
Will build the module(s) located in current directory.
@@ -87,11 +87,11 @@ when building an external module.
make -C $KDIR M=$PWD modules_install
Install the external module(s).
Installation default is in /lib/modules//extra,
- but may be prefixed with INSTALL_MOD_PATH - see separate chapter.
+ but may be prefixed with INSTALL_MOD_PATH - see separate chater.
make -C $KDIR M=$PWD clean
Remove all generated files for the module - the kernel
- source directory is not modified.
+ source directory is not moddified.
make -C $KDIR M=`pwd` help
help will list the available target when building external
@@ -99,7 +99,7 @@ when building an external module.
--- 2.3 Available options:
- $KDIR refers to the path to the kernel source top-level directory
+ $KDIR refer to path to kernel src
make -C $KDIR
Used to specify where to find the kernel source.
@@ -206,11 +206,11 @@ following files:
KERNELDIR := /lib/modules/`uname -r`/build
all::
- $(MAKE) -C $(KERNELDIR) M=`pwd` $@
+ $(MAKE) -C $KERNELDIR M=`pwd` $@
# Module specific targets
genbin:
- echo "X" > 8123_bin.o_shipped
+ echo "X" > 8123_bini.o_shipped
endif
@@ -341,13 +341,13 @@ directory and therefore needs to deal with this in their kbuild file.
EXTRA_CFLAGS := -Iinclude
8123-y := 8123_if.o 8123_pci.o 8123_bin.o
- Note that in the assignment there is no space between -I and the path.
- This is a kbuild limitation: there must be no space present.
+ Note that in the assingment there is no space between -I and the path.
+ This is a kbuild limitation and no space must be present.
=== 6. Module installation
-Modules which are included in the kernel are installed in the directory:
+Modules which are included in the kernel is installed in the directory:
/lib/modules/$(KERNELRELEASE)/kernel
@@ -365,7 +365,7 @@ External modules are installed in the directory:
=> Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel
INSTALL_MOD_PATH may be set as an ordinary shell variable or as in the
- example above be specified on the command line when calling make.
+ example above be specified on the commandline when calling make.
INSTALL_MOD_PATH has effect both when installing modules included in
the kernel as well as when installing external modules.
@@ -384,7 +384,7 @@ External modules are installed in the directory:
=== 7. Module versioning
-Module versioning is enabled by the CONFIG_MODVERSIONS tag.
+Module versioning are enabled by the CONFIG_MODVERSIONS tag.
Module versioning is used as a simple ABI consistency check. The Module
versioning creates a CRC value of the full prototype for an exported symbol and
diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt
index 61a56b100c62..5dffcfefc3c7 100644
--- a/trunk/Documentation/kernel-parameters.txt
+++ b/trunk/Documentation/kernel-parameters.txt
@@ -633,14 +633,6 @@ running once the system is up.
inport.irq= [HW] Inport (ATI XL and Microsoft) busmouse driver
Format:
- combined_mode= [HW] control which driver uses IDE ports in combined
- mode: legacy IDE driver, libata, or both
- (in the libata case, libata.atapi_enabled=1 may be
- useful as well). Note that using the ide or libata
- options may affect your device naming (e.g. by
- changing hdc to sdb).
- Format: combined (default), ide, or libata
-
inttest= [IA64]
io7= [HW] IO7 for Marvel based alpha systems
diff --git a/trunk/Documentation/networking/gianfar.txt b/trunk/Documentation/networking/gianfar.txt
deleted file mode 100644
index ad474ea07d07..000000000000
--- a/trunk/Documentation/networking/gianfar.txt
+++ /dev/null
@@ -1,72 +0,0 @@
-The Gianfar Ethernet Driver
-Sysfs File description
-
-Author: Andy Fleming
-Updated: 2005-07-28
-
-SYSFS
-
-Several of the features of the gianfar driver are controlled
-through sysfs files. These are:
-
-bd_stash:
-To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
-bd_stash, echo 'off' or '0' to disable
-
-rx_stash_len:
-To stash the first n bytes of the packet in L2, echo the number
-of bytes to buf_stash_len. echo 0 to disable.
-
-WARNING: You could really screw these up if you set them too low or high!
-fifo_threshold:
-To change the number of bytes the controller needs in the
-fifo before it starts transmission, echo the number of bytes to
-fifo_thresh. Range should be 0-511.
-
-fifo_starve:
-When the FIFO has less than this many bytes during a transmit, it
-enters starve mode, and increases the priority of TX memory
-transactions. To change, echo the number of bytes to
-fifo_starve. Range should be 0-511.
-
-fifo_starve_off:
-Once in starve mode, the FIFO remains there until it has this
-many bytes. To change, echo the number of bytes to
-fifo_starve_off. Range should be 0-511.
-
-CHECKSUM OFFLOADING
-
-The eTSEC controller (first included in parts from late 2005 like
-the 8548) has the ability to perform TCP, UDP, and IP checksums
-in hardware. The Linux kernel only offloads the TCP and UDP
-checksums (and always performs the pseudo header checksums), so
-the driver only supports checksumming for TCP/IP and UDP/IP
-packets. Use ethtool to enable or disable this feature for RX
-and TX.
-
-VLAN
-
-In order to use VLAN, please consult Linux documentation on
-configuring VLANs. The gianfar driver supports hardware insertion and
-extraction of VLAN headers, but not filtering. Filtering will be
-done by the kernel.
-
-MULTICASTING
-
-The gianfar driver supports using the group hash table on the
-TSEC (and the extended hash table on the eTSEC) for multicast
-filtering. On the eTSEC, the exact-match MAC registers are used
-before the hash tables. See Linux documentation on how to join
-multicast groups.
-
-PADDING
-
-The gianfar driver supports padding received frames with 2 bytes
-to align the IP header to a 16-byte boundary, when supported by
-hardware.
-
-ETHTOOL
-
-The gianfar driver supports the use of ethtool for many
-configuration options. You must run ethtool only on currently
-open interfaces. See ethtool documentation for details.
diff --git a/trunk/Documentation/networking/ip-sysctl.txt b/trunk/Documentation/networking/ip-sysctl.txt
index 2b7cf19a06ad..ebc09a159f62 100644
--- a/trunk/Documentation/networking/ip-sysctl.txt
+++ b/trunk/Documentation/networking/ip-sysctl.txt
@@ -46,29 +46,6 @@ ipfrag_secret_interval - INTEGER
for the hash secret) for IP fragments.
Default: 600
-ipfrag_max_dist - INTEGER
- ipfrag_max_dist is a non-negative integer value which defines the
- maximum "disorder" which is allowed among fragments which share a
- common IP source address. Note that reordering of packets is
- not unusual, but if a large number of fragments arrive from a source
- IP address while a particular fragment queue remains incomplete, it
- probably indicates that one or more fragments belonging to that queue
- have been lost. When ipfrag_max_dist is positive, an additional check
- is done on fragments before they are added to a reassembly queue - if
- ipfrag_max_dist (or more) fragments have arrived from a particular IP
- address between additions to any IP fragment queue using that source
- address, it's presumed that one or more fragments in the queue are
- lost. The existing fragment queue will be dropped, and a new one
- started. An ipfrag_max_dist value of zero disables this check.
-
- Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
- result in unnecessarily dropping fragment queues when normal
- reordering of packets occurs, which could lead to poor application
- performance. Using a very large value, e.g. 50000, increases the
- likelihood of incorrectly reassembling IP fragments that originate
- from different IP datagrams, which could result in data corruption.
- Default: 64
-
INET peer storage:
inet_peer_threshold - INTEGER
diff --git a/trunk/Documentation/pcmcia/driver-changes.txt b/trunk/Documentation/pcmcia/driver-changes.txt
index 97420f08c786..403e7b4dcdd4 100644
--- a/trunk/Documentation/pcmcia/driver-changes.txt
+++ b/trunk/Documentation/pcmcia/driver-changes.txt
@@ -1,16 +1,5 @@
This file details changes in 2.6 which affect PCMCIA card driver authors:
-* Unify detach and REMOVAL event code, as well as attach and INSERTION
- code (as of 2.6.16)
- void (*remove) (struct pcmcia_device *dev);
- int (*probe) (struct pcmcia_device *dev);
-
-* Move suspend, resume and reset out of event handler (as of 2.6.16)
- int (*suspend) (struct pcmcia_device *dev);
- int (*resume) (struct pcmcia_device *dev);
- should be initialized in struct pcmcia_driver, and handle
- (SUSPEND == RESET_PHYSICAL) and (RESUME == CARD_RESET) events
-
* event handler initialization in struct pcmcia_driver (as of 2.6.13)
The event handler is notified of all events, and must be initialized
as the event() callback in the driver's struct pcmcia_driver.
diff --git a/trunk/Documentation/powerpc/eeh-pci-error-recovery.txt b/trunk/Documentation/powerpc/eeh-pci-error-recovery.txt
index 67a11a36270c..e75d7474322c 100644
--- a/trunk/Documentation/powerpc/eeh-pci-error-recovery.txt
+++ b/trunk/Documentation/powerpc/eeh-pci-error-recovery.txt
@@ -115,7 +115,7 @@ Current PPC64 Linux EEH Implementation
At this time, a generic EEH recovery mechanism has been implemented,
so that individual device drivers do not need to be modified to support
EEH recovery. This generic mechanism piggy-backs on the PCI hotplug
-infrastructure, and percolates events up through the userspace/udev
+infrastructure, and percolates events up through the hotplug/udev
infrastructure. Followiing is a detailed description of how this is
accomplished.
@@ -172,7 +172,7 @@ A handler for the EEH notifier_block events is implemented in
drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events().
It saves the device BAR's and then calls rpaphp_unconfig_pci_adapter().
This last call causes the device driver for the card to be stopped,
-which causes uevents to go out to user space. This triggers
+which causes hotplug events to go out to user space. This triggers
user-space scripts that might issue commands such as "ifdown eth0"
for ethernet cards, and so on. This handler then sleeps for 5 seconds,
hoping to give the user-space scripts enough time to complete.
@@ -258,30 +258,29 @@ rpa_php_unconfig_pci_adapter() { // in rpaphp_pci.c
calls
pci_destroy_dev (struct pci_dev *) {
calls
- device_unregister (&dev->dev) { // in /drivers/base/core.c
+ device_unregister (&dev->dev) { // in /drivers/base/core.c
calls
- device_del(struct device * dev) { // in /drivers/base/core.c
+ device_del(struct device * dev) { // in /drivers/base/core.c
calls
- kobject_del() { //in /libs/kobject.c
+ kobject_del() { //in /libs/kobject.c
calls
- kobject_uevent() { // in /libs/kobject.c
+ kobject_hotplug() { // in /libs/kobject.c
calls
- kset_uevent() { // in /lib/kobject.c
+ kset_hotplug() { // in /lib/kobject.c
calls
- kset->uevent_ops->uevent() // which is really just
+ kset->hotplug_ops->hotplug() which is really just
a call to
- dev_uevent() { // in /drivers/base/core.c
+ dev_hotplug() { // in /drivers/base/core.c
calls
- dev->bus->uevent() which is really just a call to
- pci_uevent () { // in drivers/pci/hotplug.c
+ dev->bus->hotplug() which is really just a call to
+ pci_hotplug () { // in drivers/pci/hotplug.c
which prints device name, etc....
}
}
- then kobject_uevent() sends a netlink uevent to userspace
- --> userspace uevent
- (during early boot, nobody listens to netlink events and
- kobject_uevent() executes uevent_helper[], which runs the
- event process /sbin/hotplug)
+ then kset_hotplug() calls
+ call_usermodehelper () with
+ argv[0]=hotplug_path[] which is "/sbin/hotplug"
+ --> event to userspace,
}
}
kobject_del() then calls sysfs_remove_dir(), which would
diff --git a/trunk/Documentation/scsi/ChangeLog.megaraid b/trunk/Documentation/scsi/ChangeLog.megaraid
index 09f6300eda4b..5331d91432c7 100644
--- a/trunk/Documentation/scsi/ChangeLog.megaraid
+++ b/trunk/Documentation/scsi/ChangeLog.megaraid
@@ -1,38 +1,3 @@
-Release Date : Fri Nov 11 12:27:22 EST 2005 - Seokmann Ju
-Current Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)
-Older Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
-
-1. Sorted out PCI IDs to remove megaraid support overlaps.
- Based on the patch from Daniel, sorted out PCI IDs along with
- charactor node name change from 'megadev' to 'megadev_legacy' to avoid
- conflict.
- ---
- Hopefully we'll be getting the build restriction zapped much sooner,
- but we should also be thinking about totally removing the hardware
- support overlap in the megaraid drivers.
-
- This patch pencils in a date of Feb 06 for this, and performs some
- printk abuse in hope that existing legacy users might pick up on what's
- going on.
-
- Signed-off-by: Daniel Drake
- ---
-
-2. Fixed a issue: megaraid always fails to reset handler.
- ---
- I found that the megaraid driver always fails to reset the
- adapter with the following message:
- megaraid: resetting the host...
- megaraid mbox: reset sequence completed successfully
- megaraid: fast sync command timed out
- megaraid: reservation reset failed
- when the "Cluster mode" of the adapter BIOS is enabled.
- So, whenever the reset occurs, the adapter goes to
- offline and just become unavailable.
-
- Jun'ichi Nomura [mailto:jnomura@mtc.biglobe.ne.jp]
- ---
-
Release Date : Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju
Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
Older Version : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)
diff --git a/trunk/Documentation/scsi/scsi_mid_low_api.txt b/trunk/Documentation/scsi/scsi_mid_low_api.txt
index 8bbae3e1abdf..66565d42288f 100644
--- a/trunk/Documentation/scsi/scsi_mid_low_api.txt
+++ b/trunk/Documentation/scsi/scsi_mid_low_api.txt
@@ -150,8 +150,7 @@ scsi devices of which only the first 2 respond:
LLD mid level LLD
===-------------------=========--------------------===------
scsi_host_alloc() -->
-scsi_add_host() ---->
-scsi_scan_host() -------+
+scsi_add_host() --------+
|
slave_alloc()
slave_configure() --> scsi_adjust_queue_depth()
@@ -197,7 +196,7 @@ of the issues involved. See the section on reference counting below.
The hotplug concept may be extended to SCSI devices. Currently, when an
-HBA is added, the scsi_scan_host() function causes a scan for SCSI devices
+HBA is added, the scsi_add_host() function causes a scan for SCSI devices
attached to the HBA's SCSI transport. On newer SCSI transports the HBA
may become aware of a new SCSI device _after_ the scan has completed.
An LLD can use this sequence to make the mid level aware of a SCSI device:
@@ -373,7 +372,7 @@ names all start with "scsi_".
Summary:
scsi_activate_tcq - turn on tag command queueing
scsi_add_device - creates new scsi device (lu) instance
- scsi_add_host - perform sysfs registration and set up transport class
+ scsi_add_host - perform sysfs registration and SCSI bus scan.
scsi_adjust_queue_depth - change the queue depth on a SCSI device
scsi_assign_lock - replace default host_lock with given lock
scsi_bios_ptable - return copy of block device's partition table
@@ -387,7 +386,6 @@ Summary:
scsi_remove_device - detach and remove a SCSI device
scsi_remove_host - detach and remove all SCSI devices owned by host
scsi_report_bus_reset - report scsi _bus_ reset observed
- scsi_scan_host - scan SCSI bus
scsi_track_queue_full - track successive QUEUE_FULL events
scsi_unblock_requests - allow further commands to be queued to given host
scsi_unregister - [calls scsi_host_put()]
@@ -427,10 +425,10 @@ void scsi_activate_tcq(struct scsi_device *sdev, int depth)
* Might block: yes
*
* Notes: This call is usually performed internally during a scsi
- * bus scan when an HBA is added (i.e. scsi_scan_host()). So it
+ * bus scan when an HBA is added (i.e. scsi_add_host()). So it
* should only be called if the HBA becomes aware of a new scsi
- * device (lu) after scsi_scan_host() has completed. If successful
- * this call can lead to slave_alloc() and slave_configure() callbacks
+ * device (lu) after scsi_add_host() has completed. If successful
+ * this call we lead to slave_alloc() and slave_configure() callbacks
* into the LLD.
*
* Defined in: drivers/scsi/scsi_scan.c
@@ -441,7 +439,7 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
/**
- * scsi_add_host - perform sysfs registration and set up transport class
+ * scsi_add_host - perform sysfs registration and SCSI bus scan.
* @shost: pointer to scsi host instance
* @dev: pointer to struct device of type scsi class
*
@@ -450,11 +448,7 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
* Might block: no
*
* Notes: Only required in "hotplug initialization model" after a
- * successful call to scsi_host_alloc(). This function does not
- * scan the bus; this can be done by calling scsi_scan_host() or
- * in some other transport-specific way. The LLD must set up
- * the transport template before calling this function and may only
- * access the transport class data after this function has been called.
+ * successful call to scsi_host_alloc().
*
* Defined in: drivers/scsi/hosts.c
**/
@@ -565,7 +559,7 @@ void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
* area for the LLD's exclusive use.
* Both associated refcounting objects have their refcount set to 1.
* Full registration (in sysfs) and a bus scan are performed later when
- * scsi_add_host() and scsi_scan_host() are called.
+ * scsi_add_host() is called.
*
* Defined in: drivers/scsi/hosts.c .
**/
@@ -704,19 +698,6 @@ int scsi_remove_host(struct Scsi_Host *shost)
void scsi_report_bus_reset(struct Scsi_Host * shost, int channel)
-/**
- * scsi_scan_host - scan SCSI bus
- * @shost: a pointer to a scsi host instance
- *
- * Might block: yes
- *
- * Notes: Should be called after scsi_add_host()
- *
- * Defined in: drivers/scsi/scsi_scan.c
- **/
-void scsi_scan_host(struct Scsi_Host *shost)
-
-
/**
* scsi_track_queue_full - track successive QUEUE_FULL events on given
* device to determine if and when there is a need
@@ -1452,7 +1433,7 @@ The following people have contributed to this document:
Christoph Hellwig
Doug Ledford
Andries Brouwer
- Randy Dunlap
+ Randy Dunlap
Alan Stern
diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt
index d2578013e829..2f27f391c7cc 100644
--- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -105,7 +105,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Each of top level sound card module takes the following options.
index - index (slot #) of sound card
- - Values: 0 through 31 or negative
+ - Values: 0 through 7 or negative
- If nonnegative, assign that index number
- if negative, interpret as a bitmask of permissible
indices; the first free permitted index is assigned
@@ -134,7 +134,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma2 - second DMA # for AD1816A chip (PnP setup)
clockfreq - Clock frequency for AD1816A chip (default = 0, 33000Hz)
- This module supports multiple cards, autoprobe and PnP.
+ Module supports up to 8 cards, autoprobe and PnP.
Module snd-ad1848
-----------------
@@ -145,11 +145,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
irq - IRQ # for AD1848 chip
dma1 - DMA # for AD1848 chip (0,1,3)
- This module supports multiple cards. It does not support autoprobe
+ Module supports up to 8 cards. This module does not support autoprobe
thus main port must be specified!!! Other ports are optional.
- The power-management is supported.
-
Module snd-ad1889
-----------------
@@ -158,7 +156,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ac97_quirk - AC'97 workaround for strange hardware
See the description of intel8x0 module for details.
- This module supports multiple cards.
+ This module supports up to 8 cards.
Module snd-ali5451
------------------
@@ -186,9 +184,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
mpu_irq - IRQ # for MPU-401 (PnP setup)
fm_port - port # for OPL3 FM (PnP setup)
- This module supports multiple cards, autoprobe and PnP.
-
- The power-management is supported.
+ Module supports up to 8 cards, autoprobe and PnP.
Module snd-als4000
------------------
@@ -198,9 +194,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
joystick_port - port # for legacy joystick support.
0 = disabled (default), 1 = auto-detect
- This module supports multiple cards, autoprobe and PnP.
-
- The power-management is supported.
+ Module supports up to 8 cards, autoprobe and PnP.
Module snd-atiixp
-----------------
@@ -219,8 +213,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
implementation depends on the motherboard, and you'll need to
choose the correct one via spdif_aclink module option.
- The power-management is supported.
-
Module snd-atiixp-modem
-----------------------
@@ -231,8 +223,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note: The default index value of this module is -2, i.e. the first
slot is excluded.
- The power-management is supported.
-
Module snd-au8810, snd-au8820, snd-au8830
-----------------------------------------
@@ -273,10 +263,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma1 - 1st DMA # for AZT2320 (WSS) chip (PnP setup)
dma2 - 2nd DMA # for AZT2320 (WSS) chip (PnP setup)
- This module supports multiple cards, PnP and autoprobe.
+ Module supports up to 8 cards, PnP and autoprobe.
- The power-management is supported.
-
Module snd-azt3328
------------------
@@ -284,7 +272,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
joystick - Enable joystick (default off)
- This module supports multiple cards.
+ Module supports up to 8 cards.
Module snd-bt87x
----------------
@@ -294,7 +282,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
digital_rate - Override the default digital rate (Hz)
load_all - Load the driver even if the card model isn't known
- This module supports multiple cards.
+ Module supports up to 8 cards.
Note: The default index value of this module is -2, i.e. the first
slot is excluded.
@@ -304,7 +292,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for Creative Audigy LS and SB Live 24bit
- This module supports multiple cards.
+ Module supports up to 8 cards.
Module snd-cmi8330
@@ -320,9 +308,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
sbdma8 - 8bit DMA # for CMI8330 chip (SB16)
sbdma16 - 16bit DMA # for CMI8330 chip (SB16)
- This module supports multiple cards and autoprobe.
-
- The power-management is supported.
+ Module supports up to 8 cards and autoprobe.
Module snd-cmipci
-----------------
@@ -335,10 +321,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
(default = 1)
joystick_port - Joystick port address (0 = disable, 1 = auto-detect)
- This module supports autoprobe and multiple cards.
+ Module supports autoprobe and multiple chips (max 8).
- The power-management is supported.
-
Module snd-cs4231
-----------------
@@ -351,7 +335,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma1 - first DMA # for CS4231 chip
dma2 - second DMA # for CS4231 chip
- This module supports multiple cards. This module does not support autoprobe
+ Module supports up to 8 cards. This module does not support autoprobe
thus main port must be specified!!! Other ports are optional.
The power-management is supported.
@@ -371,7 +355,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma2 - second DMA # for Yamaha CS4232 chip (0,1,3), -1 = disable
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
- This module supports multiple cards. This module does not support autoprobe
+ Module supports up to 8 cards. This module does not support autoprobe
thus main port must be specified!!! Other ports are optional.
The power-management is supported.
@@ -392,7 +376,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma2 - second DMA # for CS4236 chip (0,1,3), -1 = disable
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
- This module supports multiple cards. This module does not support autoprobe
+ Module supports up to 8 cards. This module does not support autoprobe
(if ISA PnP is not used) thus main port and control port must be
specified!!! Other ports are optional.
@@ -405,7 +389,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dual_codec - Secondary codec ID (0 = disable, default)
- This module supports multiple cards.
+ Module supports up to 8 cards.
The power-management is supported.
@@ -419,20 +403,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
thinkpad - Force to enable Thinkpad's CLKRUN control.
mmap_valid - Support OSS mmap mode (default = 0).
- This module supports multiple cards and autoprobe.
+ Module supports up to 8 cards and autoprobe.
Usually external amp and CLKRUN controls are detected automatically
from PCI sub vendor/device ids. If they don't work, give the options
above explicitly.
The power-management is supported.
- Module snd-cs5535audio
- ----------------------
-
- Module for multifunction CS5535 companion PCI device
-
- This module supports multiple cards.
-
Module snd-dt019x
-----------------
@@ -446,11 +423,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
mpu_irq - IRQ # for MPU-401 (PnP setup)
dma8 - DMA # (PnP setup)
- This module supports multiple cards. This module is enabled only with
+ Module supports up to 8 cards. This module is enabled only with
ISA PnP support.
- The power-management is supported.
-
Module snd-dummy
----------------
@@ -458,8 +433,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
or input, but you may use this module for any application which
requires a sound card (like RealPlayer).
- The power-management is supported.
-
Module snd-emu10k1
------------------
@@ -477,7 +450,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
given in MB unit. Default value is 128.
enable_ir - enable IR
- This module supports multiple cards and autoprobe.
+ Module supports up to 8 cards and autoprobe.
Input & Output configurations [extin/extout]
* Creative Card wo/Digital out [0x0003/0x1f03]
@@ -493,14 +466,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
* Creative Card 5.1 (c) 2003 [0x3fc3/0x7cff]
* Creative Card all ins and outs [0x3fff/0x7fff]
- The power-management is supported.
-
Module snd-emu10k1x
-------------------
Module for Creative Emu10k1X (SB Live Dell OEM version)
- This module supports multiple cards.
+ Module supports up to 8 cards.
Module snd-ens1370
------------------
@@ -511,7 +482,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
joystick - Enable joystick (default off)
- This module supports multiple cards and autoprobe.
+ Module supports up to 8 cards and autoprobe.
Module snd-ens1371
------------------
@@ -524,7 +495,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
joystick_port - port # for joystick (0x200,0x208,0x210,0x218),
0 = disable (default), 1 = auto-detect
- This module supports multiple cards and autoprobe.
+ Module supports up to 8 cards and autoprobe.
Module snd-es968
----------------
@@ -535,10 +506,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
irq - IRQ # for ES968 (SB8) chip (PnP setup)
dma1 - DMA # for ES968 (SB8) chip (PnP setup)
- This module supports multiple cards, PnP and autoprobe.
+ Module supports up to 8 cards, PnP and autoprobe.
- The power-management is supported.
-
Module snd-es1688
-----------------
@@ -550,7 +519,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
mpu_irq - IRQ # for MPU-401 port (5,7,9,10)
dma8 - DMA # for ES-1688 chip (0,1,3)
- This module supports multiple cards and autoprobe (without MPU-401 port).
+ Module supports up to 8 cards and autoprobe (without MPU-401 port).
Module snd-es18xx
-----------------
@@ -565,8 +534,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma2 - first DMA # for ES-18xx chip (0,1,3)
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
- This module supports multiple cards, ISA PnP and autoprobe (without MPU-401
- port if native ISA PnP routines are not used).
+ Module supports up to 8 cards ISA PnP and autoprobe (without MPU-401 port
+ if native ISA PnP routines are not used).
When dma2 is equal with dma1, the driver works as half-duplex.
The power-management is supported.
@@ -576,9 +545,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for sound cards based on ESS Solo-1 (ES1938,ES1946) chips.
- This module supports multiple cards and autoprobe.
-
- The power-management is supported.
+ Module supports up to 8 cards and autoprobe.
Module snd-es1968
-----------------
@@ -594,7 +561,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
enable_mpu - enable MPU401 (0 = off, 1 = on, 2 = auto (default))
joystick - enable joystick (default off)
- This module supports multiple cards and autoprobe.
+ Module supports up to 8 cards and autoprobe.
The power-management is supported.
@@ -610,10 +577,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
- High 16-bits are video (radio) device number + 1
- example: 0x10002 (MediaForte 256-PCPR, device 1)
- This module supports multiple cards and autoprobe.
+ Module supports up to 8 cards and autoprobe.
- The power-management is supported.
-
Module snd-gusclassic
---------------------
@@ -627,7 +592,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
voices - GF1 voices limit (14-32)
pcm_voices - reserved PCM voices
- This module supports multiple cards and autoprobe.
+ Module supports up to 8 cards and autoprobe.
Module snd-gusextreme
---------------------
@@ -646,7 +611,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
voices - GF1 voices limit (14-32)
pcm_voices - reserved PCM voices
- This module supports multiple cards and autoprobe (without MPU-401 port).
+ Module supports up to 8 cards and autoprobe (without MPU-401 port).
Module snd-gusmax
-----------------
@@ -661,7 +626,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
voices - GF1 voices limit (14-32)
pcm_voices - reserved PCM voices
- This module supports multiple cards and autoprobe.
+ Module supports up to 8 cards and autoprobe.
Module snd-hda-intel
--------------------
@@ -723,14 +688,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
(Usually SD_LPLIB register is more accurate than the
position buffer.)
- The power-management is supported.
-
Module snd-hdsp
---------------
Module for RME Hammerfall DSP audio interface(s)
- This module supports multiple cards.
+ Module supports up to 8 cards.
Note: The firmware data can be automatically loaded via hotplug
when CONFIG_FW_LOADER is set. Otherwise, you need to load
@@ -788,7 +751,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever)
in msec resolution, default value is 500 (0.5 sec)
- This module supports multiple cards and autoprobe. Note: The consumer part
+ Module supports up to 8 cards and autoprobe. Note: The consumer part
is not used with all Envy24 based cards (for example in the MidiMan Delta
serie).
@@ -824,7 +787,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
aureon71, universe, k8x800, phase22, phase28, ms300,
av710
- This module supports multiple cards and autoprobe.
+ Module supports up to 8 cards and autoprobe.
Note: The supported board is detected by reading EEPROM or PCI
SSID (if EEPROM isn't available). You can override the
@@ -876,8 +839,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note: The default index value of this module is -2, i.e. the first
slot is excluded.
- The power-management is supported.
-
Module snd-interwave
--------------------
@@ -894,7 +855,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
effect - 1 = InterWave effects enable (default 0);
requires 8 voices
- This module supports multiple cards, autoprobe and ISA PnP.
+ Module supports up to 8 cards, autoprobe and ISA PnP.
Module snd-interwave-stb
------------------------
@@ -914,14 +875,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
effect - 1 = InterWave effects enable (default 0);
requires 8 voices
- This module supports multiple cards, autoprobe and ISA PnP.
+ Module supports up to 8 cards, autoprobe and ISA PnP.
Module snd-korg1212
-------------------
Module for Korg 1212 IO PCI card
- This module supports multiple cards.
+ Module supports up to 8 cards.
Module snd-maestro3
-------------------
@@ -933,7 +894,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
-1 for default pin (8 for allegro, 1 for
others)
- This module supports autoprobe and multiple chips.
+ Module supports autoprobe and multiple chips (max 8).
Note: the binding of amplifier is dependent on hardware.
If there is no sound even though all channels are unmuted, try to
@@ -948,7 +909,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for Digigram miXart8 sound cards.
- This module supports multiple cards.
+ Module supports multiple cards.
Note: One miXart8 board will be represented as 4 alsa cards.
See MIXART.txt for details.
@@ -967,7 +928,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
irq - IRQ number or -1 (disable)
pnp - PnP detection - 0 = disable, 1 = enable (default)
- This module supports multiple devices and PnP.
+ Module supports multiple devices (max 8) and PnP.
Module snd-mtpav
----------------
@@ -1053,7 +1014,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma2 - second DMA # for Yamaha OPL3-SA chip (0,1,3), -1 = disable
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
- This module supports multiple cards and ISA PnP. It does not support
+ Module supports up to 8 cards and ISA PnP. This module does not support
autoprobe (if ISA PnP is not used) thus all ports must be specified!!!
The power-management is supported.
@@ -1103,13 +1064,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
This module supports only one card, autoprobe and PnP.
- Module snd-pcxhr
- ----------------
-
- Module for Digigram PCXHR boards
-
- This module supports multiple cards.
-
Module snd-powermac (on ppc only)
---------------------------------
@@ -1130,22 +1084,20 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
For ARM architecture only.
- The power-management is supported.
-
Module snd-rme32
----------------
Module for RME Digi32, Digi32 Pro and Digi32/8 (Sek'd Prodif32,
Prodif96 and Prodif Gold) sound cards.
- This module supports multiple cards.
+ Module supports up to 8 cards.
Module snd-rme96
----------------
Module for RME Digi96, Digi96/8 and Digi96/8 PRO/PAD/PST sound cards.
- This module supports multiple cards.
+ Module supports up to 8 cards.
Module snd-rme9652
------------------
@@ -1155,7 +1107,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
precise_ptr - Enable precise pointer (doesn't work reliably).
(default = 0)
- This module supports multiple cards.
+ Module supports up to 8 cards.
Note: snd-page-alloc module does the job which snd-hammerfall-mem
module did formerly. It will allocate the buffers in advance
@@ -1172,8 +1124,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module supports only one card.
Module has no enable and index options.
- The power-management is supported.
-
Module snd-sb8
--------------
@@ -1185,10 +1135,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
irq - IRQ # for SB DSP chip (5,7,9,10)
dma8 - DMA # for SB DSP chip (1,3)
- This module supports multiple cards and autoprobe.
+ Module supports up to 8 cards and autoprobe.
- The power-management is supported.
-
Module snd-sb16 and snd-sbawe
-----------------------------
@@ -1207,7 +1155,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
csp - ASP/CSP chip support - 0 = disable (default), 1 = enable
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
- This module supports multiple cards, autoprobe and ISA PnP.
+ Module supports up to 8 cards, autoprobe and ISA PnP.
Note: To use Vibra16X cards in 16-bit half duplex mode, you must
disable 16bit DMA with dma16 = -1 module parameter.
@@ -1215,8 +1163,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
half duplex mode through 8-bit DMA channel by disabling their
16-bit DMA channel.
- The power-management is supported.
-
Module snd-sgalaxy
------------------
@@ -1227,9 +1173,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
irq - IRQ # (7,9,10,11)
dma1 - DMA #
- This module supports multiple cards.
-
- The power-management is supported.
+ Module supports up to 8 cards.
Module snd-sscape
-----------------
@@ -1241,7 +1185,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
mpu_irq - MPU-401 IRQ # (PnP setup)
dma - DMA # (PnP setup)
- This module supports multiple cards. ISA PnP must be enabled.
+ Module supports up to 8 cards. ISA PnP must be enabled.
You need sscape_ctl tool in alsa-tools package for loading
the microcode.
@@ -1250,21 +1194,21 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for AMD7930 sound chips found on Sparcs.
- This module supports multiple cards.
+ Module supports up to 8 cards.
Module snd-sun-cs4231 (on sparc only)
-------------------------------------
Module for CS4231 sound chips found on Sparcs.
- This module supports multiple cards.
+ Module supports up to 8 cards.
Module snd-sun-dbri (on sparc only)
-----------------------------------
Module for DBRI sound chips found on Sparcs.
- This module supports multiple cards.
+ Module supports up to 8 cards.
Module snd-wavefront
--------------------
@@ -1284,7 +1228,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma2 - DMA2 # for CS4232 PCM interface.
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
- This module supports multiple cards and ISA PnP.
+ Module supports up to 8 cards and ISA PnP.
Module snd-sonicvibes
---------------------
@@ -1296,7 +1240,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
- SoundCard must have onboard SRAM for this.
mge - Mic Gain Enable - 1 = enable, 0 = disable (default)
- This module supports multiple cards and autoprobe.
+ Module supports up to 8 cards and autoprobe.
Module snd-serial-u16550
------------------------
@@ -1315,7 +1259,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
0 = Soundcanvas, 1 = MS-124T, 2 = MS-124W S/A,
3 = MS-124W M/B, 4 = Generic
- This module supports multiple cards. This module does not support autoprobe
+ Module supports up to 8 cards. This module does not support autoprobe
thus the main port must be specified!!! Other options are optional.
Module snd-trident
@@ -1334,7 +1278,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
pcm_channels - max channels (voices) reserved for PCM
wavetable_size - max wavetable size in kB (4-?kb)
- This module supports multiple cards and autoprobe.
+ Module supports up to 8 cards and autoprobe.
The power-management is supported.
@@ -1346,14 +1290,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
vid - Vendor ID for the device (optional)
pid - Product ID for the device (optional)
- This module supports multiple devices, autoprobe and hotplugging.
+ This module supports up to 8 cards, autoprobe and hotplugging.
Module snd-usb-usx2y
--------------------
Module for Tascam USB US-122, US-224 and US-428 devices.
- This module supports multiple devices, autoprobe and hotplugging.
+ This module supports up to 8 cards, autoprobe and hotplugging.
Note: you need to load the firmware via usx2yloader utility included
in alsa-tools and alsa-firmware packages.
@@ -1412,8 +1356,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note: for the MPU401 on VIA823x, use snd-mpu401 driver
additionally. The mpu_port option is for VIA686 chips only.
- The power-management is supported.
-
Module snd-via82xx-modem
------------------------
@@ -1426,8 +1368,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note: The default index value of this module is -2, i.e. the first
slot is excluded.
- The power-management is supported.
-
Module snd-virmidi
------------------
@@ -1435,9 +1375,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
This module creates virtual rawmidi devices which communicate
to the corresponding ALSA sequencer ports.
- midi_devs - MIDI devices # (1-4, default=4)
+ midi_devs - MIDI devices # (1-8, default=4)
- This module supports multiple cards.
+ Module supports up to 8 cards.
Module snd-vx222
----------------
@@ -1447,7 +1387,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
mic - Enable Microphone on V222 Mic (NYI)
ibl - Capture IBL size. (default = 0, minimum size)
- This module supports multiple cards.
+ Module supports up to 8 cards.
When the driver is compiled as a module and the hotplug firmware
is supported, the firmware data is loaded via hotplug automatically.
@@ -1466,8 +1406,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
size is chosen. The possible IBL values can be found in
/proc/asound/cardX/vx-status proc file.
- The power-management is supported.
-
Module snd-vxpocket
-------------------
@@ -1475,7 +1413,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ibl - Capture IBL size. (default = 0, minimum size)
- This module supports multiple cards. The module is compiled only when
+ Module supports up to 8 cards. The module is compiled only when
PCMCIA is supported on kernel.
With the older 2.6.x kernel, to activate the driver via the card
@@ -1496,8 +1434,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note2: snd-vxp440 driver is merged to snd-vxpocket driver since
ALSA 1.0.10.
- The power-management is supported.
-
Module snd-ymfpci
-----------------
@@ -1511,7 +1447,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1 (auto-detect)
rear_switch - enable shared rear/line-in switch (bool)
- This module supports autoprobe and multiple chips.
+ Module supports autoprobe and multiple chips (max 8).
The power-management is supported.
@@ -1522,8 +1458,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note: the driver is build only when CONFIG_ISA is set.
- The power-management is supported.
-
AC97 Quirk Option
=================
@@ -1540,7 +1474,7 @@ the proper value with this option.
The following strings are accepted:
- default Don't override the default setting
- - none Disable the quirk
+ - disable Disable the quirk
- hp_only Bind Master and Headphone controls as a single control
- swap_hp Swap headphone and master controls
- swap_surround Swap master and surround controls
diff --git a/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 4963d83d1511..260334c98d95 100644
--- a/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -18,8 +18,8 @@
- November 17, 2005
- 0.3.6
+ October 6, 2005
+ 0.3.5
@@ -403,8 +403,9 @@
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
/* definition of the chip-specific record */
- struct mychip {
- struct snd_card *card;
+ typedef struct snd_mychip mychip_t;
+ struct snd_mychip {
+ snd_card_t *card;
// rest of implementation will be in the section
// "PCI Resource Managements"
};
@@ -412,7 +413,7 @@
/* chip-specific destructor
* (see "PCI Resource Managements")
*/
- static int snd_mychip_free(struct mychip *chip)
+ static int snd_mychip_free(mychip_t *chip)
{
.... // will be implemented later...
}
@@ -420,21 +421,22 @@
/* component-destructor
* (see "Management of Cards and Components")
*/
- static int snd_mychip_dev_free(struct snd_device *device)
+ static int snd_mychip_dev_free(snd_device_t *device)
{
- return snd_mychip_free(device->device_data);
+ mychip_t *chip = device->device_data;
+ return snd_mychip_free(chip);
}
/* chip-specific constructor
* (see "Management of Cards and Components")
*/
- static int __devinit snd_mychip_create(struct snd_card *card,
+ static int __devinit snd_mychip_create(snd_card_t *card,
struct pci_dev *pci,
- struct mychip **rchip)
+ mychip_t **rchip)
{
- struct mychip *chip;
+ mychip_t *chip;
int err;
- static struct snd_device_ops ops = {
+ static snd_device_ops_t ops = {
.dev_free = snd_mychip_dev_free,
};
@@ -472,8 +474,8 @@
const struct pci_device_id *pci_id)
{
static int dev;
- struct snd_card *card;
- struct mychip *chip;
+ snd_card_t *card;
+ mychip_t *chip;
int err;
/* (1) */
@@ -580,7 +582,7 @@
@@ -603,7 +605,7 @@
@@ -828,7 +830,7 @@
After the card is created, you can attach the components
(devices) to the card instance. On ALSA driver, a component is
- represented as a struct snd_device object.
+ represented as a snd_device_t object.
A component can be a PCM instance, a control interface, a raw
MIDI interface, etc. Each of such instances has one component
entry.
@@ -889,11 +891,14 @@
The chip-specific information, e.g. the i/o port address, its
resource pointer, or the irq number, is stored in the
chip-specific record.
+ Usually, the chip-specific record is typedef'ed as
+ xxx_t like the following:
@@ -913,12 +918,12 @@
- whether struct mychip is the type of the chip record.
+ whether mychip_t is the type of the chip record.
@@ -927,7 +932,7 @@
private_data;
+ mychip_t *chip = (mychip_t *)card->private_data;
]]>
@@ -949,8 +954,8 @@
@@ -995,7 +1000,7 @@
device_data);
+ mychip_t *chip = device->device_data;
+ return snd_mychip_free(chip);
}
]]>
@@ -1081,15 +1087,15 @@
PCI Resource Managements Example
port = pci_resource_start(pci, 0);
if (request_irq(pci->irq, snd_mychip_interrupt,
- SA_INTERRUPT|SA_SHIRQ, "My Chip", chip)) {
+ SA_INTERRUPT|SA_SHIRQ, "My Chip",
+ (void *)chip)) {
printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
snd_mychip_free(chip);
return -EBUSY;
@@ -1261,14 +1268,14 @@
Now assume that this PCI device has an I/O port with 8 bytes
- and an interrupt. Then struct mychip will have the
+ and an interrupt. Then mychip_t will have the
following fields:
irq, snd_mychip_interrupt,
- SA_INTERRUPT|SA_SHIRQ, "My Chip", chip)) {
+ SA_INTERRUPT|SA_SHIRQ, "My Chip",
+ (void *)chip)) {
printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
snd_mychip_free(chip);
return -EBUSY;
@@ -1364,7 +1372,7 @@
static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
{
- struct mychip *chip = dev_id;
+ mychip_t *chip = dev_id;
....
return IRQ_HANDLED;
}
@@ -1479,7 +1487,7 @@
iobase_virt)
@@ -1529,7 +1537,7 @@
Registration of Device Struct
At some point, typically after calling snd_device_new(),
- you need to register the struct device of the chip
+ you need to register the struct device of the chip
you're handling for udev and co. ALSA provides a macro for compatibility with
older kernels. Simply call like the following:
@@ -1731,7 +1739,7 @@
....
/* hardware definition */
- static struct snd_pcm_hardware snd_mychip_playback_hw = {
+ static snd_pcm_hardware_t snd_mychip_playback_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1750,7 +1758,7 @@
};
/* hardware definition */
- static struct snd_pcm_hardware snd_mychip_capture_hw = {
+ static snd_pcm_hardware_t snd_mychip_capture_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1769,10 +1777,10 @@
};
/* open callback */
- static int snd_mychip_playback_open(struct snd_pcm_substream *substream)
+ static int snd_mychip_playback_open(snd_pcm_substream_t *substream)
{
- struct mychip *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
+ mychip_t *chip = snd_pcm_substream_chip(substream);
+ snd_pcm_runtime_t *runtime = substream->runtime;
runtime->hw = snd_mychip_playback_hw;
// more hardware-initialization will be done here
@@ -1780,19 +1788,19 @@
}
/* close callback */
- static int snd_mychip_playback_close(struct snd_pcm_substream *substream)
+ static int snd_mychip_playback_close(snd_pcm_substream_t *substream)
{
- struct mychip *chip = snd_pcm_substream_chip(substream);
+ mychip_t *chip = snd_pcm_substream_chip(substream);
// the hardware-specific codes will be here
return 0;
}
/* open callback */
- static int snd_mychip_capture_open(struct snd_pcm_substream *substream)
+ static int snd_mychip_capture_open(snd_pcm_substream_t *substream)
{
- struct mychip *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
+ mychip_t *chip = snd_pcm_substream_chip(substream);
+ snd_pcm_runtime_t *runtime = substream->runtime;
runtime->hw = snd_mychip_capture_hw;
// more hardware-initialization will be done here
@@ -1800,33 +1808,33 @@
}
/* close callback */
- static int snd_mychip_capture_close(struct snd_pcm_substream *substream)
+ static int snd_mychip_capture_close(snd_pcm_substream_t *substream)
{
- struct mychip *chip = snd_pcm_substream_chip(substream);
+ mychip_t *chip = snd_pcm_substream_chip(substream);
// the hardware-specific codes will be here
return 0;
}
/* hw_params callback */
- static int snd_mychip_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
+ static int snd_mychip_pcm_hw_params(snd_pcm_substream_t *substream,
+ snd_pcm_hw_params_t * hw_params)
{
return snd_pcm_lib_malloc_pages(substream,
params_buffer_bytes(hw_params));
}
/* hw_free callback */
- static int snd_mychip_pcm_hw_free(struct snd_pcm_substream *substream)
+ static int snd_mychip_pcm_hw_free(snd_pcm_substream_t *substream)
{
return snd_pcm_lib_free_pages(substream);
}
/* prepare callback */
- static int snd_mychip_pcm_prepare(struct snd_pcm_substream *substream)
+ static int snd_mychip_pcm_prepare(snd_pcm_substream_t *substream)
{
- struct mychip *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
+ mychip_t *chip = snd_pcm_substream_chip(substream);
+ snd_pcm_runtime_t *runtime = substream->runtime;
/* set up the hardware with the current configuration
* for example...
@@ -1841,7 +1849,7 @@
}
/* trigger callback */
- static int snd_mychip_pcm_trigger(struct snd_pcm_substream *substream,
+ static int snd_mychip_pcm_trigger(snd_pcm_substream_t *substream,
int cmd)
{
switch (cmd) {
@@ -1858,9 +1866,9 @@
/* pointer callback */
static snd_pcm_uframes_t
- snd_mychip_pcm_pointer(struct snd_pcm_substream *substream)
+ snd_mychip_pcm_pointer(snd_pcm_substream_t *substream)
{
- struct mychip *chip = snd_pcm_substream_chip(substream);
+ mychip_t *chip = snd_pcm_substream_chip(substream);
unsigned int current_ptr;
/* get the current hardware pointer */
@@ -1869,7 +1877,7 @@
}
/* operators */
- static struct snd_pcm_ops snd_mychip_playback_ops = {
+ static snd_pcm_ops_t snd_mychip_playback_ops = {
.open = snd_mychip_playback_open,
.close = snd_mychip_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1881,7 +1889,7 @@
};
/* operators */
- static struct snd_pcm_ops snd_mychip_capture_ops = {
+ static snd_pcm_ops_t snd_mychip_capture_ops = {
.open = snd_mychip_capture_open,
.close = snd_mychip_capture_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1897,9 +1905,9 @@
*/
/* create a pcm device */
- static int __devinit snd_mychip_new_pcm(struct mychip *chip)
+ static int __devinit snd_mychip_new_pcm(mychip_t *chip)
{
- struct snd_pcm *pcm;
+ snd_pcm_t *pcm;
int err;
if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1,
@@ -1936,9 +1944,9 @@
card, "My Chip", 0, 1, 1,
@@ -1981,13 +1989,13 @@
specify more numbers, but they must be handled properly in
open/close, etc. callbacks. When you need to know which
substream you are referring to, then it can be obtained from
- struct snd_pcm_substream data passed to each callback
+ snd_pcm_substream_t data passed to each callback
as follows:
number;
]]>
@@ -2016,7 +2024,7 @@
PCM Instance with a Destructor
my_private_pcm_data);
// do what you like else
....
}
- static int __devinit snd_mychip_new_pcm(struct mychip *chip)
+ static int __devinit snd_mychip_new_pcm(mychip_t *chip)
{
- struct snd_pcm *pcm;
+ snd_pcm_t *pcm;
....
/* allocate your own data */
chip->my_private_pcm_data = kmalloc(...);
@@ -2141,7 +2149,7 @@
@@ -2244,7 +2252,7 @@ struct _snd_pcm_runtime {
Hardware Description
- The hardware descriptor (struct snd_pcm_hardware)
+ The hardware descriptor (snd_pcm_hardware_t)
contains the definitions of the fundamental hardware
configuration. Above all, you'll need to define this in
@@ -2259,7 +2267,7 @@ struct _snd_pcm_runtime {
runtime;
+ snd_pcm_runtime_t *runtime = substream->runtime;
...
runtime->hw = snd_mychip_playback_hw; /* common definition */
if (chip->model == VERY_OLD_ONE)
@@ -2274,7 +2282,7 @@ struct _snd_pcm_runtime {
PAUSE bit means that the pcm supports the
pause
operation, while the
RESUME bit means that the pcm supports
- the full suspend/resume
operation.
- If PAUSE flag is set,
- the trigger callback below
- must handle the corresponding (pause push/release) commands.
- The suspend/resume trigger commands can be defined even without
- RESUME flag. See
- Power Management section for details.
+ the suspend/resume
operation. If these flags
+ are set, the trigger callback below
+ must handle the corresponding commands.
@@ -2509,7 +2512,7 @@ struct _snd_pcm_runtime {
Running Status
The running status can be referred via runtime->status.
- This is the pointer to struct snd_pcm_mmap_status
+ This is the pointer to snd_pcm_mmap_status_t
record. For example, you can get the current DMA hardware
pointer via runtime->status->hw_ptr.
@@ -2517,7 +2520,7 @@ struct _snd_pcm_runtime {
The DMA application pointer can be referred via
runtime->control, which points
- struct snd_pcm_mmap_control record.
+ snd_pcm_mmap_control_t record.
However, accessing directly to this value is not recommended.
@@ -2539,9 +2542,9 @@ struct _snd_pcm_runtime {
runtime->private_data = data;
@@ -2583,7 +2586,7 @@ struct _snd_pcm_runtime {
The callback function takes at least the argument with
- snd_pcm_substream pointer. For retrieving the
+ snd_pcm_substream_t pointer. For retrieving the
chip record from the given substream instance, you can use the
following macro.
@@ -2591,7 +2594,7 @@ struct _snd_pcm_runtime {
@@ -2613,7 +2616,7 @@ struct _snd_pcm_runtime {
@@ -2628,10 +2631,10 @@ struct _snd_pcm_runtime {
runtime;
+ mychip_t *chip = snd_pcm_substream_chip(substream);
+ snd_pcm_runtime_t *runtime = substream->runtime;
runtime->hw = snd_mychip_playback_hw;
return 0;
@@ -2664,7 +2667,7 @@ struct _snd_pcm_runtime {
@@ -2679,7 +2682,7 @@ struct _snd_pcm_runtime {
runtime->private_data);
@@ -2706,8 +2709,8 @@ struct _snd_pcm_runtime {
@@ -2782,7 +2785,7 @@ struct _snd_pcm_runtime {
@@ -2817,7 +2820,7 @@ struct _snd_pcm_runtime {
@@ -2866,7 +2869,7 @@ struct _snd_pcm_runtime {
@@ -2908,8 +2911,8 @@ struct _snd_pcm_runtime {
- When the pcm supports the suspend/resume operation,
- regardless of full or partial suspend/resume support,
+ When the pcm supports the suspend/resume operation
+ (i.e. SNDRV_PCM_INFO_RESUME flag is set),
SUSPEND and RESUME
commands must be handled, too.
These commands are issued when the power-management status is
@@ -2918,8 +2921,6 @@ struct _snd_pcm_runtime {
do suspend and resume of the pcm substream, and usually, they
are identical with STOP and
START commands, respectively.
- See
- Power Management section for details.
@@ -2938,7 +2939,7 @@ struct _snd_pcm_runtime {
@@ -3066,7 +3067,7 @@ struct _snd_pcm_runtime {
static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
{
- struct mychip *chip = dev_id;
+ mychip_t *chip = dev_id;
spin_lock(&chip->lock);
....
if (pcm_irq_invoked(chip)) {
@@ -3110,7 +3111,7 @@ struct _snd_pcm_runtime {
static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
{
- struct mychip *chip = dev_id;
+ mychip_t *chip = dev_id;
spin_lock(&chip->lock);
....
if (pcm_irq_invoked(chip)) {
@@ -3220,13 +3221,13 @@ struct _snd_pcm_runtime {
snd_pcm_hardware stucture (or in any
+ specified in the snd_pcm_hardware_t stucture (or in any
other constraint_list). You can build a rule like this:
Example of Hardware Constraints for Channels
min < 2) {
@@ -3298,13 +3298,12 @@ struct _snd_pcm_runtime {
Example of Hardware Constraints for Channels
bits[0] == SNDRV_PCM_FMTBIT_S16_LE) {
@@ -3377,13 +3376,13 @@ struct _snd_pcm_runtime {
callbacks: info,
get and
put. Then, define a
- struct snd_kcontrol_new record, such as:
+ snd_kcontrol_new_t record, such as:
Definition of a Control
The info callback is used to get
the detailed information of this control. This must store the
- values of the given struct snd_ctl_elem_info
+ values of the given snd_ctl_elem_info_t
object. For example, for a boolean control with a single
element will be:
@@ -3608,8 +3607,8 @@ struct _snd_pcm_runtime {
Example of info callback
type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = 1;
@@ -3643,8 +3642,8 @@ struct _snd_pcm_runtime {
Example of get callback
value.integer.value[0] = get_some_value(chip);
return 0;
}
@@ -3718,8 +3717,8 @@ struct _snd_pcm_runtime {
private_value & 0xff;
int shift = (kcontrol->private_value >> 16) & 0xff;
@@ -3755,10 +3754,10 @@ struct _snd_pcm_runtime {
Example of put callback
current_value !=
ucontrol->value.integer.value[0]) {
@@ -3815,7 +3814,7 @@ struct _snd_pcm_runtime {
where my_control is the
- struct snd_kcontrol_new object defined above, and chip
+ snd_kcontrol_new_t object defined above, and chip
is the object pointer to be passed to
kcontrol->private_data
which can be referred in callbacks.
@@ -3823,7 +3822,7 @@ struct _snd_pcm_runtime {
snd_ctl_new1() allocates a new
- snd_kcontrol instance (that's why the definition
+ snd_kcontrol_t instance (that's why the definition
of my_control can be with
__devinitdata
prefix), and snd_ctl_add assigns the given
@@ -3850,7 +3849,7 @@ struct _snd_pcm_runtime {
control id pointer for the notification. The event-mask
specifies the types of notification, for example, in the above
example, the change of control values is notified.
- The id pointer is the pointer of struct snd_ctl_elem_id
+ The id pointer is the pointer of snd_ctl_elem_id_t
to be notified.
You can find some examples in es1938.c or
es1968.c for hardware volume interrupts.
@@ -3883,35 +3882,35 @@ struct _snd_pcm_runtime {
Example of AC97 Interface
private_data;
+ mychip_t *chip = ac97->private_data;
....
// read a register value here from the codec
return the_register_value;
}
- static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
+ static void snd_mychip_ac97_write(ac97_t *ac97,
unsigned short reg, unsigned short val)
{
- struct mychip *chip = ac97->private_data;
+ mychip_t *chip = ac97->private_data;
....
// write the given register value to the codec
}
- static int snd_mychip_ac97(struct mychip *chip)
+ static int snd_mychip_ac97(mychip_t *chip)
{
- struct snd_ac97_bus *bus;
- struct snd_ac97_template ac97;
+ ac97_bus_t *bus;
+ ac97_template_t ac97;
int err;
- static struct snd_ac97_bus_ops ops = {
+ static ac97_bus_ops_t ops = {
.write = snd_mychip_ac97_write,
.read = snd_mychip_ac97_read,
};
@@ -3938,8 +3937,8 @@ struct _snd_pcm_runtime {
- And then call snd_ac97_mixer() with an
- struct snd_ac97_template
+ And then call snd_ac97_mixer() with an ac97_template_t
record together with the bus pointer created above.
private_data;
+ mychip_t *chip = ac97->private_data;
....
return the_register_value;
}
@@ -4018,7 +4016,7 @@ struct _snd_pcm_runtime {
@@ -4165,7 +4163,7 @@ struct _snd_pcm_runtime {
Multiple Codecs
When there are several codecs on the same card, you need to
- call snd_ac97_mixer() multiple times with
+ call snd_ac97_new() multiple times with
ac97.num=1 or greater. The num field
specifies the codec
number.
@@ -4214,7 +4212,7 @@ struct _snd_pcm_runtime {
@@ -4255,17 +4253,17 @@ struct _snd_pcm_runtime {
Usually, the port address corresponds to the command port and
port + 1 corresponds to the data port. If not, you may change
the cport field of
- struct snd_mpu401 manually
- afterward. However, snd_mpu401 pointer is not
+ mpu401_t manually
+ afterward. However, mpu401_t pointer is not
returned explicitly by
snd_mpu401_uart_new(). You need to cast
rmidi->private_data to
- snd_mpu401 explicitly,
+ mpu401_t explicitly,
private_data;
]]>
@@ -4361,7 +4359,7 @@ struct _snd_pcm_runtime {
card, "MyMIDI", 0, outs, ins, &rmidi);
if (err < 0)
return err;
@@ -4421,7 +4419,7 @@ struct _snd_pcm_runtime {
streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
- substream = list_entry(list, struct snd_rawmidi_substream, list);
+ substream = list_entry(list, snd_rawmidi_substream_t, list);
sprintf(substream->name, "My MIDI Port %d", substream->number + 1);
}
/* same for SNDRV_RAWMIDI_STREAM_INPUT */
@@ -4465,12 +4463,12 @@ struct _snd_pcm_runtime {
If there is more than one port, your callbacks can determine the
- port index from the struct snd_rawmidi_substream data passed to each
+ port index from the snd_rawmidi_substream_t data passed to each
callback:
number;
]]>
@@ -4483,7 +4481,7 @@ struct _snd_pcm_runtime {
@@ -4501,7 +4499,7 @@ struct _snd_pcm_runtime {
@@ -4524,7 +4522,7 @@ struct _snd_pcm_runtime {
@@ -4549,7 +4547,7 @@ struct _snd_pcm_runtime {
@@ -4605,7 +4603,7 @@ struct _snd_pcm_runtime {
@@ -4649,7 +4647,7 @@ struct _snd_pcm_runtime {
@@ -4663,7 +4661,7 @@ struct _snd_pcm_runtime {
This callback is optional. If you do not set
- drain in the struct snd_rawmidi_ops
+ drain in the snd_rawmidi_ops_t
structure, ALSA will simply wait for 50 milliseconds
instead.
@@ -4705,7 +4703,7 @@ struct _snd_pcm_runtime {
@@ -4738,7 +4736,7 @@ struct _snd_pcm_runtime {
@@ -4769,7 +4767,7 @@ struct _snd_pcm_runtime {
@@ -4806,7 +4804,7 @@ struct _snd_pcm_runtime {
@@ -4825,7 +4823,7 @@ struct _snd_pcm_runtime {
private_data = p;
hw->private_free = mydata_free;
]]>
@@ -4837,9 +4835,9 @@ struct _snd_pcm_runtime {
private_data;
+ mydata_t *p = hw->private_data;
kfree(p);
}
]]>
@@ -5063,9 +5061,9 @@ struct _snd_pcm_runtime {
@@ -5146,7 +5144,7 @@ struct _snd_pcm_runtime {
@@ -5213,7 +5211,7 @@ struct _snd_pcm_runtime {
dma_private;
+ snd_pcm_sgbuf_t *sgbuf = (snd_pcm_sgbuf_t*)substream->dma_private;
]]>
@@ -5268,7 +5266,7 @@ struct _snd_pcm_runtime {
#include
/* get the physical page pointer on the given offset */
- static struct page *mychip_page(struct snd_pcm_substream *substream,
+ static struct page *mychip_page(snd_pcm_substream_t *substream,
unsigned long offset)
{
void *pageptr = substream->runtime->dma_area + offset;
@@ -5303,7 +5301,7 @@ struct _snd_pcm_runtime {
@@ -5347,8 +5345,8 @@ struct _snd_pcm_runtime {
@@ -5363,10 +5361,10 @@ struct _snd_pcm_runtime {
private_data;
+ chip_t *chip = entry->private_data;
snd_iprintf(buffer, "This is my chip!\n");
snd_iprintf(buffer, "Port = %ld\n", chip->port);
@@ -5455,7 +5453,7 @@ struct _snd_pcm_runtime {
CONFIG_PM.
-
- If the driver supports the suspend/resume
- fully, that is, the device can be
- properly resumed to the status at the suspend is called,
- you can set SNDRV_PCM_INFO_RESUME flag
- to pcm info field. Usually, this is possible when the
- registers of ths chip can be safely saved and restored to the
- RAM. If this is set, the trigger callback is called with
- SNDRV_PCM_TRIGGER_RESUME after resume
- callback is finished.
-
-
-
- Even if the driver doesn't support PM fully but only the
- partial suspend/resume is possible, it's still worthy to
- implement suspend/resume callbacks. In such a case, applications
- would reset the status by calling
- snd_pcm_prepare() and restart the stream
- appropriately. Hence, you can define suspend/resume callbacks
- below but don't set SNDRV_PCM_INFO_RESUME
- info flag to the PCM.
-
-
-
- Note that the trigger with SUSPEND can be always called when
- snd_pcm_suspend_all is called,
- regardless of SNDRV_PCM_INFO_RESUME flag.
- The RESUME flag affects only the behavior
- of snd_pcm_resume().
- (Thus, in theory,
- SNDRV_PCM_TRIGGER_RESUME isn't needed
- to be handled in the trigger callback when no
- SNDRV_PCM_INFO_RESUME flag is set. But,
- it's better to keep it for compatibility reason.)
-
- In the earlier version of ALSA drivers, a common
- power-management layer was provided, but it has been removed.
- The driver needs to define the suspend/resume hooks according to
- the bus the device is assigned. In the case of PCI driver, the
- callbacks look like below:
+ ALSA provides the common power-management layer. Each card driver
+ needs to have only low-level suspend and resume callbacks.
- Retrieve the card and the chip data.
- Call snd_power_change_state() with
- SNDRV_CTL_POWER_D3hot to change the
- power status.
+ Retrieve the chip data from pm_private_data field.
Call snd_pcm_suspend_all() to suspend the running PCM streams.
- If AC97 codecs are used, call
- snd_ac97_resume() for each codec.
Save the register values if necessary.
Stop the hardware if necessary.
- Disable the PCI device by calling
- pci_disable_device(). Then, call
- pci_save_state() at last.
+ Disable the PCI device by calling pci_disable_device().
@@ -5577,24 +5530,18 @@ struct _snd_pcm_runtime {
private_data;
+ mychip_t *chip = card->pm_private_data;
/* (2) */
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- /* (3) */
snd_pcm_suspend_all(chip->pcm);
- /* (4) */
- snd_ac97_suspend(chip->ac97);
- /* (5) */
+ /* (3) */
snd_mychip_save_registers(chip);
- /* (6) */
+ /* (4) */
snd_mychip_stop_hardware(chip);
- /* (7) */
- pci_disable_device(pci);
- pci_save_state(pci);
+ /* (5) */
+ pci_disable_device(chip->pci);
return 0;
}
]]>
@@ -5606,17 +5553,14 @@ struct _snd_pcm_runtime {
The scheme of the real resume job is as following.
- Retrieve the card and the chip data.
- Set up PCI. First, call pci_restore_state().
- Then enable the pci device again by calling pci_enable_device().
- Call pci_set_master() if necessary, too.
+ Retrieve the chip data from pm_private_data field.
+ Enable the pci device again by calling
+ pci_enable_device().
Re-initialize the chip.
Restore the saved registers if necessary.
Resume the mixer, e.g. calling
snd_ac97_resume().
Restart the hardware (if any).
- Call snd_power_change_state() with
- SNDRV_CTL_POWER_D0 to notify the processes.
@@ -5626,15 +5570,12 @@ struct _snd_pcm_runtime {
private_data;
+ mychip_t *chip = card->pm_private_data;
/* (2) */
- pci_restore_state(pci);
- pci_enable_device(pci);
- pci_set_master(pci);
+ pci_enable_device(chip->pci);
/* (3) */
snd_mychip_reinit_chip(chip);
/* (4) */
@@ -5643,8 +5584,6 @@ struct _snd_pcm_runtime {
snd_ac97_resume(chip->ac97);
/* (6) */
snd_mychip_restart_chip(chip);
- /* (7) */
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
}
]]>
@@ -5653,23 +5592,8 @@ struct _snd_pcm_runtime {
- As shown in the above, it's better to save registers after
- suspending the PCM operations via
- snd_pcm_suspend_all() or
- snd_pcm_suspend(). It means that the PCM
- streams are already stoppped when the register snapshot is
- taken. But, remind that you don't have to restart the PCM
- stream in the resume callback. It'll be restarted via
- trigger call with SNDRV_PCM_TRIGGER_RESUME
- when necessary.
-
-
-
- OK, we have all callbacks now. Let's set them up. In the
- initialization of the card, make sure that you can get the chip
- data from the card instance, typically via
- private_data field, in case you
- created the chip data individually.
+ OK, we have all callbacks now. Let's set up them now. In the
+ initialization of the card, add the following:
@@ -5678,56 +5602,33 @@ struct _snd_pcm_runtime {
const struct pci_device_id *pci_id)
{
....
- struct snd_card *card;
- struct mychip *chip;
+ snd_card_t *card;
+ mychip_t *chip;
....
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
- ....
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- ....
- card->private_data = chip;
- ....
- }
-]]>
-
-
-
- When you created the chip data with
- snd_card_new(), it's anyway accessible
- via private_data field.
-
-
-
-private_data;
+ snd_card_set_pm_callback(card, snd_my_suspend, snd_my_resume, chip);
....
}
]]>
+ Here you don't have to put ifdef CONFIG_PM around, since it's already
+ checked in the header and expanded to empty if not needed.
- If you need a space for saving the registers, allocate the
- buffer for it here, too, since it would be fatal
+ If you need a space for saving the registers, you'll need to
+ allocate the buffer for it here, too, since it would be fatal
if you cannot allocate a memory in the suspend phase.
The allocated buffer should be released in the corresponding
destructor.
- And next, set suspend/resume callbacks to the pci_driver.
+ And next, set suspend/resume callbacks to the pci_driver,
+ This can be done by passing a macro SND_PCI_PM_CALLBACKS
+ in the pci_driver struct. This macro is expanded to the correct
+ (global) callbacks if CONFIG_PM is set.
@@ -5737,10 +5638,7 @@ struct _snd_pcm_runtime {
.id_table = snd_my_ids,
.probe = snd_my_probe,
.remove = __devexit_p(snd_my_remove),
- #ifdef CONFIG_PM
- .suspend = snd_my_suspend,
- .resume = snd_my_resume,
- #endif
+ SND_PCI_PM_CALLBACKS
};
]]>
diff --git a/trunk/Documentation/sound/alsa/Procfile.txt b/trunk/Documentation/sound/alsa/Procfile.txt
index 1fe48846d78f..25c5d648aef6 100644
--- a/trunk/Documentation/sound/alsa/Procfile.txt
+++ b/trunk/Documentation/sound/alsa/Procfile.txt
@@ -138,22 +138,6 @@ card*/codec97#0/ac97#?-?+regs
# echo 02 9f1f > /proc/asound/card0/codec97#0/ac97#0-0+regs
-USB Audio Streams
------------------
-
-card*/stream*
- Shows the assignment and the current status of each audio stream
- of the given card. This information is very useful for debugging.
-
-
-HD-Audio Codecs
----------------
-
-card*/codec#*
- Shows the general codec information and the attribute of each
- widget node.
-
-
Sequencer Information
---------------------
diff --git a/trunk/Documentation/sound/alsa/hda_codec.txt b/trunk/Documentation/sound/alsa/hda_codec.txt
index 0be57ed81302..e9d07b8f1acb 100644
--- a/trunk/Documentation/sound/alsa/hda_codec.txt
+++ b/trunk/Documentation/sound/alsa/hda_codec.txt
@@ -63,7 +63,7 @@ The bus instance is created via snd_hda_bus_new(). You need to pass
the card instance, the template, and the pointer to store the
resultant bus instance.
-int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
+int snd_hda_bus_new(snd_card_t *card, const struct hda_bus_template *temp,
struct hda_bus **busp);
It returns zero if successful. A negative return value means any
@@ -166,14 +166,14 @@ The ops field contains the following callback functions:
struct hda_pcm_ops {
int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
- struct snd_pcm_substream *substream);
+ snd_pcm_substream_t *substream);
int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec,
- struct snd_pcm_substream *substream);
+ snd_pcm_substream_t *substream);
int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
unsigned int stream_tag, unsigned int format,
- struct snd_pcm_substream *substream);
+ snd_pcm_substream_t *substream);
int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
- struct snd_pcm_substream *substream);
+ snd_pcm_substream_t *substream);
};
All are non-NULL, so you can call them safely without NULL check.
@@ -284,7 +284,7 @@ parameter, and PCI subsystem IDs. If the matching entry is found, it
returns the config field value.
snd_hda_add_new_ctls() can be used to create and add control entries.
-Pass the zero-terminated array of struct snd_kcontrol_new. The same array
+Pass the zero-terminated array of snd_kcontrol_new_t. The same array
can be passed to snd_hda_resume_ctls() for resume.
Note that this will call control->put callback of these entries. So,
put callback should check codec->in_resume and force to restore the
@@ -292,7 +292,7 @@ given value if it's non-zero even if the value is identical with the
cached value.
Macros HDA_CODEC_VOLUME(), HDA_CODEC_MUTE() and their variables can be
-used for the entry of struct snd_kcontrol_new.
+used for the entry of snd_kcontrol_new_t.
The input MUX helper callbacks for such a control are provided, too:
snd_hda_input_mux_info() and snd_hda_input_mux_put(). See
diff --git a/trunk/Documentation/sysrq.txt b/trunk/Documentation/sysrq.txt
index ad0bedf678b3..baf17b381588 100644
--- a/trunk/Documentation/sysrq.txt
+++ b/trunk/Documentation/sysrq.txt
@@ -202,13 +202,17 @@ you must call __handle_sysrq_nolock instead.
* I have more questions, who can I ask?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+You may feel free to send email to myrdraal@deathsdoor.com, and I will
+respond as soon as possible.
+ -Myrdraal
+
And I'll answer any questions about the registration system you got, also
responding as soon as possible.
-Crutcher
* Credits
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Written by Mydraal
+Written by Mydraal
Updated by Adam Sulmicki
Updated by Jeremy M. Dolan 2001/01/28 10:15:59
Added to by Crutcher Dunnavant
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index 5daae53bf975..86ee06f43794 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -554,6 +554,11 @@ W: http://us1.samba.org/samba/Linux_CIFS_client.html
T: git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
S: Supported
+CONFIGFS
+P: Joel Becker
+M: Joel Becker
+S: Supported
+
CIRRUS LOGIC GENERIC FBDEV DRIVER
P: Jeff Garzik
M: jgarzik@pobox.com
@@ -650,11 +655,6 @@ L: linux-crypto@vger.kernel.org
T: git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
S: Maintained
-CS5535 Audio ALSA driver
-P: Jaya Kumar
-M: jayakumar.alsa@gmail.com
-S: Maintained
-
CYBERPRO FB DRIVER
P: Russell King
M: rmk@arm.linux.org.uk
@@ -1230,7 +1230,7 @@ IEEE 1394 SUBSYSTEM
P: Ben Collins
M: bcollins@debian.org
P: Jody McIntyre
-M: scjody@modernduck.com
+M: scjody@steamballoon.com
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
T: git kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git
@@ -1240,14 +1240,14 @@ IEEE 1394 OHCI DRIVER
P: Ben Collins
M: bcollins@debian.org
P: Jody McIntyre
-M: scjody@modernduck.com
+M: scjody@steamballoon.com
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Maintained
IEEE 1394 PCILYNX DRIVER
P: Jody McIntyre
-M: scjody@modernduck.com
+M: scjody@steamballoon.com
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
S: Maintained
@@ -1470,6 +1470,7 @@ P: Several
L: kernel-janitors@osdl.org
W: http://www.kerneljanitors.org/
W: http://sf.net/projects/kernel-janitor/
+W: http://developer.osdl.org/rddunlap/kj-patches/
S: Maintained
KERNEL NFSD
@@ -1480,11 +1481,17 @@ W: http://nfs.sourceforge.net/
W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
S: Maintained
+KERNEL EVENT LAYER (KOBJECT_UEVENT)
+P: Robert Love
+M: rml@novell.com
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
KEXEC
P: Eric Biederman
P: Randy Dunlap
M: ebiederm@xmission.com
-M: rdunlap@xenotime.net
+M: rddunlap@osdl.org
W: http://www.xmission.com/~ebiederm/files/kexec/
L: linux-kernel@vger.kernel.org
L: fastboot@osdl.org
@@ -2585,6 +2592,7 @@ S: Maintained
UDF FILESYSTEM
P: Ben Fennema
M: bfennema@falcon.csc.calpoly.edu
+L: linux_udf@hpesjro.fc.hp.com
W: http://linux-udf.sourceforge.net
S: Maintained
@@ -2637,12 +2645,6 @@ L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
S: Maintained
-USB ISP116X DRIVER
-P: Olav Kongas
-M: ok@artecdesign.ee
-L: linux-usb-devel@lists.sourceforge.net
-S: Maintained
-
USB KAWASAKI LSI DRIVER
P: Oliver Neukum
M: oliver@neukum.name
@@ -2654,7 +2656,7 @@ USB MASS STORAGE DRIVER
P: Matthew Dharm
M: mdharm-usb@one-eyed-alien.net
L: linux-usb-users@lists.sourceforge.net
-L: usb-storage@lists.one-eyed-alien.net
+L: linux-usb-devel@lists.sourceforge.net
S: Maintained
W: http://www.one-eyed-alien.net/~mdharm/linux-usb/
diff --git a/trunk/Makefile b/trunk/Makefile
index 599e744d3e33..497884d3d556 100644
--- a/trunk/Makefile
+++ b/trunk/Makefile
@@ -286,6 +286,10 @@ export quiet Q KBUILD_VERBOSE
cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
+# For backward compatibility
+check_gcc = $(warning check_gcc is deprecated - use cc-option) \
+ $(call cc-option, $(1),$(2))
+
# cc-option-yn
# Usage: flag := $(call cc-option-yn, -march=winchip-c6)
cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
@@ -477,20 +481,18 @@ ifeq ($(dot-config),1)
# Read in dependencies to all Kconfig* files, make sure to run
# oldconfig if changes are detected.
--include .kconfig.d
+-include .config.cmd
include .config
# If .config needs to be updated, it will be done via the dependency
# that autoconf has on .config.
# To avoid any implicit rule to kick in, define an empty command
-.config .kconfig.d: ;
+.config: ;
# If .config is newer than include/linux/autoconf.h, someone tinkered
-# with it and forgot to run make oldconfig.
-# If kconfig.d is missing then we are probarly in a cleaned tree so
-# we execute the config step to be sure to catch updated Kconfig files
-include/linux/autoconf.h: .kconfig.d .config
+# with it and forgot to run make oldconfig
+include/linux/autoconf.h: .config
$(Q)mkdir -p include/linux
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
else
@@ -1064,7 +1066,7 @@ help:
@echo ' all - Build all targets marked with [*]'
@echo '* vmlinux - Build the bare kernel'
@echo '* modules - Build all modules'
- @echo ' modules_install - Install all modules to INSTALL_MOD_PATH (default: /)'
+ @echo ' modules_install - Install all modules'
@echo ' dir/ - Build all files in dir and below'
@echo ' dir/file.[ois] - Build specified target only'
@echo ' dir/file.ko - Build module including final link'
@@ -1238,11 +1240,8 @@ cscope: FORCE
quiet_cmd_TAGS = MAKE $@
define cmd_TAGS
rm -f $@; \
- ETAGSF=`etags --version | grep -i exuberant >/dev/null && \
- echo "-I __initdata,__exitdata,__acquires,__releases \
- -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
- --extra=+f --c-kinds=+px"`; \
- $(all-sources) | xargs etags $$ETAGSF -a
+ ETAGSF=`etags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \
+ $(all-sources) | xargs etags $$ETAGSF -a
endef
TAGS: FORCE
@@ -1252,11 +1251,8 @@ TAGS: FORCE
quiet_cmd_tags = MAKE $@
define cmd_tags
rm -f $@; \
- CTAGSF=`ctags --version | grep -i exuberant >/dev/null && \
- echo "-I __initdata,__exitdata,__acquires,__releases \
- -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
- --extra=+f --c-kinds=+px"`; \
- $(all-sources) | xargs ctags $$CTAGSF -a
+ CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \
+ $(all-sources) | xargs ctags $$CTAGSF -a
endef
tags: FORCE
diff --git a/trunk/arch/arm/common/amba.c b/trunk/arch/arm/common/amba.c
index c95ec9eab996..e1013112c354 100644
--- a/trunk/arch/arm/common/amba.c
+++ b/trunk/arch/arm/common/amba.c
@@ -45,7 +45,7 @@ static int amba_match(struct device *dev, struct device_driver *drv)
}
#ifdef CONFIG_HOTPLUG
-static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
+static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
{
struct amba_device *pcdev = to_amba_device(dev);
@@ -58,7 +58,7 @@ static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, i
return 0;
}
#else
-#define amba_uevent NULL
+#define amba_hotplug NULL
#endif
static int amba_suspend(struct device *dev, pm_message_t state)
@@ -88,7 +88,7 @@ static int amba_resume(struct device *dev)
static struct bus_type amba_bustype = {
.name = "amba",
.match = amba_match,
- .uevent = amba_uevent,
+ .hotplug = amba_hotplug,
.suspend = amba_suspend,
.resume = amba_resume,
};
diff --git a/trunk/arch/arm/mach-pxa/mainstone.c b/trunk/arch/arm/mach-pxa/mainstone.c
index 277498ae5b6c..07892f4012d8 100644
--- a/trunk/arch/arm/mach-pxa/mainstone.c
+++ b/trunk/arch/arm/mach-pxa/mainstone.c
@@ -43,7 +43,6 @@
#include
#include
#include
-#include
#include "generic.h"
@@ -394,25 +393,6 @@ static struct platform_device *platform_devices[] __initdata = {
&mst_flash_device[1],
};
-static int mainstone_ohci_init(struct device *dev)
-{
- /* setup Port1 GPIO pin. */
- pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */
- pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */
-
- /* Set the Power Control Polarity Low and Power Sense
- Polarity Low to active low. */
- UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
- ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
-
- return 0;
-}
-
-static struct pxaohci_platform_data mainstone_ohci_platform_data = {
- .port_mode = PMM_PERPORT_MODE,
- .init = mainstone_ohci_init,
-};
-
static void __init mainstone_init(void)
{
int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
@@ -444,7 +424,6 @@ static void __init mainstone_init(void)
pxa_set_mci_info(&mainstone_mci_platform_data);
pxa_set_ficp_info(&mainstone_ficp_platform_data);
- pxa_set_ohci_info(&mainstone_ohci_platform_data);
}
diff --git a/trunk/arch/arm/mach-pxa/pxa27x.c b/trunk/arch/arm/mach-pxa/pxa27x.c
index b41b1efaa2cf..c722a9a91fcc 100644
--- a/trunk/arch/arm/mach-pxa/pxa27x.c
+++ b/trunk/arch/arm/mach-pxa/pxa27x.c
@@ -21,7 +21,6 @@
#include
#include
#include
-#include
#include "generic.h"
@@ -195,11 +194,6 @@ static struct platform_device ohci_device = {
.resource = pxa27x_ohci_resources,
};
-void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
-{
- ohci_device.dev.platform_data = info;
-}
-
static struct platform_device *devices[] __initdata = {
&ohci_device,
};
diff --git a/trunk/arch/arm26/nwfpe/fpmodule.c b/trunk/arch/arm26/nwfpe/fpmodule.c
index 5258c6096fb9..528fa710aa34 100644
--- a/trunk/arch/arm26/nwfpe/fpmodule.c
+++ b/trunk/arch/arm26/nwfpe/fpmodule.c
@@ -46,9 +46,10 @@ typedef struct task_struct* PTASK;
#ifdef MODULE
void fp_send_sig(unsigned long sig, PTASK p, int priv);
-
+#if LINUX_VERSION_CODE > 0x20115
MODULE_AUTHOR("Scott Bambrough ");
MODULE_DESCRIPTION("NWFPE floating point emulator");
+#endif
#else
#define fp_send_sig send_sig
diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/trunk/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
index 2b62dee35c6c..04a405345203 100644
--- a/trunk/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
+++ b/trunk/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
@@ -177,10 +177,9 @@ static unsigned int nforce2_fsb_read(int bootfsb)
*/
static int nforce2_set_fsb(unsigned int fsb)
{
- u32 temp = 0;
+ u32 pll, temp = 0;
unsigned int tfsb;
int diff;
- int pll = 0;
if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);
diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index 0fbbd4c1072e..68a1fc87f4ca 100644
--- a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -45,7 +45,7 @@
#define PFX "powernow-k8: "
#define BFX PFX "BIOS error: "
-#define VERSION "version 1.60.0"
+#define VERSION "version 1.50.4"
#include "powernow-k8.h"
/* serialize freq changes */
@@ -216,10 +216,10 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid)
do {
wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
- if (i++ > 100) {
- printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
- return 1;
- }
+ if (i++ > 100) {
+ printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
+ return 1;
+ }
} while (query_current_values_with_pending_wait(data));
if (savefid != data->currfid) {
@@ -336,7 +336,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
/* Phase 2 - core frequency transition */
static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
{
- u32 vcoreqfid, vcocurrfid, vcofiddiff, fid_interval, savevid = data->currvid;
+ u32 vcoreqfid, vcocurrfid, vcofiddiff, savevid = data->currvid;
if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n",
@@ -359,11 +359,9 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
: vcoreqfid - vcocurrfid;
while (vcofiddiff > 2) {
- (data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2);
-
if (reqfid > data->currfid) {
if (data->currfid > LO_FID_TABLE_TOP) {
- if (write_new_fid(data, data->currfid + fid_interval)) {
+ if (write_new_fid(data, data->currfid + 2)) {
return 1;
}
} else {
@@ -373,7 +371,7 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
}
}
} else {
- if (write_new_fid(data, data->currfid - fid_interval))
+ if (write_new_fid(data, data->currfid - 2))
return 1;
}
@@ -466,7 +464,7 @@ static int check_supported_cpu(unsigned int cpu)
set_cpus_allowed(current, cpumask_of_cpu(cpu));
if (smp_processor_id() != cpu) {
- printk(KERN_ERR PFX "limiting to cpu %u failed\n", cpu);
+ printk(KERN_ERR "limiting to cpu %u failed\n", cpu);
goto out;
}
@@ -476,7 +474,7 @@ static int check_supported_cpu(unsigned int cpu)
eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
((eax & CPUID_XFAM) != CPUID_XFAM_K8) ||
- ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) {
+ ((eax & CPUID_XMOD) > CPUID_XMOD_REV_F)) {
printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
goto out;
}
@@ -519,24 +517,22 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8
printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j);
return -ENODEV;
}
- if (pst[j].fid > MAX_FID) {
- printk(KERN_ERR BFX "maxfid exceeded with pstate %d\n", j);
- return -ENODEV;
- }
- if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) {
+ if ((pst[j].fid > MAX_FID)
+ || (pst[j].fid & 1)
+ || (j && (pst[j].fid < HI_FID_TABLE_BOTTOM))) {
/* Only first fid is allowed to be in "low" range */
- printk(KERN_ERR BFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
+ printk(KERN_ERR PFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
return -EINVAL;
}
if (pst[j].fid < lastfid)
lastfid = pst[j].fid;
}
if (lastfid & 1) {
- printk(KERN_ERR BFX "lastfid invalid\n");
+ printk(KERN_ERR PFX "lastfid invalid\n");
return -EINVAL;
}
if (lastfid > LO_FID_TABLE_TOP)
- printk(KERN_INFO BFX "first fid not from lo freq table\n");
+ printk(KERN_INFO PFX "first fid not from lo freq table\n");
return 0;
}
@@ -635,7 +631,7 @@ static int find_psb_table(struct powernow_k8_data *data)
dprintk("table vers: 0x%x\n", psb->tableversion);
if (psb->tableversion != PSB_VERSION_1_4) {
- printk(KERN_ERR BFX "PSB table is not v1.4\n");
+ printk(KERN_INFO BFX "PSB table is not v1.4\n");
return -ENODEV;
}
@@ -693,7 +689,7 @@ static int find_psb_table(struct powernow_k8_data *data)
* BIOS and Kernel Developer's Guide, which is available on
* www.amd.com
*/
- printk(KERN_ERR PFX "BIOS error - no PSB or ACPI _PSS objects\n");
+ printk(KERN_INFO PFX "BIOS error - no PSB or ACPI _PSS objects\n");
return -ENODEV;
}
@@ -916,7 +912,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
if (smp_processor_id() != pol->cpu) {
- printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
+ printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
goto err_out;
}
@@ -986,9 +982,6 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
cpumask_t oldmask = CPU_MASK_ALL;
int rc, i;
- if (!cpu_online(pol->cpu))
- return -ENODEV;
-
if (!check_supported_cpu(pol->cpu))
return -ENODEV;
@@ -1028,7 +1021,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
if (smp_processor_id() != pol->cpu) {
- printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
+ printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
goto err_out;
}
@@ -1169,9 +1162,10 @@ static void __exit powernowk8_exit(void)
cpufreq_unregister_driver(&cpufreq_amd64_driver);
}
-MODULE_AUTHOR("Paul Devriendt and Mark Langsdorf ");
+MODULE_AUTHOR("Paul Devriendt and Mark Langsdorf = interprocessor hypertransport link speed
* (only applies to MP systems obviously)
*/
/* fids (frequency identifiers) are arranged in 2 tables - lo and hi */
-#define LO_FID_TABLE_TOP 7 /* fid values marking the boundary */
+#define LO_FID_TABLE_TOP 6 /* fid values marking the boundary */
#define HI_FID_TABLE_BOTTOM 8 /* between the low and high tables */
#define LO_VCOFREQ_TABLE_TOP 1400 /* corresponding vco frequency values */
@@ -107,7 +106,7 @@ struct powernow_k8_data {
#define MIN_FREQ 800 /* Min and max freqs, per spec */
#define MAX_FREQ 5000
-#define INVALID_FID_MASK 0xffffffc0 /* not a valid fid if these bits are set */
+#define INVALID_FID_MASK 0xffffffc1 /* not a valid fid if these bits are set */
#define INVALID_VID_MASK 0xffffffc0 /* not a valid vid if these bits are set */
#define VID_OFF 0x3f
diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
index b425cd3d1838..5b7d18a06afa 100644
--- a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
@@ -40,7 +40,6 @@ static struct pci_dev *speedstep_chipset_dev;
*/
static unsigned int speedstep_processor = 0;
-static u32 pmbase;
/*
* There are only two frequency states for each processor. Values
@@ -57,46 +56,33 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
/**
- * speedstep_find_register - read the PMBASE address
+ * speedstep_set_state - set the SpeedStep state
+ * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
*
- * Returns: -ENODEV if no register could be found
+ * Tries to change the SpeedStep state.
*/
-static int speedstep_find_register (void)
+static void speedstep_set_state (unsigned int state)
{
- if (!speedstep_chipset_dev)
- return -ENODEV;
+ u32 pmbase;
+ u8 pm2_blk;
+ u8 value;
+ unsigned long flags;
+
+ if (!speedstep_chipset_dev || (state > 0x1))
+ return;
/* get PMBASE */
pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
if (!(pmbase & 0x01)) {
printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
- return -ENODEV;
+ return;
}
pmbase &= 0xFFFFFFFE;
if (!pmbase) {
printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
- return -ENODEV;
- }
-
- dprintk("pmbase is 0x%x\n", pmbase);
- return 0;
-}
-
-/**
- * speedstep_set_state - set the SpeedStep state
- * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
- *
- * Tries to change the SpeedStep state.
- */
-static void speedstep_set_state (unsigned int state)
-{
- u8 pm2_blk;
- u8 value;
- unsigned long flags;
-
- if (state > 0x1)
return;
+ }
/* Disable IRQs */
local_irq_save(flags);
@@ -329,11 +315,10 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
cpus_allowed = current->cpus_allowed;
set_cpus_allowed(current, policy->cpus);
- /* detect low and high frequency and transition latency */
+ /* detect low and high frequency */
result = speedstep_get_freqs(speedstep_processor,
&speedstep_freqs[SPEEDSTEP_LOW].frequency,
&speedstep_freqs[SPEEDSTEP_HIGH].frequency,
- &policy->cpuinfo.transition_latency,
&speedstep_set_state);
set_cpus_allowed(current, cpus_allowed);
if (result)
@@ -350,6 +335,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
/* cpuinfo and default policy values */
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cur = speed;
result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
@@ -414,9 +400,6 @@ static int __init speedstep_init(void)
return -EINVAL;
}
- if (speedstep_find_register())
- return -ENODEV;
-
return cpufreq_register_driver(&speedstep_driver);
}
diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
index 7c47005a1805..d368b3f5fce8 100644
--- a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
+++ b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
@@ -320,13 +320,11 @@ EXPORT_SYMBOL_GPL(speedstep_detect_processor);
unsigned int speedstep_get_freqs(unsigned int processor,
unsigned int *low_speed,
unsigned int *high_speed,
- unsigned int *transition_latency,
void (*set_state) (unsigned int state))
{
unsigned int prev_speed;
unsigned int ret = 0;
unsigned long flags;
- struct timeval tv1, tv2;
if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
return -EINVAL;
@@ -339,7 +337,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
return -EIO;
dprintk("previous speed is %u\n", prev_speed);
-
+
local_irq_save(flags);
/* switch to low state */
@@ -352,17 +350,8 @@ unsigned int speedstep_get_freqs(unsigned int processor,
dprintk("low speed is %u\n", *low_speed);
- /* start latency measurement */
- if (transition_latency)
- do_gettimeofday(&tv1);
-
/* switch to high state */
set_state(SPEEDSTEP_HIGH);
-
- /* end latency measurement */
- if (transition_latency)
- do_gettimeofday(&tv2);
-
*high_speed = speedstep_get_processor_frequency(processor);
if (!*high_speed) {
ret = -EIO;
@@ -380,25 +369,6 @@ unsigned int speedstep_get_freqs(unsigned int processor,
if (*high_speed != prev_speed)
set_state(SPEEDSTEP_LOW);
- if (transition_latency) {
- *transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC +
- tv2.tv_usec - tv1.tv_usec;
- dprintk("transition latency is %u uSec\n", *transition_latency);
-
- /* convert uSec to nSec and add 20% for safety reasons */
- *transition_latency *= 1200;
-
- /* check if the latency measurement is too high or too low
- * and set it to a safe value (500uSec) in that case
- */
- if (*transition_latency > 10000000 || *transition_latency < 50000) {
- printk (KERN_WARNING "speedstep: frequency transition measured seems out of "
- "range (%u nSec), falling back to a safe one of %u nSec.\n",
- *transition_latency, 500000);
- *transition_latency = 500000;
- }
- }
-
out:
local_irq_restore(flags);
return (ret);
diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
index 6a727fd3a77e..261a2c9b7f6b 100644
--- a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
+++ b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
@@ -44,5 +44,4 @@ extern unsigned int speedstep_get_processor_frequency(unsigned int processor);
extern unsigned int speedstep_get_freqs(unsigned int processor,
unsigned int *low_speed,
unsigned int *high_speed,
- unsigned int *transition_latency,
void (*set_state) (unsigned int state));
diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
index 28cc5d524afc..2718fb6f6aba 100644
--- a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+++ b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
@@ -269,7 +269,6 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
result = speedstep_get_freqs(speedstep_processor,
&speedstep_freqs[SPEEDSTEP_LOW].frequency,
&speedstep_freqs[SPEEDSTEP_HIGH].frequency,
- NULL,
&speedstep_set_state);
if (result) {
diff --git a/trunk/arch/i386/kernel/cpu/proc.c b/trunk/arch/i386/kernel/cpu/proc.c
index 6d91b274589c..e7921315ae9d 100644
--- a/trunk/arch/i386/kernel/cpu/proc.c
+++ b/trunk/arch/i386/kernel/cpu/proc.c
@@ -3,7 +3,6 @@
#include
#include
#include
-#include
/*
* Get CPU information for use by the procfs.
@@ -87,11 +86,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "stepping\t: unknown\n");
if ( cpu_has(c, X86_FEATURE_TSC) ) {
- unsigned int freq = cpufreq_quick_get(n);
- if (!freq)
- freq = cpu_khz;
seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
- freq / 1000, (freq % 1000));
+ cpu_khz / 1000, (cpu_khz % 1000));
}
/* Cache size */
diff --git a/trunk/arch/i386/kernel/traps.c b/trunk/arch/i386/kernel/traps.c
index ab0e9430f775..f0dffa03fbba 100644
--- a/trunk/arch/i386/kernel/traps.c
+++ b/trunk/arch/i386/kernel/traps.c
@@ -452,7 +452,7 @@ DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
#endif
DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
-DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip)
+DO_ERROR_INFO( 6, SIGILL, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
diff --git a/trunk/arch/ia64/kernel/setup.c b/trunk/arch/ia64/kernel/setup.c
index c33305d8e5eb..5add0bcf87a7 100644
--- a/trunk/arch/ia64/kernel/setup.c
+++ b/trunk/arch/ia64/kernel/setup.c
@@ -43,7 +43,6 @@
#include
#include
#include
-#include
#include
#include
@@ -518,7 +517,6 @@ show_cpuinfo (struct seq_file *m, void *v)
char family[32], features[128], *cp, sep;
struct cpuinfo_ia64 *c = v;
unsigned long mask;
- unsigned long proc_freq;
int i;
mask = c->features;
@@ -551,10 +549,6 @@ show_cpuinfo (struct seq_file *m, void *v)
sprintf(cp, " 0x%lx", mask);
}
- proc_freq = cpufreq_quick_get(cpunum);
- if (!proc_freq)
- proc_freq = c->proc_freq / 1000;
-
seq_printf(m,
"processor : %d\n"
"vendor : %s\n"
@@ -571,7 +565,7 @@ show_cpuinfo (struct seq_file *m, void *v)
"BogoMIPS : %lu.%02lu\n",
cpunum, c->vendor, family, c->model, c->revision, c->archrev,
features, c->ppn, c->number,
- proc_freq / 1000, proc_freq % 1000,
+ c->proc_freq / 1000000, c->proc_freq % 1000000,
c->itc_freq / 1000000, c->itc_freq % 1000000,
lpj*HZ/500000, (lpj*HZ/5000) % 100);
#ifdef CONFIG_SMP
diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c
index 30dbc98bf0b3..20d76fae24e8 100644
--- a/trunk/arch/ia64/pci/pci.c
+++ b/trunk/arch/ia64/pci/pci.c
@@ -700,7 +700,7 @@ int ia64_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
*/
int ia64_pci_legacy_write(struct pci_dev *bus, u16 port, u32 val, u8 size)
{
- int ret = size;
+ int ret = 0;
switch (size) {
case 1:
diff --git a/trunk/arch/ia64/sn/kernel/tiocx.c b/trunk/arch/ia64/sn/kernel/tiocx.c
index 768c21deb2e5..0d8592a745a7 100644
--- a/trunk/arch/ia64/sn/kernel/tiocx.c
+++ b/trunk/arch/ia64/sn/kernel/tiocx.c
@@ -65,7 +65,7 @@ static int tiocx_match(struct device *dev, struct device_driver *drv)
}
-static int tiocx_uevent(struct device *dev, char **envp, int num_envp,
+static int tiocx_hotplug(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
return -ENODEV;
@@ -79,7 +79,7 @@ static void tiocx_bus_release(struct device *dev)
struct bus_type tiocx_bus_type = {
.name = "tiocx",
.match = tiocx_match,
- .uevent = tiocx_uevent,
+ .hotplug = tiocx_hotplug,
};
/**
diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c
index 60353f5acc48..330cf84d21fe 100644
--- a/trunk/arch/mips/kernel/linux32.c
+++ b/trunk/arch/mips/kernel/linux32.c
@@ -420,7 +420,7 @@ asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf,
goto out;
pos = merge_64(a4, a5);
ret = rw_verify_area(READ, file, &pos, count);
- if (ret < 0)
+ if (ret)
goto out;
ret = -EINVAL;
if (!file->f_op || !(read = file->f_op->read))
@@ -455,7 +455,7 @@ asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char * buf,
goto out;
pos = merge_64(a4, a5);
ret = rw_verify_area(WRITE, file, &pos, count);
- if (ret < 0)
+ if (ret)
goto out;
ret = -EINVAL;
if (!file->f_op || !(write = file->f_op->write))
diff --git a/trunk/arch/powerpc/kernel/vio.c b/trunk/arch/powerpc/kernel/vio.c
index 13c41495fe06..71a6addf9f7f 100644
--- a/trunk/arch/powerpc/kernel/vio.c
+++ b/trunk/arch/powerpc/kernel/vio.c
@@ -293,6 +293,6 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
struct bus_type vio_bus_type = {
.name = "vio",
- .uevent = vio_hotplug,
+ .hotplug = vio_hotplug,
.match = vio_bus_match,
};
diff --git a/trunk/arch/x86_64/boot/.gitignore b/trunk/arch/x86_64/boot/.gitignore
deleted file mode 100644
index 495f20c085de..000000000000
--- a/trunk/arch/x86_64/boot/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-bootsect
-bzImage
-setup
diff --git a/trunk/arch/x86_64/boot/tools/.gitignore b/trunk/arch/x86_64/boot/tools/.gitignore
deleted file mode 100644
index 378eac25d311..000000000000
--- a/trunk/arch/x86_64/boot/tools/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build
diff --git a/trunk/arch/x86_64/ia32/.gitignore b/trunk/arch/x86_64/ia32/.gitignore
deleted file mode 100644
index 48ab174fe5f1..000000000000
--- a/trunk/arch/x86_64/ia32/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vsyscall*.so
diff --git a/trunk/arch/x86_64/kernel/setup.c b/trunk/arch/x86_64/kernel/setup.c
index 64c4534b930c..750e01dcbdf4 100644
--- a/trunk/arch/x86_64/kernel/setup.c
+++ b/trunk/arch/x86_64/kernel/setup.c
@@ -42,7 +42,6 @@
#include
#include
#include
-#include
#include
#include
@@ -1257,11 +1256,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "stepping\t: unknown\n");
if (cpu_has(c,X86_FEATURE_TSC)) {
- unsigned int freq = cpufreq_quick_get((unsigned)(c-cpu_data));
- if (!freq)
- freq = cpu_khz;
seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
- freq / 1000, (freq % 1000));
+ cpu_khz / 1000, (cpu_khz % 1000));
}
/* Cache size */
diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c
index f1ed83f3f083..f04609d553b8 100644
--- a/trunk/block/genhd.c
+++ b/trunk/block/genhd.c
@@ -358,7 +358,7 @@ static struct sysfs_ops disk_sysfs_ops = {
static ssize_t disk_uevent_store(struct gendisk * disk,
const char *buf, size_t count)
{
- kobject_uevent(&disk->kobj, KOBJ_ADD);
+ kobject_hotplug(&disk->kobj, KOBJ_ADD);
return count;
}
static ssize_t disk_dev_read(struct gendisk * disk, char *page)
@@ -455,14 +455,14 @@ static struct kobj_type ktype_block = {
extern struct kobj_type ktype_part;
-static int block_uevent_filter(struct kset *kset, struct kobject *kobj)
+static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
return ((ktype == &ktype_block) || (ktype == &ktype_part));
}
-static int block_uevent(struct kset *kset, struct kobject *kobj, char **envp,
+static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct kobj_type *ktype = get_ktype(kobj);
@@ -474,40 +474,40 @@ static int block_uevent(struct kset *kset, struct kobject *kobj, char **envp,
if (ktype == &ktype_block) {
disk = container_of(kobj, struct gendisk, kobj);
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
- &length, "MINOR=%u", disk->first_minor);
+ add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
+ &length, "MINOR=%u", disk->first_minor);
} else if (ktype == &ktype_part) {
disk = container_of(kobj->parent, struct gendisk, kobj);
part = container_of(kobj, struct hd_struct, kobj);
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
- &length, "MINOR=%u",
- disk->first_minor + part->partno);
+ add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
+ &length, "MINOR=%u",
+ disk->first_minor + part->partno);
} else
return 0;
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "MAJOR=%u", disk->major);
+ add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &length,
+ "MAJOR=%u", disk->major);
/* add physical device, backing this device */
physdev = disk->driverfs_dev;
if (physdev) {
char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL);
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
- &length, "PHYSDEVPATH=%s", path);
+ add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
+ &length, "PHYSDEVPATH=%s", path);
kfree(path);
if (physdev->bus)
- add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "PHYSDEVBUS=%s",
- physdev->bus->name);
+ add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PHYSDEVBUS=%s",
+ physdev->bus->name);
if (physdev->driver)
- add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "PHYSDEVDRIVER=%s",
- physdev->driver->name);
+ add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PHYSDEVDRIVER=%s",
+ physdev->driver->name);
}
/* terminate, set to next free slot, shrink available space */
@@ -520,13 +520,13 @@ static int block_uevent(struct kset *kset, struct kobject *kobj, char **envp,
return 0;
}
-static struct kset_uevent_ops block_uevent_ops = {
- .filter = block_uevent_filter,
- .uevent = block_uevent,
+static struct kset_hotplug_ops block_hotplug_ops = {
+ .filter = block_hotplug_filter,
+ .hotplug = block_hotplug,
};
/* declare block_subsys. */
-static decl_subsys(block, &ktype_block, &block_uevent_ops);
+static decl_subsys(block, &ktype_block, &block_hotplug_ops);
/*
diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c
index d4beb9a89ee0..99c9ca6d5992 100644
--- a/trunk/block/ll_rw_blk.c
+++ b/trunk/block/ll_rw_blk.c
@@ -239,7 +239,7 @@ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
q->backing_dev_info.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
q->backing_dev_info.state = 0;
q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY;
- blk_queue_max_sectors(q, SAFE_MAX_SECTORS);
+ blk_queue_max_sectors(q, MAX_SECTORS);
blk_queue_hardsect_size(q, 512);
blk_queue_dma_alignment(q, 511);
blk_queue_congestion_threshold(q);
@@ -555,12 +555,7 @@ void blk_queue_max_sectors(request_queue_t *q, unsigned short max_sectors)
printk("%s: set to minimum %d\n", __FUNCTION__, max_sectors);
}
- if (BLK_DEF_MAX_SECTORS > max_sectors)
- q->max_hw_sectors = q->max_sectors = max_sectors;
- else {
- q->max_sectors = BLK_DEF_MAX_SECTORS;
- q->max_hw_sectors = max_sectors;
- }
+ q->max_sectors = q->max_hw_sectors = max_sectors;
}
EXPORT_SYMBOL(blk_queue_max_sectors);
@@ -662,8 +657,8 @@ EXPORT_SYMBOL(blk_queue_hardsect_size);
void blk_queue_stack_limits(request_queue_t *t, request_queue_t *b)
{
/* zero is "infinity" */
- t->max_sectors = min_not_zero(t->max_sectors,b->max_sectors);
- t->max_hw_sectors = min_not_zero(t->max_hw_sectors,b->max_hw_sectors);
+ t->max_sectors = t->max_hw_sectors =
+ min_not_zero(t->max_sectors,b->max_sectors);
t->max_phys_segments = min(t->max_phys_segments,b->max_phys_segments);
t->max_hw_segments = min(t->max_hw_segments,b->max_hw_segments);
@@ -1298,15 +1293,9 @@ static inline int ll_new_hw_segment(request_queue_t *q,
static int ll_back_merge_fn(request_queue_t *q, struct request *req,
struct bio *bio)
{
- unsigned short max_sectors;
int len;
- if (unlikely(blk_pc_request(req)))
- max_sectors = q->max_hw_sectors;
- else
- max_sectors = q->max_sectors;
-
- if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
+ if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) {
req->flags |= REQ_NOMERGE;
if (req == q->last_merge)
q->last_merge = NULL;
@@ -1336,16 +1325,9 @@ static int ll_back_merge_fn(request_queue_t *q, struct request *req,
static int ll_front_merge_fn(request_queue_t *q, struct request *req,
struct bio *bio)
{
- unsigned short max_sectors;
int len;
- if (unlikely(blk_pc_request(req)))
- max_sectors = q->max_hw_sectors;
- else
- max_sectors = q->max_sectors;
-
-
- if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
+ if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) {
req->flags |= REQ_NOMERGE;
if (req == q->last_merge)
q->last_merge = NULL;
@@ -2162,7 +2144,7 @@ int blk_rq_map_user(request_queue_t *q, struct request *rq, void __user *ubuf,
struct bio *bio;
int reading;
- if (len > (q->max_hw_sectors << 9))
+ if (len > (q->max_sectors << 9))
return -EINVAL;
if (!len || !ubuf)
return -EINVAL;
@@ -2277,7 +2259,7 @@ int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf,
{
struct bio *bio;
- if (len > (q->max_hw_sectors << 9))
+ if (len > (q->max_sectors << 9))
return -EINVAL;
if (!len || !kbuf)
return -EINVAL;
@@ -2324,8 +2306,6 @@ void blk_execute_rq_nowait(request_queue_t *q, struct gendisk *bd_disk,
generic_unplug_device(q);
}
-EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
-
/**
* blk_execute_rq - insert a request into queue for execution
* @q: queue to insert the request in
@@ -2464,7 +2444,7 @@ void disk_round_stats(struct gendisk *disk)
/*
* queue lock must be held
*/
-void __blk_put_request(request_queue_t *q, struct request *req)
+static void __blk_put_request(request_queue_t *q, struct request *req)
{
struct request_list *rl = req->rl;
@@ -2493,8 +2473,6 @@ void __blk_put_request(request_queue_t *q, struct request *req)
}
}
-EXPORT_SYMBOL_GPL(__blk_put_request);
-
void blk_put_request(struct request *req)
{
unsigned long flags;
diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c
index 1d8852f7bbff..6e7db2e79f42 100644
--- a/trunk/block/scsi_ioctl.c
+++ b/trunk/block/scsi_ioctl.c
@@ -233,7 +233,7 @@ static int sg_io(struct file *file, request_queue_t *q,
if (verify_command(file, cmd))
return -EPERM;
- if (hdr->dxfer_len > (q->max_hw_sectors << 9))
+ if (hdr->dxfer_len > (q->max_sectors << 9))
return -EIO;
if (hdr->dxfer_len)
diff --git a/trunk/drivers/acpi/container.c b/trunk/drivers/acpi/container.c
index b69a8cad82b7..27ec12c1fab0 100644
--- a/trunk/drivers/acpi/container.c
+++ b/trunk/drivers/acpi/container.c
@@ -172,21 +172,21 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
if (ACPI_FAILURE(status) || !device) {
result = container_device_add(&device, handle);
if (!result)
- kobject_uevent(&device->kobj,
- KOBJ_ONLINE);
+ kobject_hotplug(&device->kobj,
+ KOBJ_ONLINE);
else
printk("Failed to add container\n");
}
} else {
if (ACPI_SUCCESS(status)) {
/* device exist and this is a remove request */
- kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+ kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
}
}
break;
case ACPI_NOTIFY_EJECT_REQUEST:
if (!acpi_bus_get_device(handle, &device) && device) {
- kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+ kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
}
break;
default:
diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c
index 1278aca96fe3..0c561c571f29 100644
--- a/trunk/drivers/acpi/processor_core.c
+++ b/trunk/drivers/acpi/processor_core.c
@@ -748,7 +748,7 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
return_VALUE(-ENODEV);
if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
- kobject_uevent(&(*device)->kobj, KOBJ_ONLINE);
+ kobject_hotplug(&(*device)->kobj, KOBJ_ONLINE);
}
return_VALUE(0);
}
@@ -788,13 +788,13 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
}
if (pr->id >= 0 && (pr->id < NR_CPUS)) {
- kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+ kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
break;
}
result = acpi_processor_start(device);
if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
- kobject_uevent(&device->kobj, KOBJ_ONLINE);
+ kobject_hotplug(&device->kobj, KOBJ_ONLINE);
} else {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Device [%s] failed to start\n",
@@ -818,7 +818,7 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
}
if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
- kobject_uevent(&device->kobj, KOBJ_OFFLINE);
+ kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c
index 0745d20afb8c..31218e1d2a18 100644
--- a/trunk/drivers/acpi/scan.c
+++ b/trunk/drivers/acpi/scan.c
@@ -78,7 +78,7 @@ static struct kobj_type ktype_acpi_ns = {
.release = acpi_device_release,
};
-static int namespace_uevent(struct kset *kset, struct kobject *kobj,
+static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
char **envp, int num_envp, char *buffer,
int buffer_size)
{
@@ -89,8 +89,8 @@ static int namespace_uevent(struct kset *kset, struct kobject *kobj,
if (!dev->driver)
return 0;
- if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
- "PHYSDEVDRIVER=%s", dev->driver->name))
+ if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
+ "PHYSDEVDRIVER=%s", dev->driver->name))
return -ENOMEM;
envp[i] = NULL;
@@ -98,8 +98,8 @@ static int namespace_uevent(struct kset *kset, struct kobject *kobj,
return 0;
}
-static struct kset_uevent_ops namespace_uevent_ops = {
- .uevent = &namespace_uevent,
+static struct kset_hotplug_ops namespace_hotplug_ops = {
+ .hotplug = &namespace_hotplug,
};
static struct kset acpi_namespace_kset = {
@@ -108,7 +108,7 @@ static struct kset acpi_namespace_kset = {
},
.subsys = &acpi_subsys,
.ktype = &ktype_acpi_ns,
- .uevent_ops = &namespace_uevent_ops,
+ .hotplug_ops = &namespace_hotplug_ops,
};
static void acpi_device_register(struct acpi_device *device,
@@ -347,7 +347,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
}
/* --------------------------------------------------------------------------
- ACPI sysfs device file support
+ ACPI hotplug sysfs device file support
-------------------------------------------------------------------------- */
static ssize_t acpi_eject_store(struct acpi_device *device,
const char *buf, size_t count);
diff --git a/trunk/drivers/base/Kconfig b/trunk/drivers/base/Kconfig
index f0eff3dac58d..934149c1512b 100644
--- a/trunk/drivers/base/Kconfig
+++ b/trunk/drivers/base/Kconfig
@@ -19,11 +19,11 @@ config PREVENT_FIRMWARE_BUILD
If unsure say Y here.
config FW_LOADER
- tristate "Userspace firmware loading support"
+ tristate "Hotplug firmware loading support"
select HOTPLUG
---help---
This option is provided for the case where no in-kernel-tree modules
- require userspace firmware loading support, but a module built outside
+ require hotplug firmware loading support, but a module built outside
the kernel tree does.
config DEBUG_DRIVER
diff --git a/trunk/drivers/base/bus.c b/trunk/drivers/base/bus.c
index 29f6af554e71..fa601b085eba 100644
--- a/trunk/drivers/base/bus.c
+++ b/trunk/drivers/base/bus.c
@@ -152,11 +152,7 @@ static ssize_t driver_unbind(struct device_driver *drv,
dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
if (dev && dev->driver == drv) {
- if (dev->parent) /* Needed for USB */
- down(&dev->parent->sem);
device_release_driver(dev);
- if (dev->parent)
- up(&dev->parent->sem);
err = count;
}
put_device(dev);
@@ -179,13 +175,9 @@ static ssize_t driver_bind(struct device_driver *drv,
dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
if (dev && dev->driver == NULL) {
- if (dev->parent) /* Needed for USB */
- down(&dev->parent->sem);
down(&dev->sem);
err = driver_probe_device(drv, dev);
up(&dev->sem);
- if (dev->parent)
- up(&dev->parent->sem);
}
put_device(dev);
put_bus(bus);
@@ -428,26 +420,6 @@ static void driver_remove_attrs(struct bus_type * bus, struct device_driver * dr
}
}
-#ifdef CONFIG_HOTPLUG
-/*
- * Thanks to drivers making their tables __devinit, we can't allow manual
- * bind and unbind from userspace unless CONFIG_HOTPLUG is enabled.
- */
-static void add_bind_files(struct device_driver *drv)
-{
- driver_create_file(drv, &driver_attr_unbind);
- driver_create_file(drv, &driver_attr_bind);
-}
-
-static void remove_bind_files(struct device_driver *drv)
-{
- driver_remove_file(drv, &driver_attr_bind);
- driver_remove_file(drv, &driver_attr_unbind);
-}
-#else
-static inline void add_bind_files(struct device_driver *drv) {}
-static inline void remove_bind_files(struct device_driver *drv) {}
-#endif
/**
* bus_add_driver - Add a driver to the bus.
@@ -477,7 +449,8 @@ int bus_add_driver(struct device_driver * drv)
module_add_driver(drv->owner, drv);
driver_add_attrs(bus, drv);
- add_bind_files(drv);
+ driver_create_file(drv, &driver_attr_unbind);
+ driver_create_file(drv, &driver_attr_bind);
}
return error;
}
@@ -495,7 +468,8 @@ int bus_add_driver(struct device_driver * drv)
void bus_remove_driver(struct device_driver * drv)
{
if (drv->bus) {
- remove_bind_files(drv);
+ driver_remove_file(drv, &driver_attr_bind);
+ driver_remove_file(drv, &driver_attr_unbind);
driver_remove_attrs(drv->bus, drv);
klist_remove(&drv->knode_bus);
pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
@@ -510,13 +484,8 @@ void bus_remove_driver(struct device_driver * drv)
/* Helper for bus_rescan_devices's iter */
static int bus_rescan_devices_helper(struct device *dev, void *data)
{
- if (!dev->driver) {
- if (dev->parent) /* Needed for USB */
- down(&dev->parent->sem);
+ if (!dev->driver)
device_attach(dev);
- if (dev->parent)
- up(&dev->parent->sem);
- }
return 0;
}
diff --git a/trunk/drivers/base/class.c b/trunk/drivers/base/class.c
index df7fdabd0730..db65fd0babe9 100644
--- a/trunk/drivers/base/class.c
+++ b/trunk/drivers/base/class.c
@@ -178,7 +178,7 @@ static void class_device_create_release(struct class_device *class_dev)
}
/* needed to allow these devices to have parent class devices */
-static int class_device_create_uevent(struct class_device *class_dev,
+static int class_device_create_hotplug(struct class_device *class_dev,
char **envp, int num_envp,
char *buffer, int buffer_size)
{
@@ -331,7 +331,7 @@ static struct kobj_type ktype_class_device = {
.release = class_dev_release,
};
-static int class_uevent_filter(struct kset *kset, struct kobject *kobj)
+static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
@@ -343,14 +343,14 @@ static int class_uevent_filter(struct kset *kset, struct kobject *kobj)
return 0;
}
-static const char *class_uevent_name(struct kset *kset, struct kobject *kobj)
+static const char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
{
struct class_device *class_dev = to_class_dev(kobj);
return class_dev->class->name;
}
-static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
+static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct class_device *class_dev = to_class_dev(kobj);
@@ -365,29 +365,29 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
struct device *dev = class_dev->dev;
char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
- &length, "PHYSDEVPATH=%s", path);
+ add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
+ &length, "PHYSDEVPATH=%s", path);
kfree(path);
if (dev->bus)
- add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "PHYSDEVBUS=%s", dev->bus->name);
+ add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PHYSDEVBUS=%s", dev->bus->name);
if (dev->driver)
- add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "PHYSDEVDRIVER=%s", dev->driver->name);
+ add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PHYSDEVDRIVER=%s", dev->driver->name);
}
if (MAJOR(class_dev->devt)) {
- add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "MAJOR=%u", MAJOR(class_dev->devt));
+ add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "MAJOR=%u", MAJOR(class_dev->devt));
- add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "MINOR=%u", MINOR(class_dev->devt));
+ add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "MINOR=%u", MINOR(class_dev->devt));
}
/* terminate, set to next free slot, shrink available space */
@@ -397,30 +397,30 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
buffer = &buffer[length];
buffer_size -= length;
- if (class_dev->uevent) {
+ if (class_dev->hotplug) {
/* have the class device specific function add its stuff */
- retval = class_dev->uevent(class_dev, envp, num_envp,
+ retval = class_dev->hotplug(class_dev, envp, num_envp,
buffer, buffer_size);
if (retval)
- pr_debug("class_dev->uevent() returned %d\n", retval);
- } else if (class_dev->class->uevent) {
+ pr_debug("class_dev->hotplug() returned %d\n", retval);
+ } else if (class_dev->class->hotplug) {
/* have the class specific function add its stuff */
- retval = class_dev->class->uevent(class_dev, envp, num_envp,
+ retval = class_dev->class->hotplug(class_dev, envp, num_envp,
buffer, buffer_size);
if (retval)
- pr_debug("class->uevent() returned %d\n", retval);
+ pr_debug("class->hotplug() returned %d\n", retval);
}
return retval;
}
-static struct kset_uevent_ops class_uevent_ops = {
- .filter = class_uevent_filter,
- .name = class_uevent_name,
- .uevent = class_uevent,
+static struct kset_hotplug_ops class_hotplug_ops = {
+ .filter = class_hotplug_filter,
+ .name = class_hotplug_name,
+ .hotplug = class_hotplug,
};
-static decl_subsys(class_obj, &ktype_class_device, &class_uevent_ops);
+static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops);
static int class_device_add_attrs(struct class_device * cd)
@@ -464,7 +464,7 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf)
static ssize_t store_uevent(struct class_device *class_dev,
const char *buf, size_t count)
{
- kobject_uevent(&class_dev->kobj, KOBJ_ADD);
+ kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
return count;
}
@@ -559,7 +559,7 @@ int class_device_add(struct class_device *class_dev)
class_name);
}
- kobject_uevent(&class_dev->kobj, KOBJ_ADD);
+ kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
/* notify any interfaces this device is now here */
if (parent_class) {
@@ -632,7 +632,7 @@ struct class_device *class_device_create(struct class *cls,
class_dev->class = cls;
class_dev->parent = parent;
class_dev->release = class_device_create_release;
- class_dev->uevent = class_device_create_uevent;
+ class_dev->hotplug = class_device_create_hotplug;
va_start(args, fmt);
vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
@@ -674,7 +674,7 @@ void class_device_del(struct class_device *class_dev)
class_device_remove_file(class_dev, class_dev->devt_attr);
class_device_remove_attrs(class_dev);
- kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
+ kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
kobject_del(&class_dev->kobj);
class_device_put(parent_device);
diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c
index fd8059920dbf..8615b42b517a 100644
--- a/trunk/drivers/base/core.c
+++ b/trunk/drivers/base/core.c
@@ -90,7 +90,7 @@ static struct kobj_type ktype_device = {
};
-static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
+static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
@@ -102,14 +102,14 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
return 0;
}
-static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj)
+static const char *dev_hotplug_name(struct kset *kset, struct kobject *kobj)
{
struct device *dev = to_dev(kobj);
return dev->bus->name;
}
-static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
+static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct device *dev = to_dev(kobj);
@@ -119,15 +119,15 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
/* add bus name of physical device */
if (dev->bus)
- add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "PHYSDEVBUS=%s", dev->bus->name);
+ add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PHYSDEVBUS=%s", dev->bus->name);
/* add driver name of physical device */
if (dev->driver)
- add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "PHYSDEVDRIVER=%s", dev->driver->name);
+ add_hotplug_env_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PHYSDEVDRIVER=%s", dev->driver->name);
/* terminate, set to next free slot, shrink available space */
envp[i] = NULL;
@@ -136,11 +136,11 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
buffer = &buffer[length];
buffer_size -= length;
- if (dev->bus && dev->bus->uevent) {
+ if (dev->bus && dev->bus->hotplug) {
/* have the bus specific function add its stuff */
- retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
+ retval = dev->bus->hotplug (dev, envp, num_envp, buffer, buffer_size);
if (retval) {
- pr_debug ("%s - uevent() returned %d\n",
+ pr_debug ("%s - hotplug() returned %d\n",
__FUNCTION__, retval);
}
}
@@ -148,16 +148,16 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
return retval;
}
-static struct kset_uevent_ops device_uevent_ops = {
- .filter = dev_uevent_filter,
- .name = dev_uevent_name,
- .uevent = dev_uevent,
+static struct kset_hotplug_ops device_hotplug_ops = {
+ .filter = dev_hotplug_filter,
+ .name = dev_hotplug_name,
+ .hotplug = dev_hotplug,
};
static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- kobject_uevent(&dev->kobj, KOBJ_ADD);
+ kobject_hotplug(&dev->kobj, KOBJ_ADD);
return count;
}
@@ -165,7 +165,7 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
* device_subsys - structure to be registered with kobject core.
*/
-decl_subsys(devices, &ktype_device, &device_uevent_ops);
+decl_subsys(devices, &ktype_device, &device_hotplug_ops);
/**
@@ -274,7 +274,7 @@ int device_add(struct device *dev)
dev->uevent_attr.store = store_uevent;
device_create_file(dev, &dev->uevent_attr);
- kobject_uevent(&dev->kobj, KOBJ_ADD);
+ kobject_hotplug(&dev->kobj, KOBJ_ADD);
if ((error = device_pm_add(dev)))
goto PMError;
if ((error = bus_add_device(dev)))
@@ -291,7 +291,7 @@ int device_add(struct device *dev)
BusError:
device_pm_remove(dev);
PMError:
- kobject_uevent(&dev->kobj, KOBJ_REMOVE);
+ kobject_hotplug(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj);
Error:
if (parent)
@@ -374,7 +374,7 @@ void device_del(struct device * dev)
platform_notify_remove(dev);
bus_remove_device(dev);
device_pm_remove(dev);
- kobject_uevent(&dev->kobj, KOBJ_REMOVE);
+ kobject_hotplug(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj);
if (parent)
put_device(parent);
diff --git a/trunk/drivers/base/cpu.c b/trunk/drivers/base/cpu.c
index 281d26784d25..a95844790f7b 100644
--- a/trunk/drivers/base/cpu.c
+++ b/trunk/drivers/base/cpu.c
@@ -41,14 +41,14 @@ static ssize_t store_online(struct sys_device *dev, const char *buf,
case '0':
ret = cpu_down(cpu->sysdev.id);
if (!ret)
- kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
+ kobject_hotplug(&dev->kobj, KOBJ_OFFLINE);
break;
case '1':
ret = smp_prepare_cpu(cpu->sysdev.id);
if (!ret)
ret = cpu_up(cpu->sysdev.id);
if (!ret)
- kobject_uevent(&dev->kobj, KOBJ_ONLINE);
+ kobject_hotplug(&dev->kobj, KOBJ_ONLINE);
break;
default:
ret = -EINVAL;
diff --git a/trunk/drivers/base/dd.c b/trunk/drivers/base/dd.c
index 2b905016664d..3b419c9a1e7e 100644
--- a/trunk/drivers/base/dd.c
+++ b/trunk/drivers/base/dd.c
@@ -65,8 +65,7 @@ void device_bind_driver(struct device * dev)
* This function returns 1 if a match is found, an error if one
* occurs (that is not -ENODEV or -ENXIO), and 0 otherwise.
*
- * This function must be called with @dev->sem held. When called
- * for a USB interface, @dev->parent->sem must be held as well.
+ * This function must be called with @dev->sem held.
*/
int driver_probe_device(struct device_driver * drv, struct device * dev)
{
@@ -124,8 +123,6 @@ static int __device_attach(struct device_driver * drv, void * data)
*
* Returns 1 if the device was bound to a driver;
* 0 if no matching device was found; error code otherwise.
- *
- * When called for a USB interface, @dev->parent->sem must be held.
*/
int device_attach(struct device * dev)
{
@@ -155,14 +152,10 @@ static int __driver_attach(struct device * dev, void * data)
* is an error.
*/
- if (dev->parent) /* Needed for USB */
- down(&dev->parent->sem);
down(&dev->sem);
if (!dev->driver)
driver_probe_device(drv, dev);
up(&dev->sem);
- if (dev->parent)
- up(&dev->parent->sem);
return 0;
}
@@ -188,8 +181,6 @@ void driver_attach(struct device_driver * drv)
* Manually detach device from driver.
*
* __device_release_driver() must be called with @dev->sem held.
- * When called for a USB interface, @dev->parent->sem must be held
- * as well.
*/
static void __device_release_driver(struct device * dev)
@@ -242,14 +233,10 @@ void driver_detach(struct device_driver * drv)
get_device(dev);
spin_unlock(&drv->klist_devices.k_lock);
- if (dev->parent) /* Needed for USB */
- down(&dev->parent->sem);
down(&dev->sem);
if (dev->driver == drv)
__device_release_driver(dev);
up(&dev->sem);
- if (dev->parent)
- up(&dev->parent->sem);
put_device(dev);
}
}
diff --git a/trunk/drivers/base/firmware_class.c b/trunk/drivers/base/firmware_class.c
index 5b3d5e9ddcb6..59dacb6552c0 100644
--- a/trunk/drivers/base/firmware_class.c
+++ b/trunk/drivers/base/firmware_class.c
@@ -85,17 +85,17 @@ firmware_timeout_store(struct class *class, const char *buf, size_t count)
static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store);
static void fw_class_dev_release(struct class_device *class_dev);
-int firmware_class_uevent(struct class_device *dev, char **envp,
+int firmware_class_hotplug(struct class_device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
static struct class firmware_class = {
.name = "firmware",
- .uevent = firmware_class_uevent,
+ .hotplug = firmware_class_hotplug,
.release = fw_class_dev_release,
};
int
-firmware_class_uevent(struct class_device *class_dev, char **envp,
+firmware_class_hotplug(struct class_device *class_dev, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct firmware_priv *fw_priv = class_get_devdata(class_dev);
@@ -104,12 +104,13 @@ firmware_class_uevent(struct class_device *class_dev, char **envp,
if (!test_bit(FW_STATUS_READY, &fw_priv->status))
return -ENODEV;
- if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
- "FIRMWARE=%s", fw_priv->fw_id))
+ if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
+ "FIRMWARE=%s", fw_priv->fw_id))
return -ENOMEM;
- if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
- "TIMEOUT=%i", loading_timeout))
+ if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
+ "TIMEOUT=%i", loading_timeout))
return -ENOMEM;
+
envp[i] = NULL;
return 0;
@@ -351,7 +352,7 @@ fw_register_class_device(struct class_device **class_dev_p,
static int
fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
- const char *fw_name, struct device *device, int uevent)
+ const char *fw_name, struct device *device, int hotplug)
{
struct class_device *class_dev;
struct firmware_priv *fw_priv;
@@ -383,7 +384,7 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
goto error_unreg;
}
- if (uevent)
+ if (hotplug)
set_bit(FW_STATUS_READY, &fw_priv->status);
else
set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status);
@@ -398,7 +399,7 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
static int
_request_firmware(const struct firmware **firmware_p, const char *name,
- struct device *device, int uevent)
+ struct device *device, int hotplug)
{
struct class_device *class_dev;
struct firmware_priv *fw_priv;
@@ -417,19 +418,19 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
}
retval = fw_setup_class_device(firmware, &class_dev, name, device,
- uevent);
+ hotplug);
if (retval)
goto error_kfree_fw;
fw_priv = class_get_devdata(class_dev);
- if (uevent) {
+ if (hotplug) {
if (loading_timeout > 0) {
fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
add_timer(&fw_priv->timeout);
}
- kobject_uevent(&class_dev->kobj, KOBJ_ADD);
+ kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
wait_for_completion(&fw_priv->completion);
set_bit(FW_STATUS_DONE, &fw_priv->status);
del_timer_sync(&fw_priv->timeout);
@@ -455,7 +456,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
}
/**
- * request_firmware: - send firmware request and wait for it
+ * request_firmware: - request firmware to hotplug and wait for it
* @firmware_p: pointer to firmware image
* @name: name of firmware file
* @device: device for which firmware is being loaded
@@ -465,7 +466,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
*
* Should be called from user context where sleeping is allowed.
*
- * @name will be used as $FIRMWARE in the uevent environment and
+ * @name will be used as $FIRMWARE in the hotplug environment and
* should be distinctive enough not to be confused with any other
* firmware image for this or any other device.
**/
@@ -473,8 +474,8 @@ int
request_firmware(const struct firmware **firmware_p, const char *name,
struct device *device)
{
- int uevent = 1;
- return _request_firmware(firmware_p, name, device, uevent);
+ int hotplug = 1;
+ return _request_firmware(firmware_p, name, device, hotplug);
}
/**
@@ -517,7 +518,7 @@ struct firmware_work {
struct device *device;
void *context;
void (*cont)(const struct firmware *fw, void *context);
- int uevent;
+ int hotplug;
};
static int
@@ -532,7 +533,7 @@ request_firmware_work_func(void *arg)
}
daemonize("%s/%s", "firmware", fw_work->name);
ret = _request_firmware(&fw, fw_work->name, fw_work->device,
- fw_work->uevent);
+ fw_work->hotplug);
if (ret < 0)
fw_work->cont(NULL, fw_work->context);
else {
@@ -547,7 +548,7 @@ request_firmware_work_func(void *arg)
/**
* request_firmware_nowait: asynchronous version of request_firmware
* @module: module requesting the firmware
- * @uevent: sends uevent to copy the firmware image if this flag
+ * @hotplug: invokes hotplug event to copy the firmware image if this flag
* is non-zero else the firmware copy must be done manually.
* @name: name of firmware file
* @device: device for which firmware is being loaded
@@ -561,7 +562,7 @@ request_firmware_work_func(void *arg)
**/
int
request_firmware_nowait(
- struct module *module, int uevent,
+ struct module *module, int hotplug,
const char *name, struct device *device, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
@@ -582,7 +583,7 @@ request_firmware_nowait(
.device = device,
.context = context,
.cont = cont,
- .uevent = uevent,
+ .hotplug = hotplug,
};
ret = kernel_thread(request_firmware_work_func, fw_work,
diff --git a/trunk/drivers/base/memory.c b/trunk/drivers/base/memory.c
index 7e1d077874df..bc3ca6a656b2 100644
--- a/trunk/drivers/base/memory.c
+++ b/trunk/drivers/base/memory.c
@@ -29,12 +29,12 @@ static struct sysdev_class memory_sysdev_class = {
set_kset_name(MEMORY_CLASS_NAME),
};
-static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj)
+static char *memory_hotplug_name(struct kset *kset, struct kobject *kobj)
{
return MEMORY_CLASS_NAME;
}
-static int memory_uevent(struct kset *kset, struct kobject *kobj, char **envp,
+static int memory_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size)
{
int retval = 0;
@@ -42,9 +42,9 @@ static int memory_uevent(struct kset *kset, struct kobject *kobj, char **envp,
return retval;
}
-static struct kset_uevent_ops memory_uevent_ops = {
- .name = memory_uevent_name,
- .uevent = memory_uevent,
+static struct kset_hotplug_ops memory_hotplug_ops = {
+ .name = memory_hotplug_name,
+ .hotplug = memory_hotplug,
};
static struct notifier_block *memory_chain;
@@ -431,7 +431,7 @@ int __init memory_dev_init(void)
unsigned int i;
int ret;
- memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops;
+ memory_sysdev_class.kset.hotplug_ops = &memory_hotplug_ops;
ret = sysdev_class_register(&memory_sysdev_class);
/*
diff --git a/trunk/drivers/base/platform.c b/trunk/drivers/base/platform.c
index 0f81731bdfa8..8827dafba945 100644
--- a/trunk/drivers/base/platform.c
+++ b/trunk/drivers/base/platform.c
@@ -25,7 +25,6 @@
struct device platform_bus = {
.bus_id = "platform",
};
-EXPORT_SYMBOL_GPL(platform_bus);
/**
* platform_get_resource - get a resource for a device
@@ -50,7 +49,6 @@ platform_get_resource(struct platform_device *dev, unsigned int type,
}
return NULL;
}
-EXPORT_SYMBOL_GPL(platform_get_resource);
/**
* platform_get_irq - get an IRQ for a device
@@ -63,7 +61,6 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
return r ? r->start : 0;
}
-EXPORT_SYMBOL_GPL(platform_get_irq);
/**
* platform_get_resource_byname - get a resource for a device by name
@@ -87,7 +84,6 @@ platform_get_resource_byname(struct platform_device *dev, unsigned int type,
}
return NULL;
}
-EXPORT_SYMBOL_GPL(platform_get_resource_byname);
/**
* platform_get_irq - get an IRQ for a device
@@ -100,7 +96,6 @@ int platform_get_irq_byname(struct platform_device *dev, char *name)
return r ? r->start : 0;
}
-EXPORT_SYMBOL_GPL(platform_get_irq_byname);
/**
* platform_add_devices - add a numbers of platform devices
@@ -122,7 +117,6 @@ int platform_add_devices(struct platform_device **devs, int num)
return ret;
}
-EXPORT_SYMBOL_GPL(platform_add_devices);
struct platform_object {
struct platform_device pdev;
@@ -174,7 +168,7 @@ struct platform_device *platform_device_alloc(const char *name, unsigned int id)
pa->pdev.dev.release = platform_device_release;
}
- return pa ? &pa->pdev : NULL;
+ return pa ? &pa->pdev : NULL;
}
EXPORT_SYMBOL_GPL(platform_device_alloc);
@@ -263,7 +257,7 @@ int platform_device_add(struct platform_device *pdev)
p = &ioport_resource;
}
- if (p && insert_resource(p, r)) {
+ if (p && request_resource(p, r)) {
printk(KERN_ERR
"%s: failed to claim resource %d\n",
pdev->dev.bus_id, i);
@@ -288,13 +282,24 @@ int platform_device_add(struct platform_device *pdev)
EXPORT_SYMBOL_GPL(platform_device_add);
/**
- * platform_device_del - remove a platform-level device
+ * platform_device_register - add a platform-level device
+ * @pdev: platform device we're adding
+ *
+ */
+int platform_device_register(struct platform_device * pdev)
+{
+ device_initialize(&pdev->dev);
+ return platform_device_add(pdev);
+}
+
+/**
+ * platform_device_unregister - remove a platform-level device
* @pdev: platform device we're removing
*
* Note that this function will also release all memory- and port-based
* resources owned by the device (@dev->resource).
*/
-void platform_device_del(struct platform_device *pdev)
+void platform_device_unregister(struct platform_device * pdev)
{
int i;
@@ -305,37 +310,9 @@ void platform_device_del(struct platform_device *pdev)
release_resource(r);
}
- device_del(&pdev->dev);
+ device_unregister(&pdev->dev);
}
}
-EXPORT_SYMBOL_GPL(platform_device_del);
-
-/**
- * platform_device_register - add a platform-level device
- * @pdev: platform device we're adding
- *
- */
-int platform_device_register(struct platform_device * pdev)
-{
- device_initialize(&pdev->dev);
- return platform_device_add(pdev);
-}
-EXPORT_SYMBOL_GPL(platform_device_register);
-
-/**
- * platform_device_unregister - unregister a platform-level device
- * @pdev: platform device we're unregistering
- *
- * Unregistration is done in 2 steps. Fisrt we release all resources
- * and remove it from the sybsystem, then we drop reference count by
- * calling platform_device_put().
- */
-void platform_device_unregister(struct platform_device * pdev)
-{
- platform_device_del(pdev);
- platform_device_put(pdev);
-}
-EXPORT_SYMBOL_GPL(platform_device_unregister);
/**
* platform_device_register_simple
@@ -378,7 +355,6 @@ struct platform_device *platform_device_register_simple(char *name, unsigned int
platform_device_put(pdev);
return ERR_PTR(retval);
}
-EXPORT_SYMBOL_GPL(platform_device_register_simple);
static int platform_drv_probe(struct device *_dev)
{
@@ -500,7 +476,6 @@ struct bus_type platform_bus_type = {
.suspend = platform_suspend,
.resume = platform_resume,
};
-EXPORT_SYMBOL_GPL(platform_bus_type);
int __init platform_bus_init(void)
{
@@ -529,3 +504,14 @@ u64 dma_get_required_mask(struct device *dev)
}
EXPORT_SYMBOL_GPL(dma_get_required_mask);
#endif
+
+EXPORT_SYMBOL_GPL(platform_bus);
+EXPORT_SYMBOL_GPL(platform_bus_type);
+EXPORT_SYMBOL_GPL(platform_add_devices);
+EXPORT_SYMBOL_GPL(platform_device_register);
+EXPORT_SYMBOL_GPL(platform_device_register_simple);
+EXPORT_SYMBOL_GPL(platform_device_unregister);
+EXPORT_SYMBOL_GPL(platform_get_irq);
+EXPORT_SYMBOL_GPL(platform_get_resource);
+EXPORT_SYMBOL_GPL(platform_get_irq_byname);
+EXPORT_SYMBOL_GPL(platform_get_resource_byname);
diff --git a/trunk/drivers/base/power/runtime.c b/trunk/drivers/base/power/runtime.c
index 96370ec1d673..adbc3148c039 100644
--- a/trunk/drivers/base/power/runtime.c
+++ b/trunk/drivers/base/power/runtime.c
@@ -62,10 +62,8 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state)
up(&dpm_sem);
return error;
}
-EXPORT_SYMBOL(dpm_runtime_suspend);
-#if 0
/**
* dpm_set_power_state - Update power_state field.
* @dev: Device.
@@ -82,4 +80,3 @@ void dpm_set_power_state(struct device * dev, pm_message_t state)
dev->power.power_state = state;
up(&dpm_sem);
}
-#endif /* 0 */
diff --git a/trunk/drivers/block/Kconfig b/trunk/drivers/block/Kconfig
index c4b9d2adfc08..7b1cd93892be 100644
--- a/trunk/drivers/block/Kconfig
+++ b/trunk/drivers/block/Kconfig
@@ -358,8 +358,7 @@ config BLK_DEV_UB
This driver supports certain USB attached storage devices
such as flash keys.
- If you enable this driver, it is recommended to avoid conflicts
- with usb-storage by enabling USB_LIBUSUAL.
+ Warning: Enabling this cripples the usb-storage driver.
If unsure, say N.
diff --git a/trunk/drivers/block/ub.c b/trunk/drivers/block/ub.c
index 10740a065088..bfb23d543ff7 100644
--- a/trunk/drivers/block/ub.c
+++ b/trunk/drivers/block/ub.c
@@ -9,6 +9,7 @@
*
* TODO (sorted by decreasing priority)
* -- Kill first_open (Al Viro fixed the block layer now)
+ * -- Do resets with usb_device_reset (needs a thread context, use khubd)
* -- set readonly flag for CDs, set removable flag for CF readers
* -- do inquiry and verify we got a disk and not a tape (for LUN mismatch)
* -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
@@ -28,7 +29,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -106,6 +106,16 @@
* +--------+
*/
+/*
+ * Definitions which have to be scattered once we understand the layout better.
+ */
+
+/* Transport (despite PR in the name) */
+#define US_PR_BULK 0x50 /* bulk only */
+
+/* Protocol */
+#define US_SC_SCSI 0x06 /* Transparent */
+
/*
* This many LUNs per USB device.
* Every one of them takes a host, see UB_MAX_HOSTS.
@@ -115,7 +125,7 @@
/*
*/
-#define UB_PARTS_PER_LUN 8
+#define UB_MINORS_PER_MAJOR 8
#define UB_MAX_CDB_SIZE 16 /* Corresponds to Bulk */
@@ -235,13 +245,6 @@ struct ub_scsi_cmd {
void *back;
};
-struct ub_request {
- struct request *rq;
- unsigned int current_try;
- unsigned int nsg; /* sgv[nsg] */
- struct scatterlist sgv[UB_MAX_REQ_SG];
-};
-
/*
*/
struct ub_capacity {
@@ -337,8 +340,6 @@ struct ub_lun {
int readonly;
int first_open; /* Kludge. See ub_bd_open. */
- struct ub_request urq;
-
/* Use Ingo's mempool if or when we have more than one command. */
/*
* Currently we never need more than one command for the whole device.
@@ -359,7 +360,6 @@ struct ub_dev {
atomic_t poison; /* The USB device is disconnected */
int openc; /* protected by ub_lock! */
/* kref is too implicit for our taste */
- int reset; /* Reset is running */
unsigned int tagcnt;
char name[12];
struct usb_device *dev;
@@ -387,9 +387,6 @@ struct ub_dev {
struct bulk_cs_wrap work_bcs;
struct usb_ctrlrequest work_cr;
- struct work_struct reset_work;
- wait_queue_head_t reset_wait;
-
int sg_stat[6];
struct ub_scsi_trace tr;
};
@@ -398,14 +395,12 @@ struct ub_dev {
*/
static void ub_cleanup(struct ub_dev *sc);
static int ub_request_fn_1(struct ub_lun *lun, struct request *rq);
-static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
- struct ub_scsi_cmd *cmd, struct ub_request *urq);
-static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
- struct ub_scsi_cmd *cmd, struct ub_request *urq);
+static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
+ struct ub_scsi_cmd *cmd, struct request *rq);
+static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
+ struct ub_scsi_cmd *cmd, struct request *rq);
static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static void ub_end_rq(struct request *rq, int uptodate);
-static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
- struct ub_request *urq, struct ub_scsi_cmd *cmd);
static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static void ub_urb_complete(struct urb *urb, struct pt_regs *pt);
static void ub_scsi_action(unsigned long _dev);
@@ -420,8 +415,6 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
int stalled_pipe);
static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd);
-static void ub_reset_enter(struct ub_dev *sc);
-static void ub_reset_task(void *arg);
static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun);
static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
struct ub_capacity *ret);
@@ -429,18 +422,13 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum);
/*
*/
-#ifdef CONFIG_USB_LIBUSUAL
-
-#define ub_usb_ids storage_usb_ids
-#else
-
static struct usb_device_id ub_usb_ids[] = {
+ // { USB_DEVICE_VER(0x0781, 0x0002, 0x0009, 0x0009) }, /* SDDR-31 */
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
{ }
};
MODULE_DEVICE_TABLE(usb, ub_usb_ids);
-#endif /* CONFIG_USB_LIBUSUAL */
/*
* Find me a way to identify "next free minor" for add_disk(),
@@ -533,9 +521,6 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr,
cnt = 0;
spin_lock_irqsave(&sc->lock, flags);
- cnt += sprintf(page + cnt,
- "poison %d reset %d\n",
- atomic_read(&sc->poison), sc->reset);
cnt += sprintf(page + cnt,
"qlen %d qmax %d\n",
sc->cmd_queue.qlen, sc->cmd_queue.qmax);
@@ -785,8 +770,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
{
struct ub_dev *sc = lun->udev;
struct ub_scsi_cmd *cmd;
- struct ub_request *urq;
- int n_elem;
+ int rc;
if (atomic_read(&sc->poison) || lun->changed) {
blkdev_dequeue_request(rq);
@@ -794,70 +778,65 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
return 0;
}
- if (lun->urq.rq != NULL)
- return -1;
if ((cmd = ub_get_cmd(lun)) == NULL)
return -1;
memset(cmd, 0, sizeof(struct ub_scsi_cmd));
blkdev_dequeue_request(rq);
-
- urq = &lun->urq;
- memset(urq, 0, sizeof(struct ub_request));
- urq->rq = rq;
-
- /*
- * get scatterlist from block layer
- */
- n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]);
- if (n_elem < 0) {
- printk(KERN_INFO "%s: failed request map (%d)\n",
- lun->name, n_elem); /* P3 */
- goto drop;
- }
- if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */
- printk(KERN_WARNING "%s: request with %d segments\n",
- lun->name, n_elem);
- goto drop;
- }
- urq->nsg = n_elem;
- sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
-
if (blk_pc_request(rq)) {
- ub_cmd_build_packet(sc, lun, cmd, urq);
+ rc = ub_cmd_build_packet(sc, lun, cmd, rq);
} else {
- ub_cmd_build_block(sc, lun, cmd, urq);
+ rc = ub_cmd_build_block(sc, lun, cmd, rq);
+ }
+ if (rc != 0) {
+ ub_put_cmd(lun, cmd);
+ ub_end_rq(rq, 0);
+ return 0;
}
cmd->state = UB_CMDST_INIT;
cmd->lun = lun;
cmd->done = ub_rw_cmd_done;
- cmd->back = urq;
+ cmd->back = rq;
cmd->tag = sc->tagcnt++;
- if (ub_submit_scsi(sc, cmd) != 0)
- goto drop;
-
- return 0;
+ if (ub_submit_scsi(sc, cmd) != 0) {
+ ub_put_cmd(lun, cmd);
+ ub_end_rq(rq, 0);
+ return 0;
+ }
-drop:
- ub_put_cmd(lun, cmd);
- ub_end_rq(rq, 0);
return 0;
}
-static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
- struct ub_scsi_cmd *cmd, struct ub_request *urq)
+static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
+ struct ub_scsi_cmd *cmd, struct request *rq)
{
- struct request *rq = urq->rq;
+ int ub_dir;
+ int n_elem;
unsigned int block, nblks;
if (rq_data_dir(rq) == WRITE)
- cmd->dir = UB_DIR_WRITE;
+ ub_dir = UB_DIR_WRITE;
else
- cmd->dir = UB_DIR_READ;
+ ub_dir = UB_DIR_READ;
+ cmd->dir = ub_dir;
- cmd->nsg = urq->nsg;
- memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg);
+ /*
+ * get scatterlist from block layer
+ */
+ n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
+ if (n_elem <= 0) {
+ printk(KERN_INFO "%s: failed request map (%d)\n",
+ sc->name, n_elem); /* P3 */
+ return -1; /* request with no s/g entries? */
+ }
+ if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */
+ printk(KERN_WARNING "%s: request with %d segments\n",
+ sc->name, n_elem);
+ return -1;
+ }
+ cmd->nsg = n_elem;
+ sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
/*
* build the command
@@ -868,7 +847,7 @@ static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
block = rq->sector >> lun->capacity.bshift;
nblks = rq->nr_sectors >> lun->capacity.bshift;
- cmd->cdb[0] = (cmd->dir == UB_DIR_READ)? READ_10: WRITE_10;
+ cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10;
/* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */
cmd->cdb[2] = block >> 24;
cmd->cdb[3] = block >> 16;
@@ -879,12 +858,14 @@ static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
cmd->cdb_len = 10;
cmd->len = rq->nr_sectors * 512;
+
+ return 0;
}
-static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
- struct ub_scsi_cmd *cmd, struct ub_request *urq)
+static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
+ struct ub_scsi_cmd *cmd, struct request *rq)
{
- struct request *rq = urq->rq;
+ int n_elem;
if (rq->data_len == 0) {
cmd->dir = UB_DIR_NONE;
@@ -893,26 +874,40 @@ static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
cmd->dir = UB_DIR_WRITE;
else
cmd->dir = UB_DIR_READ;
+
}
- cmd->nsg = urq->nsg;
- memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg);
+ /*
+ * get scatterlist from block layer
+ */
+ n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
+ if (n_elem < 0) {
+ printk(KERN_INFO "%s: failed request map (%d)\n",
+ sc->name, n_elem); /* P3 */
+ return -1;
+ }
+ if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */
+ printk(KERN_WARNING "%s: request with %d segments\n",
+ sc->name, n_elem);
+ return -1;
+ }
+ cmd->nsg = n_elem;
+ sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
cmd->cdb_len = rq->cmd_len;
cmd->len = rq->data_len;
+
+ return 0;
}
static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
{
+ struct request *rq = cmd->back;
struct ub_lun *lun = cmd->lun;
- struct ub_request *urq = cmd->back;
- struct request *rq;
int uptodate;
- rq = urq->rq;
-
if (cmd->error == 0) {
uptodate = 1;
@@ -933,16 +928,9 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
rq->errors = SAM_STAT_CHECK_CONDITION;
else
rq->errors = DID_ERROR << 16;
- } else {
- if (cmd->error == -EIO) {
- if (ub_rw_cmd_retry(sc, lun, urq, cmd) == 0)
- return;
- }
}
}
- urq->rq = NULL;
-
ub_put_cmd(lun, cmd);
ub_end_rq(rq, uptodate);
blk_start_queue(lun->disk->queue);
@@ -950,43 +938,11 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
static void ub_end_rq(struct request *rq, int uptodate)
{
- end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
- end_that_request_last(rq);
-}
-
-static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
- struct ub_request *urq, struct ub_scsi_cmd *cmd)
-{
-
- if (atomic_read(&sc->poison))
- return -ENXIO;
-
- ub_reset_enter(sc);
-
- if (urq->current_try >= 3)
- return -EIO;
- urq->current_try++;
- /* P3 */ printk("%s: dir %c len/act %d/%d "
- "[sense %x %02x %02x] retry %d\n",
- sc->name, UB_DIR_CHAR(cmd->dir), cmd->len, cmd->act_len,
- cmd->key, cmd->asc, cmd->ascq, urq->current_try);
-
- memset(cmd, 0, sizeof(struct ub_scsi_cmd));
- ub_cmd_build_block(sc, lun, cmd, urq);
-
- cmd->state = UB_CMDST_INIT;
- cmd->lun = lun;
- cmd->done = ub_rw_cmd_done;
- cmd->back = urq;
-
- cmd->tag = sc->tagcnt++;
+ int rc;
-#if 0 /* Wasteful */
- return ub_submit_scsi(sc, cmd);
-#else
- ub_cmdq_add(sc, cmd);
- return 0;
-#endif
+ rc = end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
+ // assert(rc == 0);
+ end_that_request_last(rq);
}
/*
@@ -1119,7 +1075,7 @@ static void ub_scsi_dispatch(struct ub_dev *sc)
struct ub_scsi_cmd *cmd;
int rc;
- while (!sc->reset && (cmd = ub_cmdq_peek(sc)) != NULL) {
+ while ((cmd = ub_cmdq_peek(sc)) != NULL) {
if (cmd->state == UB_CMDST_DONE) {
ub_cmdq_pop(sc);
(*cmd->done)(sc, cmd);
@@ -1142,12 +1098,11 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
{
struct urb *urb = &sc->work_urb;
struct bulk_cs_wrap *bcs;
- int len;
int rc;
if (atomic_read(&sc->poison)) {
- ub_state_done(sc, cmd, -ENODEV);
- return;
+ /* A little too simplistic, I feel... */
+ goto Bad_End;
}
if (cmd->state == UB_CMDST_CLEAR) {
@@ -1155,6 +1110,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
/*
* STALL while clearning STALL.
* The control pipe clears itself - nothing to do.
+ * XXX Might try to reset the device here and retry.
*/
printk(KERN_NOTICE "%s: stall on control pipe\n",
sc->name);
@@ -1173,6 +1129,11 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
} else if (cmd->state == UB_CMDST_CLR2STS) {
if (urb->status == -EPIPE) {
+ /*
+ * STALL while clearning STALL.
+ * The control pipe clears itself - nothing to do.
+ * XXX Might try to reset the device here and retry.
+ */
printk(KERN_NOTICE "%s: stall on control pipe\n",
sc->name);
goto Bad_End;
@@ -1190,6 +1151,11 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
} else if (cmd->state == UB_CMDST_CLRRS) {
if (urb->status == -EPIPE) {
+ /*
+ * STALL while clearning STALL.
+ * The control pipe clears itself - nothing to do.
+ * XXX Might try to reset the device here and retry.
+ */
printk(KERN_NOTICE "%s: stall on control pipe\n",
sc->name);
goto Bad_End;
@@ -1206,12 +1172,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
ub_state_stat_counted(sc, cmd);
} else if (cmd->state == UB_CMDST_CMD) {
- switch (urb->status) {
- case 0:
- break;
- case -EOVERFLOW:
- goto Bad_End;
- case -EPIPE:
+ if (urb->status == -EPIPE) {
rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
if (rc != 0) {
printk(KERN_NOTICE "%s: "
@@ -1221,20 +1182,17 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
* This is typically ENOMEM or some other such shit.
* Retrying is pointless. Just do Bad End on it...
*/
- ub_state_done(sc, cmd, rc);
- return;
+ goto Bad_End;
}
cmd->state = UB_CMDST_CLEAR;
ub_cmdtr_state(sc, cmd);
return;
- case -ESHUTDOWN: /* unplug */
- case -EILSEQ: /* unplug timeout on uhci */
- ub_state_done(sc, cmd, -ENODEV);
- return;
- default:
+ }
+ if (urb->status != 0) {
goto Bad_End;
}
if (urb->actual_length != US_BULK_CB_WRAP_LEN) {
+ /* XXX Must do reset here to unconfuse the device */
goto Bad_End;
}
@@ -1253,8 +1211,11 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
printk(KERN_NOTICE "%s: "
"unable to submit clear (%d)\n",
sc->name, rc);
- ub_state_done(sc, cmd, rc);
- return;
+ /*
+ * This is typically ENOMEM or some other such shit.
+ * Retrying is pointless. Just do Bad End on it...
+ */
+ goto Bad_End;
}
cmd->state = UB_CMDST_CLR2STS;
ub_cmdtr_state(sc, cmd);
@@ -1263,50 +1224,14 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
if (urb->status == -EOVERFLOW) {
/*
* A babble? Failure, but we must transfer CSW now.
+ * XXX This is going to end in perpetual babble. Reset.
*/
cmd->error = -EOVERFLOW; /* A cheap trick... */
ub_state_stat(sc, cmd);
return;
}
-
- if (cmd->dir == UB_DIR_WRITE) {
- /*
- * Do not continue writes in case of a failure.
- * Doing so would cause sectors to be mixed up,
- * which is worse than sectors lost.
- *
- * We must try to read the CSW, or many devices
- * get confused.
- */
- len = urb->actual_length;
- if (urb->status != 0 ||
- len != cmd->sgv[cmd->current_sg].length) {
- cmd->act_len += len;
- ub_cmdtr_act_len(sc, cmd);
-
- cmd->error = -EIO;
- ub_state_stat(sc, cmd);
- return;
- }
-
- } else {
- /*
- * If an error occurs on read, we record it, and
- * continue to fetch data in order to avoid bubble.
- *
- * As a small shortcut, we stop if we detect that
- * a CSW mixed into data.
- */
- if (urb->status != 0)
- cmd->error = -EIO;
-
- len = urb->actual_length;
- if (urb->status != 0 ||
- len != cmd->sgv[cmd->current_sg].length) {
- if ((len & 0x1FF) == US_BULK_CS_WRAP_LEN)
- goto Bad_End;
- }
- }
+ if (urb->status != 0)
+ goto Bad_End;
cmd->act_len += urb->actual_length;
ub_cmdtr_act_len(sc, cmd);
@@ -1324,8 +1249,11 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
printk(KERN_NOTICE "%s: "
"unable to submit clear (%d)\n",
sc->name, rc);
- ub_state_done(sc, cmd, rc);
- return;
+ /*
+ * This is typically ENOMEM or some other such shit.
+ * Retrying is pointless. Just do Bad End on it...
+ */
+ goto Bad_End;
}
/*
@@ -1338,8 +1266,14 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
ub_cmdtr_state(sc, cmd);
return;
}
-
- /* Catch everything, including -EOVERFLOW and other nasties. */
+ if (urb->status == -EOVERFLOW) {
+ /*
+ * XXX We are screwed here. Retrying is pointless,
+ * because the pipelined data will not get in until
+ * we read with a big enough buffer. We must reset XXX.
+ */
+ goto Bad_End;
+ }
if (urb->status != 0)
goto Bad_End;
@@ -1385,15 +1319,15 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
return;
}
- len = le32_to_cpu(bcs->Residue);
- if (len != cmd->len - cmd->act_len) {
+ rc = le32_to_cpu(bcs->Residue);
+ if (rc != cmd->len - cmd->act_len) {
/*
* It is all right to transfer less, the caller has
* to check. But it's not all right if the device
* counts disagree with our counts.
*/
/* P3 */ printk("%s: resid %d len %d act %d\n",
- sc->name, len, cmd->len, cmd->act_len);
+ sc->name, rc, cmd->len, cmd->act_len);
goto Bad_End;
}
@@ -1404,13 +1338,13 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
ub_state_sense(sc, cmd);
return;
case US_BULK_STAT_PHASE:
+ /* XXX We must reset the transport here */
/* P3 */ printk("%s: status PHASE\n", sc->name);
goto Bad_End;
default:
printk(KERN_INFO "%s: unknown CSW status 0x%x\n",
sc->name, bcs->Status);
- ub_state_done(sc, cmd, -EINVAL);
- return;
+ goto Bad_End;
}
/* Not zeroing error to preserve a babble indicator */
@@ -1430,8 +1364,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
printk(KERN_WARNING "%s: "
"wrong command state %d\n",
sc->name, cmd->state);
- ub_state_done(sc, cmd, -EINVAL);
- return;
+ goto Bad_End;
}
return;
@@ -1678,93 +1611,6 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
ub_scsi_urb_compl(sc, cmd);
}
-/*
- * Reset management
- */
-
-static void ub_reset_enter(struct ub_dev *sc)
-{
-
- if (sc->reset) {
- /* This happens often on multi-LUN devices. */
- return;
- }
- sc->reset = 1;
-
-#if 0 /* Not needed because the disconnect waits for us. */
- unsigned long flags;
- spin_lock_irqsave(&ub_lock, flags);
- sc->openc++;
- spin_unlock_irqrestore(&ub_lock, flags);
-#endif
-
-#if 0 /* We let them stop themselves. */
- struct list_head *p;
- struct ub_lun *lun;
- list_for_each(p, &sc->luns) {
- lun = list_entry(p, struct ub_lun, link);
- blk_stop_queue(lun->disk->queue);
- }
-#endif
-
- schedule_work(&sc->reset_work);
-}
-
-static void ub_reset_task(void *arg)
-{
- struct ub_dev *sc = arg;
- unsigned long flags;
- struct list_head *p;
- struct ub_lun *lun;
- int lkr, rc;
-
- if (!sc->reset) {
- printk(KERN_WARNING "%s: Running reset unrequested\n",
- sc->name);
- return;
- }
-
- if (atomic_read(&sc->poison)) {
- printk(KERN_NOTICE "%s: Not resetting disconnected device\n",
- sc->name); /* P3 This floods. Remove soon. XXX */
- } else if (sc->dev->actconfig->desc.bNumInterfaces != 1) {
- printk(KERN_NOTICE "%s: Not resetting multi-interface device\n",
- sc->name); /* P3 This floods. Remove soon. XXX */
- } else {
- if ((lkr = usb_lock_device_for_reset(sc->dev, sc->intf)) < 0) {
- printk(KERN_NOTICE
- "%s: usb_lock_device_for_reset failed (%d)\n",
- sc->name, lkr);
- } else {
- rc = usb_reset_device(sc->dev);
- if (rc < 0) {
- printk(KERN_NOTICE "%s: "
- "usb_lock_device_for_reset failed (%d)\n",
- sc->name, rc);
- }
-
- if (lkr)
- usb_unlock_device(sc->dev);
- }
- }
-
- /*
- * In theory, no commands can be running while reset is active,
- * so nobody can ask for another reset, and so we do not need any
- * queues of resets or anything. We do need a spinlock though,
- * to interact with block layer.
- */
- spin_lock_irqsave(&sc->lock, flags);
- sc->reset = 0;
- tasklet_schedule(&sc->tasklet);
- list_for_each(p, &sc->luns) {
- lun = list_entry(p, struct ub_lun, link);
- blk_start_queue(lun->disk->queue);
- }
- wake_up(&sc->reset_wait);
- spin_unlock_irqrestore(&sc->lock, flags);
-}
-
/*
* This is called from a process context.
*/
@@ -2300,7 +2146,7 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
if (ep_in == NULL || ep_out == NULL) {
printk(KERN_NOTICE "%s: failed endpoint check\n",
sc->name);
- return -ENODEV;
+ return -EIO;
}
/* Calculate and store the pipe values */
@@ -2326,9 +2172,6 @@ static int ub_probe(struct usb_interface *intf,
int rc;
int i;
- if (usb_usual_check_type(dev_id, USB_US_TYPE_UB))
- return -ENXIO;
-
rc = -ENOMEM;
if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)
goto err_core;
@@ -2338,8 +2181,6 @@ static int ub_probe(struct usb_interface *intf,
usb_init_urb(&sc->work_urb);
tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc);
atomic_set(&sc->poison, 0);
- INIT_WORK(&sc->reset_work, ub_reset_task, sc);
- init_waitqueue_head(&sc->reset_wait);
init_timer(&sc->work_timer);
sc->work_timer.data = (unsigned long) sc;
@@ -2360,8 +2201,7 @@ static int ub_probe(struct usb_interface *intf,
/* XXX Verify that we can handle the device (from descriptors) */
- if (ub_get_pipes(sc, sc->dev, intf) != 0)
- goto err_dev_desc;
+ ub_get_pipes(sc, sc->dev, intf);
if (device_create_file(&sc->intf->dev, &dev_attr_diag) != 0)
goto err_diag;
@@ -2432,7 +2272,6 @@ static int ub_probe(struct usb_interface *intf,
/* device_remove_file(&sc->intf->dev, &dev_attr_diag); */
err_diag:
-err_dev_desc:
usb_set_intfdata(intf, NULL);
// usb_put_intf(sc->intf);
usb_put_dev(sc->dev);
@@ -2470,14 +2309,14 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
ub_revalidate(sc, lun);
rc = -ENOMEM;
- if ((disk = alloc_disk(UB_PARTS_PER_LUN)) == NULL)
+ if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL)
goto err_diskalloc;
lun->disk = disk;
sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a');
sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a');
disk->major = UB_MAJOR;
- disk->first_minor = lun->id * UB_PARTS_PER_LUN;
+ disk->first_minor = lun->id * UB_MINORS_PER_MAJOR;
disk->fops = &ub_bd_fops;
disk->private_data = lun;
disk->driverfs_dev = &sc->intf->dev;
@@ -2540,11 +2379,6 @@ static void ub_disconnect(struct usb_interface *intf)
*/
atomic_set(&sc->poison, 1);
- /*
- * Wait for reset to end, if any.
- */
- wait_event(sc->reset_wait, !sc->reset);
-
/*
* Blow away queued commands.
*
@@ -2558,7 +2392,7 @@ static void ub_disconnect(struct usb_interface *intf)
{
struct ub_scsi_cmd *cmd;
int cnt = 0;
- while ((cmd = ub_cmdq_peek(sc)) != NULL) {
+ while ((cmd = ub_cmdq_pop(sc)) != NULL) {
cmd->error = -ENOTCONN;
cmd->state = UB_CMDST_DONE;
ub_cmdtr_state(sc, cmd);
@@ -2627,6 +2461,7 @@ static void ub_disconnect(struct usb_interface *intf)
}
static struct usb_driver ub_driver = {
+ .owner = THIS_MODULE,
.name = "ub",
.probe = ub_probe,
.disconnect = ub_disconnect,
@@ -2644,7 +2479,6 @@ static int __init ub_init(void)
if ((rc = usb_register(&ub_driver)) != 0)
goto err_register;
- usb_usual_set_present(USB_US_TYPE_UB);
return 0;
err_register:
@@ -2660,7 +2494,6 @@ static void __exit ub_exit(void)
devfs_remove(DEVFS_NAME);
unregister_blkdev(UB_MAJOR, DRV_NAME);
- usb_usual_clear_present(USB_US_TYPE_UB);
}
module_init(ub_init);
diff --git a/trunk/drivers/bluetooth/bcm203x.c b/trunk/drivers/bluetooth/bcm203x.c
index 3e7a067cc087..8e7fb3551775 100644
--- a/trunk/drivers/bluetooth/bcm203x.c
+++ b/trunk/drivers/bluetooth/bcm203x.c
@@ -275,6 +275,7 @@ static void bcm203x_disconnect(struct usb_interface *intf)
}
static struct usb_driver bcm203x_driver = {
+ .owner = THIS_MODULE,
.name = "bcm203x",
.probe = bcm203x_probe,
.disconnect = bcm203x_disconnect,
diff --git a/trunk/drivers/bluetooth/bfusb.c b/trunk/drivers/bluetooth/bfusb.c
index 8947c8837dac..067e27893e4a 100644
--- a/trunk/drivers/bluetooth/bfusb.c
+++ b/trunk/drivers/bluetooth/bfusb.c
@@ -768,6 +768,7 @@ static void bfusb_disconnect(struct usb_interface *intf)
}
static struct usb_driver bfusb_driver = {
+ .owner = THIS_MODULE,
.name = "bfusb",
.probe = bfusb_probe,
.disconnect = bfusb_disconnect,
diff --git a/trunk/drivers/bluetooth/bluecard_cs.c b/trunk/drivers/bluetooth/bluecard_cs.c
index 9888bc151755..f36c563d72c4 100644
--- a/trunk/drivers/bluetooth/bluecard_cs.c
+++ b/trunk/drivers/bluetooth/bluecard_cs.c
@@ -87,8 +87,14 @@ typedef struct bluecard_info_t {
static void bluecard_config(dev_link_t *link);
static void bluecard_release(dev_link_t *link);
+static int bluecard_event(event_t event, int priority, event_callback_args_t *args);
-static void bluecard_detach(struct pcmcia_device *p_dev);
+static dev_info_t dev_info = "bluecard_cs";
+
+static dev_link_t *bluecard_attach(void);
+static void bluecard_detach(dev_link_t *);
+
+static dev_link_t *dev_list = NULL;
/* Default baud rate: 57600, 115200, 230400 or 460800 */
@@ -856,15 +862,17 @@ static int bluecard_close(bluecard_info_t *info)
return 0;
}
-static int bluecard_attach(struct pcmcia_device *p_dev)
+static dev_link_t *bluecard_attach(void)
{
bluecard_info_t *info;
+ client_reg_t client_reg;
dev_link_t *link;
+ int ret;
/* Create new info device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
- return -ENOMEM;
+ return NULL;
link = &info->link;
link->priv = info;
@@ -881,24 +889,50 @@ static int bluecard_attach(struct pcmcia_device *p_dev)
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- bluecard_config(link);
+ /* Register with Card Services */
+ link->next = dev_list;
+ dev_list = link;
+ client_reg.dev_info = &dev_info;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+
+ ret = pcmcia_register_client(&link->handle, &client_reg);
+ if (ret != CS_SUCCESS) {
+ cs_error(link->handle, RegisterClient, ret);
+ bluecard_detach(link);
+ return NULL;
+ }
- return 0;
+ return link;
}
-static void bluecard_detach(struct pcmcia_device *p_dev)
+static void bluecard_detach(dev_link_t *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
bluecard_info_t *info = link->priv;
+ dev_link_t **linkp;
+ int ret;
+
+ /* Locate device structure */
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link)
+ break;
+
+ if (*linkp == NULL)
+ return;
if (link->state & DEV_CONFIG)
bluecard_release(link);
+ if (link->handle) {
+ ret = pcmcia_deregister_client(link->handle);
+ if (ret != CS_SUCCESS)
+ cs_error(link->handle, DeregisterClient, ret);
+ }
+
+ /* Unlink device structure, free bits */
+ *linkp = link->next;
+
kfree(info);
}
@@ -1011,24 +1045,39 @@ static void bluecard_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-static int bluecard_suspend(struct pcmcia_device *dev)
-{
- dev_link_t *link = dev_to_instance(dev);
-
- link->state |= DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
- return 0;
-}
-
-static int bluecard_resume(struct pcmcia_device *dev)
+static int bluecard_event(event_t event, int priority, event_callback_args_t *args)
{
- dev_link_t *link = dev_to_instance(dev);
+ dev_link_t *link = args->client_data;
+ bluecard_info_t *info = link->priv;
- link->state &= ~DEV_SUSPEND;
- if (DEV_OK(link))
- pcmcia_request_configuration(link->handle, &link->conf);
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG) {
+ bluecard_close(info);
+ bluecard_release(link);
+ }
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ bluecard_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ if (link->state & DEV_CONFIG)
+ pcmcia_release_configuration(link->handle);
+ break;
+ case CS_EVENT_PM_RESUME:
+ link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
+ if (DEV_OK(link))
+ pcmcia_request_configuration(link->handle, &link->conf);
+ break;
+ }
return 0;
}
@@ -1046,11 +1095,10 @@ static struct pcmcia_driver bluecard_driver = {
.drv = {
.name = "bluecard_cs",
},
- .probe = bluecard_attach,
- .remove = bluecard_detach,
+ .attach = bluecard_attach,
+ .event = bluecard_event,
+ .detach = bluecard_detach,
.id_table = bluecard_ids,
- .suspend = bluecard_suspend,
- .resume = bluecard_resume,
};
static int __init init_bluecard_cs(void)
@@ -1062,6 +1110,7 @@ static int __init init_bluecard_cs(void)
static void __exit exit_bluecard_cs(void)
{
pcmcia_unregister_driver(&bluecard_driver);
+ BUG_ON(dev_list != NULL);
}
module_init(init_bluecard_cs);
diff --git a/trunk/drivers/bluetooth/bpa10x.c b/trunk/drivers/bluetooth/bpa10x.c
index 9446960ac742..394796315adc 100644
--- a/trunk/drivers/bluetooth/bpa10x.c
+++ b/trunk/drivers/bluetooth/bpa10x.c
@@ -619,6 +619,7 @@ static void bpa10x_disconnect(struct usb_interface *intf)
}
static struct usb_driver bpa10x_driver = {
+ .owner = THIS_MODULE,
.name = "bpa10x",
.probe = bpa10x_probe,
.disconnect = bpa10x_disconnect,
diff --git a/trunk/drivers/bluetooth/bt3c_cs.c b/trunk/drivers/bluetooth/bt3c_cs.c
index e522d19ad886..d2a0add19cc8 100644
--- a/trunk/drivers/bluetooth/bt3c_cs.c
+++ b/trunk/drivers/bluetooth/bt3c_cs.c
@@ -90,8 +90,14 @@ typedef struct bt3c_info_t {
static void bt3c_config(dev_link_t *link);
static void bt3c_release(dev_link_t *link);
+static int bt3c_event(event_t event, int priority, event_callback_args_t *args);
-static void bt3c_detach(struct pcmcia_device *p_dev);
+static dev_info_t dev_info = "bt3c_cs";
+
+static dev_link_t *bt3c_attach(void);
+static void bt3c_detach(dev_link_t *);
+
+static dev_link_t *dev_list = NULL;
/* Transmit states */
@@ -657,15 +663,17 @@ static int bt3c_close(bt3c_info_t *info)
return 0;
}
-static int bt3c_attach(struct pcmcia_device *p_dev)
+static dev_link_t *bt3c_attach(void)
{
bt3c_info_t *info;
+ client_reg_t client_reg;
dev_link_t *link;
+ int ret;
/* Create new info device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
- return -ENOMEM;
+ return NULL;
link = &info->link;
link->priv = info;
@@ -682,24 +690,50 @@ static int bt3c_attach(struct pcmcia_device *p_dev)
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- bt3c_config(link);
+ /* Register with Card Services */
+ link->next = dev_list;
+ dev_list = link;
+ client_reg.dev_info = &dev_info;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+
+ ret = pcmcia_register_client(&link->handle, &client_reg);
+ if (ret != CS_SUCCESS) {
+ cs_error(link->handle, RegisterClient, ret);
+ bt3c_detach(link);
+ return NULL;
+ }
- return 0;
+ return link;
}
-static void bt3c_detach(struct pcmcia_device *p_dev)
+static void bt3c_detach(dev_link_t *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
bt3c_info_t *info = link->priv;
+ dev_link_t **linkp;
+ int ret;
+
+ /* Locate device structure */
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link)
+ break;
+
+ if (*linkp == NULL)
+ return;
if (link->state & DEV_CONFIG)
bt3c_release(link);
+ if (link->handle) {
+ ret = pcmcia_deregister_client(link->handle);
+ if (ret != CS_SUCCESS)
+ cs_error(link->handle, DeregisterClient, ret);
+ }
+
+ /* Unlink device structure, free bits */
+ *linkp = link->next;
+
kfree(info);
}
@@ -857,29 +891,43 @@ static void bt3c_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-static int bt3c_suspend(struct pcmcia_device *dev)
-{
- dev_link_t *link = dev_to_instance(dev);
- link->state |= DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
-
- return 0;
-}
-
-static int bt3c_resume(struct pcmcia_device *dev)
+static int bt3c_event(event_t event, int priority, event_callback_args_t *args)
{
- dev_link_t *link = dev_to_instance(dev);
+ dev_link_t *link = args->client_data;
+ bt3c_info_t *info = link->priv;
- link->state &= ~DEV_SUSPEND;
- if (DEV_OK(link))
- pcmcia_request_configuration(link->handle, &link->conf);
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG) {
+ bt3c_close(info);
+ bt3c_release(link);
+ }
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ bt3c_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ if (link->state & DEV_CONFIG)
+ pcmcia_release_configuration(link->handle);
+ break;
+ case CS_EVENT_PM_RESUME:
+ link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
+ if (DEV_OK(link))
+ pcmcia_request_configuration(link->handle, &link->conf);
+ break;
+ }
return 0;
}
-
static struct pcmcia_device_id bt3c_ids[] = {
PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),
PCMCIA_DEVICE_NULL
@@ -891,11 +939,10 @@ static struct pcmcia_driver bt3c_driver = {
.drv = {
.name = "bt3c_cs",
},
- .probe = bt3c_attach,
- .remove = bt3c_detach,
+ .attach = bt3c_attach,
+ .event = bt3c_event,
+ .detach = bt3c_detach,
.id_table = bt3c_ids,
- .suspend = bt3c_suspend,
- .resume = bt3c_resume,
};
static int __init init_bt3c_cs(void)
@@ -907,6 +954,7 @@ static int __init init_bt3c_cs(void)
static void __exit exit_bt3c_cs(void)
{
pcmcia_unregister_driver(&bt3c_driver);
+ BUG_ON(dev_list != NULL);
}
module_init(init_bt3c_cs);
diff --git a/trunk/drivers/bluetooth/btuart_cs.c b/trunk/drivers/bluetooth/btuart_cs.c
index 7b4bff4cfa2d..529a28a3209d 100644
--- a/trunk/drivers/bluetooth/btuart_cs.c
+++ b/trunk/drivers/bluetooth/btuart_cs.c
@@ -86,8 +86,14 @@ typedef struct btuart_info_t {
static void btuart_config(dev_link_t *link);
static void btuart_release(dev_link_t *link);
+static int btuart_event(event_t event, int priority, event_callback_args_t *args);
-static void btuart_detach(struct pcmcia_device *p_dev);
+static dev_info_t dev_info = "btuart_cs";
+
+static dev_link_t *btuart_attach(void);
+static void btuart_detach(dev_link_t *);
+
+static dev_link_t *dev_list = NULL;
/* Maximum baud rate */
@@ -576,15 +582,17 @@ static int btuart_close(btuart_info_t *info)
return 0;
}
-static int btuart_attach(struct pcmcia_device *p_dev)
+static dev_link_t *btuart_attach(void)
{
btuart_info_t *info;
+ client_reg_t client_reg;
dev_link_t *link;
+ int ret;
/* Create new info device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
- return -ENOMEM;
+ return NULL;
link = &info->link;
link->priv = info;
@@ -601,24 +609,50 @@ static int btuart_attach(struct pcmcia_device *p_dev)
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- btuart_config(link);
+ /* Register with Card Services */
+ link->next = dev_list;
+ dev_list = link;
+ client_reg.dev_info = &dev_info;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+
+ ret = pcmcia_register_client(&link->handle, &client_reg);
+ if (ret != CS_SUCCESS) {
+ cs_error(link->handle, RegisterClient, ret);
+ btuart_detach(link);
+ return NULL;
+ }
- return 0;
+ return link;
}
-static void btuart_detach(struct pcmcia_device *p_dev)
+static void btuart_detach(dev_link_t *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
btuart_info_t *info = link->priv;
+ dev_link_t **linkp;
+ int ret;
+
+ /* Locate device structure */
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link)
+ break;
+
+ if (*linkp == NULL)
+ return;
if (link->state & DEV_CONFIG)
btuart_release(link);
+ if (link->handle) {
+ ret = pcmcia_deregister_client(link->handle);
+ if (ret != CS_SUCCESS)
+ cs_error(link->handle, DeregisterClient, ret);
+ }
+
+ /* Unlink device structure, free bits */
+ *linkp = link->next;
+
kfree(info);
}
@@ -777,29 +811,43 @@ static void btuart_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-static int btuart_suspend(struct pcmcia_device *dev)
-{
- dev_link_t *link = dev_to_instance(dev);
- link->state |= DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
-
- return 0;
-}
-
-static int btuart_resume(struct pcmcia_device *dev)
+static int btuart_event(event_t event, int priority, event_callback_args_t *args)
{
- dev_link_t *link = dev_to_instance(dev);
+ dev_link_t *link = args->client_data;
+ btuart_info_t *info = link->priv;
- link->state &= ~DEV_SUSPEND;
- if (DEV_OK(link))
- pcmcia_request_configuration(link->handle, &link->conf);
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG) {
+ btuart_close(info);
+ btuart_release(link);
+ }
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ btuart_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ if (link->state & DEV_CONFIG)
+ pcmcia_release_configuration(link->handle);
+ break;
+ case CS_EVENT_PM_RESUME:
+ link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
+ if (DEV_OK(link))
+ pcmcia_request_configuration(link->handle, &link->conf);
+ break;
+ }
return 0;
}
-
static struct pcmcia_device_id btuart_ids[] = {
/* don't use this driver. Use serial_cs + hci_uart instead */
PCMCIA_DEVICE_NULL
@@ -811,11 +859,10 @@ static struct pcmcia_driver btuart_driver = {
.drv = {
.name = "btuart_cs",
},
- .probe = btuart_attach,
- .remove = btuart_detach,
+ .attach = btuart_attach,
+ .event = btuart_event,
+ .detach = btuart_detach,
.id_table = btuart_ids,
- .suspend = btuart_suspend,
- .resume = btuart_resume,
};
static int __init init_btuart_cs(void)
@@ -827,6 +874,7 @@ static int __init init_btuart_cs(void)
static void __exit exit_btuart_cs(void)
{
pcmcia_unregister_driver(&btuart_driver);
+ BUG_ON(dev_list != NULL);
}
module_init(init_btuart_cs);
diff --git a/trunk/drivers/bluetooth/dtl1_cs.c b/trunk/drivers/bluetooth/dtl1_cs.c
index 0449bc45ae5e..dec5980a1cd6 100644
--- a/trunk/drivers/bluetooth/dtl1_cs.c
+++ b/trunk/drivers/bluetooth/dtl1_cs.c
@@ -89,8 +89,14 @@ typedef struct dtl1_info_t {
static void dtl1_config(dev_link_t *link);
static void dtl1_release(dev_link_t *link);
+static int dtl1_event(event_t event, int priority, event_callback_args_t *args);
-static void dtl1_detach(struct pcmcia_device *p_dev);
+static dev_info_t dev_info = "dtl1_cs";
+
+static dev_link_t *dtl1_attach(void);
+static void dtl1_detach(dev_link_t *);
+
+static dev_link_t *dev_list = NULL;
/* Transmit states */
@@ -555,15 +561,17 @@ static int dtl1_close(dtl1_info_t *info)
return 0;
}
-static int dtl1_attach(struct pcmcia_device *p_dev)
+static dev_link_t *dtl1_attach(void)
{
dtl1_info_t *info;
+ client_reg_t client_reg;
dev_link_t *link;
+ int ret;
/* Create new info device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
- return -ENOMEM;
+ return NULL;
link = &info->link;
link->priv = info;
@@ -580,24 +588,50 @@ static int dtl1_attach(struct pcmcia_device *p_dev)
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- dtl1_config(link);
+ /* Register with Card Services */
+ link->next = dev_list;
+ dev_list = link;
+ client_reg.dev_info = &dev_info;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+
+ ret = pcmcia_register_client(&link->handle, &client_reg);
+ if (ret != CS_SUCCESS) {
+ cs_error(link->handle, RegisterClient, ret);
+ dtl1_detach(link);
+ return NULL;
+ }
- return 0;
+ return link;
}
-static void dtl1_detach(struct pcmcia_device *p_dev)
+static void dtl1_detach(dev_link_t *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
dtl1_info_t *info = link->priv;
+ dev_link_t **linkp;
+ int ret;
+
+ /* Locate device structure */
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link)
+ break;
+
+ if (*linkp == NULL)
+ return;
if (link->state & DEV_CONFIG)
dtl1_release(link);
+ if (link->handle) {
+ ret = pcmcia_deregister_client(link->handle);
+ if (ret != CS_SUCCESS)
+ cs_error(link->handle, DeregisterClient, ret);
+ }
+
+ /* Unlink device structure, free bits */
+ *linkp = link->next;
+
kfree(info);
}
@@ -729,33 +763,46 @@ static void dtl1_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
}
-static int dtl1_suspend(struct pcmcia_device *dev)
-{
- dev_link_t *link = dev_to_instance(dev);
- link->state |= DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
-
- return 0;
-}
-
-static int dtl1_resume(struct pcmcia_device *dev)
+static int dtl1_event(event_t event, int priority, event_callback_args_t *args)
{
- dev_link_t *link = dev_to_instance(dev);
+ dev_link_t *link = args->client_data;
+ dtl1_info_t *info = link->priv;
- link->state &= ~DEV_SUSPEND;
- if (DEV_OK(link))
- pcmcia_request_configuration(link->handle, &link->conf);
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG) {
+ dtl1_close(info);
+ dtl1_release(link);
+ }
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ dtl1_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ if (link->state & DEV_CONFIG)
+ pcmcia_release_configuration(link->handle);
+ break;
+ case CS_EVENT_PM_RESUME:
+ link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
+ if (DEV_OK(link))
+ pcmcia_request_configuration(link->handle, &link->conf);
+ break;
+ }
return 0;
}
-
static struct pcmcia_device_id dtl1_ids[] = {
PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),
- PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3),
PCMCIA_DEVICE_NULL
};
MODULE_DEVICE_TABLE(pcmcia, dtl1_ids);
@@ -765,11 +812,10 @@ static struct pcmcia_driver dtl1_driver = {
.drv = {
.name = "dtl1_cs",
},
- .probe = dtl1_attach,
- .remove = dtl1_detach,
+ .attach = dtl1_attach,
+ .event = dtl1_event,
+ .detach = dtl1_detach,
.id_table = dtl1_ids,
- .suspend = dtl1_suspend,
- .resume = dtl1_resume,
};
static int __init init_dtl1_cs(void)
@@ -781,6 +827,7 @@ static int __init init_dtl1_cs(void)
static void __exit exit_dtl1_cs(void)
{
pcmcia_unregister_driver(&dtl1_driver);
+ BUG_ON(dev_list != NULL);
}
module_init(init_dtl1_cs);
diff --git a/trunk/drivers/bluetooth/hci_usb.c b/trunk/drivers/bluetooth/hci_usb.c
index 92382e823285..057cb2b6e6d1 100644
--- a/trunk/drivers/bluetooth/hci_usb.c
+++ b/trunk/drivers/bluetooth/hci_usb.c
@@ -1044,6 +1044,7 @@ static void hci_usb_disconnect(struct usb_interface *intf)
}
static struct usb_driver hci_usb_driver = {
+ .owner = THIS_MODULE,
.name = "hci_usb",
.probe = hci_usb_probe,
.disconnect = hci_usb_disconnect,
diff --git a/trunk/drivers/char/.gitignore b/trunk/drivers/char/.gitignore
index 73dfdcebfbba..2b6b1d772ed7 100644
--- a/trunk/drivers/char/.gitignore
+++ b/trunk/drivers/char/.gitignore
@@ -1,3 +1,3 @@
consolemap_deftbl.c
defkeymap.c
-qtronixmap.c
+
diff --git a/trunk/drivers/char/ip2/i2pack.h b/trunk/drivers/char/ip2/i2pack.h
index 00342a677c90..e9b87a78622c 100644
--- a/trunk/drivers/char/ip2/i2pack.h
+++ b/trunk/drivers/char/ip2/i2pack.h
@@ -358,7 +358,7 @@ typedef struct _failStat
#define MB_OUT_STRIPPED 0x40 // Board has read all output from fifo
#define MB_FATAL_ERROR 0x20 // Board has encountered a fatal error
-#pragma pack() // Reset padding to command-line default
+#pragma pack(4) // Reset padding to command-line default
#endif // I2PACK_H
diff --git a/trunk/drivers/char/n_hdlc.c b/trunk/drivers/char/n_hdlc.c
index a133a62f3d55..c3660d8781a4 100644
--- a/trunk/drivers/char/n_hdlc.c
+++ b/trunk/drivers/char/n_hdlc.c
@@ -562,7 +562,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
} /* end of n_hdlc_tty_receive() */
/**
- * n_hdlc_tty_read - Called to retrieve one frame of data (if available)
+ * n_hdlc_tty_read - Called to retreive one frame of data (if available)
* @tty - pointer to tty instance data
* @file - pointer to open file object
* @buf - pointer to returned data buffer
diff --git a/trunk/drivers/char/pcmcia/cm4000_cs.c b/trunk/drivers/char/pcmcia/cm4000_cs.c
index 649677b5dc36..61681c9f3f72 100644
--- a/trunk/drivers/char/pcmcia/cm4000_cs.c
+++ b/trunk/drivers/char/pcmcia/cm4000_cs.c
@@ -66,6 +66,7 @@ static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte";
#define T_100MSEC msecs_to_jiffies(100)
#define T_500MSEC msecs_to_jiffies(500)
+static void cm4000_detach(dev_link_t *link);
static void cm4000_release(dev_link_t *link);
static int major; /* major number we get from the kernel */
@@ -155,6 +156,7 @@ struct cm4000_dev {
/*sbuf*/ 512*sizeof(char) - \
/*queue*/ 4*sizeof(wait_queue_head_t))
+static dev_info_t dev_info = MODULE_NAME;
static dev_link_t *dev_table[CM4000_MAX_DEV];
/* This table doesn't use spaces after the comma between fields and thus
@@ -1862,36 +1864,68 @@ static void cm4000_config(dev_link_t * link, int devno)
link->state &= ~DEV_CONFIG_PENDING;
}
-static int cm4000_suspend(struct pcmcia_device *p_dev)
+static int cm4000_event(event_t event, int priority,
+ event_callback_args_t *args)
{
- dev_link_t *link = dev_to_instance(p_dev);
- struct cm4000_dev *dev;
-
- dev = link->priv;
-
- link->state |= DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
- stop_monitor(dev);
-
- return 0;
-}
-
-static int cm4000_resume(struct pcmcia_device *p_dev)
-{
- dev_link_t *link = dev_to_instance(p_dev);
+ dev_link_t *link;
struct cm4000_dev *dev;
+ int devno;
+ link = args->client_data;
dev = link->priv;
- link->state &= ~DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_request_configuration(link->handle, &link->conf);
+ DEBUGP(3, dev, "-> cm4000_event\n");
+ for (devno = 0; devno < CM4000_MAX_DEV; devno++)
+ if (dev_table[devno] == link)
+ break;
- if (link->open)
- start_monitor(dev);
+ if (devno == CM4000_MAX_DEV)
+ return CS_BAD_ADAPTER;
- return 0;
+ switch (event) {
+ case CS_EVENT_CARD_INSERTION:
+ DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n");
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ cm4000_config(link, devno);
+ break;
+ case CS_EVENT_CARD_REMOVAL:
+ DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
+ link->state &= ~DEV_PRESENT;
+ stop_monitor(dev);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
+ "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
+ link->state |= DEV_SUSPEND;
+ /* fall-through */
+ case CS_EVENT_RESET_PHYSICAL:
+ DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
+ if (link->state & DEV_CONFIG) {
+ DEBUGP(5, dev, "ReleaseConfiguration\n");
+ pcmcia_release_configuration(link->handle);
+ }
+ stop_monitor(dev);
+ break;
+ case CS_EVENT_PM_RESUME:
+ DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
+ "(fall-through to CS_EVENT_CARD_RESET)\n");
+ link->state &= ~DEV_SUSPEND;
+ /* fall-through */
+ case CS_EVENT_CARD_RESET:
+ DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
+ if ((link->state & DEV_CONFIG)) {
+ DEBUGP(5, dev, "RequestConfiguration\n");
+ pcmcia_request_configuration(link->handle, &link->conf);
+ }
+ if (link->open)
+ start_monitor(dev);
+ break;
+ default:
+ DEBUGP(5, dev, "unknown event %.2x\n", event);
+ break;
+ }
+ DEBUGP(3, dev, "<- cm4000_event\n");
+ return CS_SUCCESS;
}
static void cm4000_release(dev_link_t *link)
@@ -1901,10 +1935,11 @@ static void cm4000_release(dev_link_t *link)
pcmcia_release_io(link->handle, &link->io);
}
-static int cm4000_attach(struct pcmcia_device *p_dev)
+static dev_link_t *cm4000_attach(void)
{
struct cm4000_dev *dev;
dev_link_t *link;
+ client_reg_t client_reg;
int i;
for (i = 0; i < CM4000_MAX_DEV; i++)
@@ -1913,55 +1948,76 @@ static int cm4000_attach(struct pcmcia_device *p_dev)
if (i == CM4000_MAX_DEV) {
printk(KERN_NOTICE MODULE_NAME ": all devices in use\n");
- return -ENODEV;
+ return NULL;
}
/* create a new cm4000_cs device */
dev = kzalloc(sizeof(struct cm4000_dev), GFP_KERNEL);
if (dev == NULL)
- return -ENOMEM;
+ return NULL;
link = &dev->link;
link->priv = dev;
link->conf.IntType = INT_MEMORY_AND_IO;
dev_table[i] = link;
+ /* register with card services */
+ client_reg.dev_info = &dev_info;
+ client_reg.EventMask =
+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+
+ i = pcmcia_register_client(&link->handle, &client_reg);
+ if (i) {
+ cs_error(link->handle, RegisterClient, i);
+ cm4000_detach(link);
+ return NULL;
+ }
+
init_waitqueue_head(&dev->devq);
init_waitqueue_head(&dev->ioq);
init_waitqueue_head(&dev->atrq);
init_waitqueue_head(&dev->readq);
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- cm4000_config(link, i);
-
- return 0;
+ return link;
}
-static void cm4000_detach(struct pcmcia_device *p_dev)
+static void cm4000_detach_by_devno(int devno, dev_link_t * link)
{
- dev_link_t *link = dev_to_instance(p_dev);
struct cm4000_dev *dev = link->priv;
- int devno;
- /* find device */
- for (devno = 0; devno < CM4000_MAX_DEV; devno++)
- if (dev_table[devno] == link)
- break;
- if (devno == CM4000_MAX_DEV)
- return;
+ DEBUGP(3, dev, "-> detach_by_devno(devno=%d)\n", devno);
- link->state &= ~DEV_PRESENT;
- stop_monitor(dev);
+ if (link->state & DEV_CONFIG) {
+ DEBUGP(5, dev, "device still configured (try to release it)\n");
+ cm4000_release(link);
+ }
- if (link->state & DEV_CONFIG)
- cm4000_release(link);
+ if (link->handle) {
+ pcmcia_deregister_client(link->handle);
+ }
dev_table[devno] = NULL;
- kfree(dev);
+ kfree(dev);
+ return;
+}
+
+static void cm4000_detach(dev_link_t * link)
+{
+ int i;
+
+ /* find device */
+ for (i = 0; i < CM4000_MAX_DEV; i++)
+ if (dev_table[i] == link)
+ break;
+
+ if (i == CM4000_MAX_DEV)
+ return;
+ cm4000_detach_by_devno(i, link);
return;
}
@@ -1986,10 +2042,9 @@ static struct pcmcia_driver cm4000_driver = {
.drv = {
.name = "cm4000_cs",
},
- .probe = cm4000_attach,
- .remove = cm4000_detach,
- .suspend = cm4000_suspend,
- .resume = cm4000_resume,
+ .attach = cm4000_attach,
+ .detach = cm4000_detach,
+ .event = cm4000_event,
.id_table = cm4000_ids,
};
@@ -2009,8 +2064,13 @@ static int __init cmm_init(void)
static void __exit cmm_exit(void)
{
+ int i;
+
printk(KERN_INFO MODULE_NAME ": unloading\n");
pcmcia_unregister_driver(&cm4000_driver);
+ for (i = 0; i < CM4000_MAX_DEV; i++)
+ if (dev_table[i])
+ cm4000_detach_by_devno(i, dev_table[i]);
unregister_chrdev(major, DEVICE_NAME);
};
diff --git a/trunk/drivers/char/pcmcia/cm4040_cs.c b/trunk/drivers/char/pcmcia/cm4040_cs.c
index 46eb371bf17e..4c698d908ffa 100644
--- a/trunk/drivers/char/pcmcia/cm4040_cs.c
+++ b/trunk/drivers/char/pcmcia/cm4040_cs.c
@@ -65,6 +65,7 @@ static char *version =
#define POLL_PERIOD msecs_to_jiffies(10)
static void reader_release(dev_link_t *link);
+static void reader_detach(dev_link_t *link);
static int major;
@@ -85,6 +86,7 @@ struct reader_dev {
struct timer_list poll_timer;
};
+static dev_info_t dev_info = MODULE_NAME;
static dev_link_t *dev_table[CM_MAX_DEV];
#ifndef PCMCIA_DEBUG
@@ -627,26 +629,65 @@ static void reader_config(dev_link_t *link, int devno)
link->state &= ~DEV_CONFIG_PENDING;
}
-static int reader_suspend(struct pcmcia_device *p_dev)
+static int reader_event(event_t event, int priority,
+ event_callback_args_t *args)
{
- dev_link_t *link = dev_to_instance(p_dev);
-
- link->state |= DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
-
- return 0;
-}
-
-static int reader_resume(struct pcmcia_device *p_dev)
-{
- dev_link_t *link = dev_to_instance(p_dev);
+ dev_link_t *link;
+ struct reader_dev *dev;
+ int devno;
- link->state &= ~DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_request_configuration(link->handle, &link->conf);
+ link = args->client_data;
+ dev = link->priv;
+ DEBUGP(3, dev, "-> reader_event\n");
+ for (devno = 0; devno < CM_MAX_DEV; devno++) {
+ if (dev_table[devno] == link)
+ break;
+ }
+ if (devno == CM_MAX_DEV)
+ return CS_BAD_ADAPTER;
- return 0;
+ switch (event) {
+ case CS_EVENT_CARD_INSERTION:
+ DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n");
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ reader_config(link, devno);
+ break;
+ case CS_EVENT_CARD_REMOVAL:
+ DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
+ link->state &= ~DEV_PRESENT;
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
+ "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
+ link->state |= DEV_SUSPEND;
+
+ case CS_EVENT_RESET_PHYSICAL:
+ DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
+ if (link->state & DEV_CONFIG) {
+ DEBUGP(5, dev, "ReleaseConfiguration\n");
+ pcmcia_release_configuration(link->handle);
+ }
+ break;
+ case CS_EVENT_PM_RESUME:
+ DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
+ "(fall-through to CS_EVENT_CARD_RESET)\n");
+ link->state &= ~DEV_SUSPEND;
+
+ case CS_EVENT_CARD_RESET:
+ DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
+ if ((link->state & DEV_CONFIG)) {
+ DEBUGP(5, dev, "RequestConfiguration\n");
+ pcmcia_request_configuration(link->handle,
+ &link->conf);
+ }
+ break;
+ default:
+ DEBUGP(5, dev, "reader_event: unknown event %.2x\n",
+ event);
+ break;
+ }
+ DEBUGP(3, dev, "<- reader_event\n");
+ return CS_SUCCESS;
}
static void reader_release(dev_link_t *link)
@@ -656,10 +697,11 @@ static void reader_release(dev_link_t *link)
pcmcia_release_io(link->handle, &link->io);
}
-static int reader_attach(struct pcmcia_device *p_dev)
+static dev_link_t *reader_attach(void)
{
struct reader_dev *dev;
dev_link_t *link;
+ client_reg_t client_reg;
int i;
for (i = 0; i < CM_MAX_DEV; i++) {
@@ -668,11 +710,11 @@ static int reader_attach(struct pcmcia_device *p_dev)
}
if (i == CM_MAX_DEV)
- return -ENODEV;
+ return NULL;
dev = kzalloc(sizeof(struct reader_dev), GFP_KERNEL);
if (dev == NULL)
- return -ENOMEM;
+ return NULL;
dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
dev->buffer_status = 0;
@@ -683,6 +725,20 @@ static int reader_attach(struct pcmcia_device *p_dev)
link->conf.IntType = INT_MEMORY_AND_IO;
dev_table[i] = link;
+ client_reg.dev_info = &dev_info;
+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+ client_reg.EventMask=
+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+ i = pcmcia_register_client(&link->handle, &client_reg);
+ if (i) {
+ cs_error(link->handle, RegisterClient, i);
+ reader_detach(link);
+ return NULL;
+ }
init_waitqueue_head(&dev->devq);
init_waitqueue_head(&dev->poll_wait);
init_waitqueue_head(&dev->read_wait);
@@ -690,37 +746,39 @@ static int reader_attach(struct pcmcia_device *p_dev)
init_timer(&dev->poll_timer);
dev->poll_timer.function = &cm4040_do_poll;
- link->handle = p_dev;
- p_dev->instance = link;
+ return link;
+}
+
+static void reader_detach_by_devno(int devno, dev_link_t *link)
+{
+ struct reader_dev *dev = link->priv;
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- reader_config(link, i);
+ if (link->state & DEV_CONFIG) {
+ DEBUGP(5, dev, "device still configured (try to release it)\n");
+ reader_release(link);
+ }
- return 0;
+ pcmcia_deregister_client(link->handle);
+ dev_table[devno] = NULL;
+ DEBUGP(5, dev, "freeing dev=%p\n", dev);
+ cm4040_stop_poll(dev);
+ kfree(dev);
+ return;
}
-static void reader_detach(struct pcmcia_device *p_dev)
+static void reader_detach(dev_link_t *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
- struct reader_dev *dev = link->priv;
- int devno;
+ int i;
/* find device */
- for (devno = 0; devno < CM_MAX_DEV; devno++) {
- if (dev_table[devno] == link)
+ for (i = 0; i < CM_MAX_DEV; i++) {
+ if (dev_table[i] == link)
break;
}
- if (devno == CM_MAX_DEV)
+ if (i == CM_MAX_DEV)
return;
- link->state &= ~DEV_PRESENT;
-
- if (link->state & DEV_CONFIG)
- reader_release(link);
-
- dev_table[devno] = NULL;
- kfree(dev);
-
+ reader_detach_by_devno(i, link);
return;
}
@@ -746,10 +804,9 @@ static struct pcmcia_driver reader_driver = {
.drv = {
.name = "cm4040_cs",
},
- .probe = reader_attach,
- .remove = reader_detach,
- .suspend = reader_suspend,
- .resume = reader_resume,
+ .attach = reader_attach,
+ .detach = reader_detach,
+ .event = reader_event,
.id_table = cm4040_ids,
};
@@ -768,8 +825,14 @@ static int __init cm4040_init(void)
static void __exit cm4040_exit(void)
{
+ int i;
+
printk(KERN_INFO MODULE_NAME ": unloading\n");
pcmcia_unregister_driver(&reader_driver);
+ for (i = 0; i < CM_MAX_DEV; i++) {
+ if (dev_table[i])
+ reader_detach_by_devno(i, dev_table[i]);
+ }
unregister_chrdev(major, DEVICE_NAME);
}
diff --git a/trunk/drivers/char/pcmcia/synclink_cs.c b/trunk/drivers/char/pcmcia/synclink_cs.c
index cf45b100eff1..2c326ea53421 100644
--- a/trunk/drivers/char/pcmcia/synclink_cs.c
+++ b/trunk/drivers/char/pcmcia/synclink_cs.c
@@ -486,7 +486,13 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout);
static void mgslpc_config(dev_link_t *link);
static void mgslpc_release(u_long arg);
-static void mgslpc_detach(struct pcmcia_device *p_dev);
+static int mgslpc_event(event_t event, int priority,
+ event_callback_args_t *args);
+static dev_link_t *mgslpc_attach(void);
+static void mgslpc_detach(dev_link_t *);
+
+static dev_info_t dev_info = "synclink_cs";
+static dev_link_t *dev_list = NULL;
/*
* 1st function defined in .text section. Calling this function in
@@ -533,10 +539,12 @@ static void ldisc_receive_buf(struct tty_struct *tty,
}
}
-static int mgslpc_attach(struct pcmcia_device *p_dev)
+static dev_link_t *mgslpc_attach(void)
{
MGSLPC_INFO *info;
dev_link_t *link;
+ client_reg_t client_reg;
+ int ret;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_attach\n");
@@ -544,7 +552,7 @@ static int mgslpc_attach(struct pcmcia_device *p_dev)
info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
if (!info) {
printk("Error can't allocate device instance data\n");
- return -ENOMEM;
+ return NULL;
}
memset(info, 0, sizeof(MGSLPC_INFO));
@@ -579,15 +587,24 @@ static int mgslpc_attach(struct pcmcia_device *p_dev)
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
- link->handle = p_dev;
- p_dev->instance = link;
+ /* Register with Card Services */
+ link->next = dev_list;
+ dev_list = link;
+
+ client_reg.dev_info = &dev_info;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- mgslpc_config(link);
+ ret = pcmcia_register_client(&link->handle, &client_reg);
+ if (ret != CS_SUCCESS) {
+ cs_error(link->handle, RegisterClient, ret);
+ mgslpc_detach(link);
+ return NULL;
+ }
mgslpc_add_device(info);
- return 0;
+ return link;
}
/* Card has been inserted.
@@ -719,50 +736,85 @@ static void mgslpc_release(u_long arg)
pcmcia_release_io(link->handle, &link->io);
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
+ if (link->state & DEV_STALE_LINK)
+ mgslpc_detach(link);
}
-static void mgslpc_detach(struct pcmcia_device *p_dev)
+static void mgslpc_detach(dev_link_t *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
+ dev_link_t **linkp;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_detach(0x%p)\n", link);
+
+ /* find device */
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link) break;
+ if (*linkp == NULL)
+ return;
if (link->state & DEV_CONFIG) {
- ((MGSLPC_INFO *)link->priv)->stop = 1;
- mgslpc_release((u_long)link);
+ /* device is configured/active, mark it so when
+ * release() is called a proper detach() occurs.
+ */
+ if (debug_level >= DEBUG_LEVEL_INFO)
+ printk(KERN_DEBUG "synclinkpc: detach postponed, '%s' "
+ "still locked\n", link->dev->dev_name);
+ link->state |= DEV_STALE_LINK;
+ return;
}
+ /* Break the link with Card Services */
+ if (link->handle)
+ pcmcia_deregister_client(link->handle);
+
+ /* Unlink device structure, and free it */
+ *linkp = link->next;
mgslpc_remove_device((MGSLPC_INFO *)link->priv);
}
-static int mgslpc_suspend(struct pcmcia_device *dev)
-{
- dev_link_t *link = dev_to_instance(dev);
- MGSLPC_INFO *info = link->priv;
-
- link->state |= DEV_SUSPEND;
- info->stop = 1;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
-
- return 0;
-}
-
-static int mgslpc_resume(struct pcmcia_device *dev)
+static int mgslpc_event(event_t event, int priority,
+ event_callback_args_t *args)
{
- dev_link_t *link = dev_to_instance(dev);
- MGSLPC_INFO *info = link->priv;
-
- link->state &= ~DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_request_configuration(link->handle, &link->conf);
- info->stop = 0;
-
- return 0;
+ dev_link_t *link = args->client_data;
+ MGSLPC_INFO *info = link->priv;
+
+ if (debug_level >= DEBUG_LEVEL_INFO)
+ printk("mgslpc_event(0x%06x)\n", event);
+
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG) {
+ ((MGSLPC_INFO *)link->priv)->stop = 1;
+ mgslpc_release((u_long)link);
+ }
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ mgslpc_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ /* Mark the device as stopped, to block IO until later */
+ info->stop = 1;
+ if (link->state & DEV_CONFIG)
+ pcmcia_release_configuration(link->handle);
+ break;
+ case CS_EVENT_PM_RESUME:
+ link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
+ if (link->state & DEV_CONFIG)
+ pcmcia_request_configuration(link->handle, &link->conf);
+ info->stop = 0;
+ break;
+ }
+ return 0;
}
-
static inline int mgslpc_paranoia_check(MGSLPC_INFO *info,
char *name, const char *routine)
{
@@ -3039,11 +3091,10 @@ static struct pcmcia_driver mgslpc_driver = {
.drv = {
.name = "synclink_cs",
},
- .probe = mgslpc_attach,
- .remove = mgslpc_detach,
+ .attach = mgslpc_attach,
+ .event = mgslpc_event,
+ .detach = mgslpc_detach,
.id_table = mgslpc_ids,
- .suspend = mgslpc_suspend,
- .resume = mgslpc_resume,
};
static struct tty_operations mgslpc_ops = {
@@ -3087,6 +3138,7 @@ static void synclink_cs_cleanup(void)
}
pcmcia_unregister_driver(&mgslpc_driver);
+ BUG_ON(dev_list != NULL);
}
static int __init synclink_cs_init(void)
diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c
index bdfdfd28594d..7999da25fe40 100644
--- a/trunk/drivers/char/random.c
+++ b/trunk/drivers/char/random.c
@@ -1554,8 +1554,10 @@ __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
EXPORT_SYMBOL(secure_tcp_sequence_number);
-/* Generate secure starting point for ephemeral IPV4 transport port search */
-u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
+
+
+/* Generate secure starting point for ephemeral TCP port search */
+u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
{
struct keydata *keyptr = get_keyptr();
u32 hash[4];
@@ -1573,7 +1575,7 @@ u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dport)
+u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dport)
{
struct keydata *keyptr = get_keyptr();
u32 hash[12];
@@ -1584,7 +1586,7 @@ u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dpo
return twothirdsMD4Transform(daddr, hash);
}
-EXPORT_SYMBOL(secure_ipv6_port_ephemeral);
+EXPORT_SYMBOL(secure_tcpv6_port_ephemeral);
#endif
#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
diff --git a/trunk/drivers/char/watchdog/ixp4xx_wdt.c b/trunk/drivers/char/watchdog/ixp4xx_wdt.c
index 3800835ca8f3..b5be8b11104a 100644
--- a/trunk/drivers/char/watchdog/ixp4xx_wdt.c
+++ b/trunk/drivers/char/watchdog/ixp4xx_wdt.c
@@ -186,8 +186,8 @@ static int __init ixp4xx_wdt_init(void)
unsigned long processor_id;
asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :);
- if (!(processor_id & 0xf) && !cpu_is_ixp46x()) {
- printk("IXP4XXX Watchdog: Rev. A0 IXP42x CPU detected - "
+ if (!(processor_id & 0xf)) {
+ printk("IXP4XXX Watchdog: Rev. A0 CPU detected - "
"watchdog disabled\n");
return -ENODEV;
diff --git a/trunk/drivers/char/watchdog/pcwd_usb.c b/trunk/drivers/char/watchdog/pcwd_usb.c
index 1533f56baa42..092e9b133750 100644
--- a/trunk/drivers/char/watchdog/pcwd_usb.c
+++ b/trunk/drivers/char/watchdog/pcwd_usb.c
@@ -151,6 +151,7 @@ static void usb_pcwd_disconnect (struct usb_interface *interface);
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver usb_pcwd_driver = {
+ .owner = THIS_MODULE,
.name = DRIVER_NAME,
.probe = usb_pcwd_probe,
.disconnect = usb_pcwd_disconnect,
diff --git a/trunk/drivers/cpufreq/cpufreq.c b/trunk/drivers/cpufreq/cpufreq.c
index a9163d02983a..815902c2c856 100644
--- a/trunk/drivers/cpufreq/cpufreq.c
+++ b/trunk/drivers/cpufreq/cpufreq.c
@@ -822,30 +822,6 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigne
}
-/**
- * cpufreq_quick_get - get the CPU frequency (in kHz) frpm policy->cur
- * @cpu: CPU number
- *
- * This is the last known freq, without actually getting it from the driver.
- * Return value will be same as what is shown in scaling_cur_freq in sysfs.
- */
-unsigned int cpufreq_quick_get(unsigned int cpu)
-{
- struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
- unsigned int ret = 0;
-
- if (policy) {
- down(&policy->lock);
- ret = policy->cur;
- up(&policy->lock);
- cpufreq_cpu_put(policy);
- }
-
- return (ret);
-}
-EXPORT_SYMBOL(cpufreq_quick_get);
-
-
/**
* cpufreq_get - get the current CPU frequency (in kHz)
* @cpu: CPU number
diff --git a/trunk/drivers/cpufreq/cpufreq_conservative.c b/trunk/drivers/cpufreq/cpufreq_conservative.c
index 39543a2bed0f..2ed5c4363b53 100644
--- a/trunk/drivers/cpufreq/cpufreq_conservative.c
+++ b/trunk/drivers/cpufreq/cpufreq_conservative.c
@@ -93,7 +93,7 @@ static inline unsigned int get_cpu_idle_time(unsigned int cpu)
{
return kstat_cpu(cpu).cpustat.idle +
kstat_cpu(cpu).cpustat.iowait +
- ( dbs_tuners_ins.ignore_nice ?
+ ( !dbs_tuners_ins.ignore_nice ?
kstat_cpu(cpu).cpustat.nice :
0);
}
@@ -127,7 +127,7 @@ show_one(sampling_rate, sampling_rate);
show_one(sampling_down_factor, sampling_down_factor);
show_one(up_threshold, up_threshold);
show_one(down_threshold, down_threshold);
-show_one(ignore_nice_load, ignore_nice);
+show_one(ignore_nice, ignore_nice);
show_one(freq_step, freq_step);
static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
@@ -207,7 +207,7 @@ static ssize_t store_down_threshold(struct cpufreq_policy *unused,
return count;
}
-static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
+static ssize_t store_ignore_nice(struct cpufreq_policy *policy,
const char *buf, size_t count)
{
unsigned int input;
@@ -272,7 +272,7 @@ define_one_rw(sampling_rate);
define_one_rw(sampling_down_factor);
define_one_rw(up_threshold);
define_one_rw(down_threshold);
-define_one_rw(ignore_nice_load);
+define_one_rw(ignore_nice);
define_one_rw(freq_step);
static struct attribute * dbs_attributes[] = {
@@ -282,7 +282,7 @@ static struct attribute * dbs_attributes[] = {
&sampling_down_factor.attr,
&up_threshold.attr,
&down_threshold.attr,
- &ignore_nice_load.attr,
+ &ignore_nice.attr,
&freq_step.attr,
NULL
};
diff --git a/trunk/drivers/cpufreq/cpufreq_ondemand.c b/trunk/drivers/cpufreq/cpufreq_ondemand.c
index e69fd8dd1f1c..17741111246b 100644
--- a/trunk/drivers/cpufreq/cpufreq_ondemand.c
+++ b/trunk/drivers/cpufreq/cpufreq_ondemand.c
@@ -89,7 +89,7 @@ static inline unsigned int get_cpu_idle_time(unsigned int cpu)
{
return kstat_cpu(cpu).cpustat.idle +
kstat_cpu(cpu).cpustat.iowait +
- ( dbs_tuners_ins.ignore_nice ?
+ ( !dbs_tuners_ins.ignore_nice ?
kstat_cpu(cpu).cpustat.nice :
0);
}
@@ -122,7 +122,7 @@ static ssize_t show_##file_name \
show_one(sampling_rate, sampling_rate);
show_one(sampling_down_factor, sampling_down_factor);
show_one(up_threshold, up_threshold);
-show_one(ignore_nice_load, ignore_nice);
+show_one(ignore_nice, ignore_nice);
static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
const char *buf, size_t count)
@@ -182,7 +182,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
return count;
}
-static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
+static ssize_t store_ignore_nice(struct cpufreq_policy *policy,
const char *buf, size_t count)
{
unsigned int input;
@@ -223,7 +223,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name)
define_one_rw(sampling_rate);
define_one_rw(sampling_down_factor);
define_one_rw(up_threshold);
-define_one_rw(ignore_nice_load);
+define_one_rw(ignore_nice);
static struct attribute * dbs_attributes[] = {
&sampling_rate_max.attr,
@@ -231,7 +231,7 @@ static struct attribute * dbs_attributes[] = {
&sampling_rate.attr,
&sampling_down_factor.attr,
&up_threshold.attr,
- &ignore_nice_load.attr,
+ &ignore_nice.attr,
NULL
};
diff --git a/trunk/drivers/ide/ide-cd.c b/trunk/drivers/ide/ide-cd.c
index 70aeb3a60120..b4d7a3efb90f 100644
--- a/trunk/drivers/ide/ide-cd.c
+++ b/trunk/drivers/ide/ide-cd.c
@@ -3509,7 +3509,6 @@ static int __init ide_cdrom_init(void)
return driver_register(&ide_cdrom_driver.gen_driver);
}
-MODULE_ALIAS("ide:*m-cdrom*");
module_init(ide_cdrom_init);
module_exit(ide_cdrom_exit);
MODULE_LICENSE("GPL");
diff --git a/trunk/drivers/ide/ide-disk.c b/trunk/drivers/ide/ide-disk.c
index 4e5767968d7f..449522f0540c 100644
--- a/trunk/drivers/ide/ide-disk.c
+++ b/trunk/drivers/ide/ide-disk.c
@@ -1271,7 +1271,6 @@ static int __init idedisk_init(void)
return driver_register(&idedisk_driver.gen_driver);
}
-MODULE_ALIAS("ide:*m-disk*");
module_init(idedisk_init);
module_exit(idedisk_exit);
MODULE_LICENSE("GPL");
diff --git a/trunk/drivers/ide/ide-floppy.c b/trunk/drivers/ide/ide-floppy.c
index fba3fffc2d66..9e293c8063dc 100644
--- a/trunk/drivers/ide/ide-floppy.c
+++ b/trunk/drivers/ide/ide-floppy.c
@@ -2197,7 +2197,6 @@ static int __init idefloppy_init(void)
return driver_register(&idefloppy_driver.gen_driver);
}
-MODULE_ALIAS("ide:*m-floppy*");
module_init(idefloppy_init);
module_exit(idefloppy_exit);
MODULE_LICENSE("GPL");
diff --git a/trunk/drivers/ide/ide-tape.c b/trunk/drivers/ide/ide-tape.c
index fab9b2b02504..7d7944ed4158 100644
--- a/trunk/drivers/ide/ide-tape.c
+++ b/trunk/drivers/ide/ide-tape.c
@@ -4947,7 +4947,6 @@ static int __init idetape_init(void)
return error;
}
-MODULE_ALIAS("ide:*m-tape*");
module_init(idetape_init);
module_exit(idetape_exit);
MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR);
diff --git a/trunk/drivers/ide/ide.c b/trunk/drivers/ide/ide.c
index 4b524f6b3ecd..8af179b531c3 100644
--- a/trunk/drivers/ide/ide.c
+++ b/trunk/drivers/ide/ide.c
@@ -1904,69 +1904,9 @@ static int ide_bus_match(struct device *dev, struct device_driver *drv)
return 1;
}
-static char *media_string(ide_drive_t *drive)
-{
- switch (drive->media) {
- case ide_disk:
- return "disk";
- case ide_cdrom:
- return "cdrom";
- case ide_tape:
- return "tape";
- case ide_floppy:
- return "floppy";
- default:
- return "UNKNOWN";
- }
-}
-
-static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- ide_drive_t *drive = to_ide_device(dev);
- return sprintf(buf, "%s\n", media_string(drive));
-}
-
-static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- ide_drive_t *drive = to_ide_device(dev);
- return sprintf(buf, "%s\n", drive->name);
-}
-
-static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- ide_drive_t *drive = to_ide_device(dev);
- return sprintf(buf, "ide:m-%s\n", media_string(drive));
-}
-
-static struct device_attribute ide_dev_attrs[] = {
- __ATTR_RO(media),
- __ATTR_RO(drivename),
- __ATTR_RO(modalias),
- __ATTR_NULL
-};
-
-static int ide_uevent(struct device *dev, char **envp, int num_envp,
- char *buffer, int buffer_size)
-{
- ide_drive_t *drive = to_ide_device(dev);
- int i = 0;
- int length = 0;
-
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "MEDIA=%s", media_string(drive));
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "DRIVENAME=%s", drive->name);
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "MODALIAS=ide:m-%s", media_string(drive));
- envp[i] = NULL;
- return 0;
-}
-
struct bus_type ide_bus_type = {
.name = "ide",
.match = ide_bus_match,
- .uevent = ide_uevent,
- .dev_attrs = ide_dev_attrs,
.suspend = generic_ide_suspend,
.resume = generic_ide_resume,
};
diff --git a/trunk/drivers/ide/legacy/ide-cs.c b/trunk/drivers/ide/legacy/ide-cs.c
index 4c2af9020905..ef79805218e4 100644
--- a/trunk/drivers/ide/legacy/ide-cs.c
+++ b/trunk/drivers/ide/legacy/ide-cs.c
@@ -88,12 +88,15 @@ typedef struct ide_info_t {
} ide_info_t;
static void ide_release(dev_link_t *);
-static void ide_config(dev_link_t *);
-
-static void ide_detach(struct pcmcia_device *p_dev);
+static int ide_event(event_t event, int priority,
+ event_callback_args_t *args);
+static dev_info_t dev_info = "ide-cs";
+static dev_link_t *ide_attach(void);
+static void ide_detach(dev_link_t *);
+static dev_link_t *dev_list = NULL;
/*======================================================================
@@ -103,17 +106,18 @@ static void ide_detach(struct pcmcia_device *p_dev);
======================================================================*/
-static int ide_attach(struct pcmcia_device *p_dev)
+static dev_link_t *ide_attach(void)
{
ide_info_t *info;
dev_link_t *link;
-
+ client_reg_t client_reg;
+ int ret;
+
DEBUG(0, "ide_attach()\n");
/* Create new ide device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
+ if (!info) return NULL;
link = &info->link; link->priv = info;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -124,14 +128,21 @@ static int ide_attach(struct pcmcia_device *p_dev)
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
-
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- ide_config(link);
-
- return 0;
+
+ /* Register with Card Services */
+ link->next = dev_list;
+ dev_list = link;
+ client_reg.dev_info = &dev_info;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+ ret = pcmcia_register_client(&link->handle, &client_reg);
+ if (ret != CS_SUCCESS) {
+ cs_error(link->handle, RegisterClient, ret);
+ ide_detach(link);
+ return NULL;
+ }
+
+ return link;
} /* ide_attach */
/*======================================================================
@@ -143,16 +154,32 @@ static int ide_attach(struct pcmcia_device *p_dev)
======================================================================*/
-static void ide_detach(struct pcmcia_device *p_dev)
+static void ide_detach(dev_link_t *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
+ dev_link_t **linkp;
+ int ret;
DEBUG(0, "ide_detach(0x%p)\n", link);
+
+ /* Locate device structure */
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link) break;
+ if (*linkp == NULL)
+ return;
if (link->state & DEV_CONFIG)
ide_release(link);
-
+
+ if (link->handle) {
+ ret = pcmcia_deregister_client(link->handle);
+ if (ret != CS_SUCCESS)
+ cs_error(link->handle, DeregisterClient, ret);
+ }
+
+ /* Unlink, free device structure */
+ *linkp = link->next;
kfree(link->priv);
+
} /* ide_detach */
static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
@@ -379,28 +406,6 @@ void ide_release(dev_link_t *link)
} /* ide_release */
-static int ide_suspend(struct pcmcia_device *dev)
-{
- dev_link_t *link = dev_to_instance(dev);
-
- link->state |= DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
-
- return 0;
-}
-
-static int ide_resume(struct pcmcia_device *dev)
-{
- dev_link_t *link = dev_to_instance(dev);
-
- link->state &= ~DEV_SUSPEND;
- if (DEV_OK(link))
- pcmcia_request_configuration(link->handle, &link->conf);
-
- return 0;
-}
-
/*======================================================================
The card status event handler. Mostly, this schedules other
@@ -410,15 +415,48 @@ static int ide_resume(struct pcmcia_device *dev)
======================================================================*/
+int ide_event(event_t event, int priority,
+ event_callback_args_t *args)
+{
+ dev_link_t *link = args->client_data;
+
+ DEBUG(1, "ide_event(0x%06x)\n", event);
+
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG)
+ ide_release(link);
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ ide_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ if (link->state & DEV_CONFIG)
+ pcmcia_release_configuration(link->handle);
+ break;
+ case CS_EVENT_PM_RESUME:
+ link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
+ if (DEV_OK(link))
+ pcmcia_request_configuration(link->handle, &link->conf);
+ break;
+ }
+ return 0;
+} /* ide_event */
+
static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_FUNC_ID(4),
- PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */
PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
- PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */
PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */
PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
@@ -433,8 +471,6 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591),
PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
- PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
- PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -458,11 +494,10 @@ static struct pcmcia_driver ide_cs_driver = {
.drv = {
.name = "ide-cs",
},
- .probe = ide_attach,
- .remove = ide_detach,
+ .attach = ide_attach,
+ .event = ide_event,
+ .detach = ide_detach,
.id_table = ide_ids,
- .suspend = ide_suspend,
- .resume = ide_resume,
};
static int __init init_ide_cs(void)
@@ -473,6 +508,7 @@ static int __init init_ide_cs(void)
static void __exit exit_ide_cs(void)
{
pcmcia_unregister_driver(&ide_cs_driver);
+ BUG_ON(dev_list != NULL);
}
late_initcall(init_ide_cs);
diff --git a/trunk/drivers/ieee1394/.gitignore b/trunk/drivers/ieee1394/.gitignore
deleted file mode 100644
index 33da10a25323..000000000000
--- a/trunk/drivers/ieee1394/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-oui.c
diff --git a/trunk/drivers/ieee1394/Kconfig b/trunk/drivers/ieee1394/Kconfig
index 39142e2f804b..25103a0ef9b3 100644
--- a/trunk/drivers/ieee1394/Kconfig
+++ b/trunk/drivers/ieee1394/Kconfig
@@ -169,4 +169,27 @@ config IEEE1394_RAWIO
To compile this driver as a module, say M here: the
module will be called raw1394.
+config IEEE1394_CMP
+ tristate "IEC61883-1 Plug support"
+ depends on IEEE1394
+ help
+ This option enables the Connection Management Procedures
+ (IEC61883-1) driver, which implements input and output plugs.
+
+ To compile this driver as a module, say M here: the
+ module will be called cmp.
+
+config IEEE1394_AMDTP
+ tristate "IEC61883-6 (Audio transmission) support"
+ depends on IEEE1394 && IEEE1394_OHCI1394 && IEEE1394_CMP
+ help
+ This option enables the Audio & Music Data Transmission Protocol
+ (IEC61883-6) driver, which implements audio transmission over
+ IEEE1394.
+
+ The userspace interface is documented in amdtp.h.
+
+ To compile this driver as a module, say M here: the
+ module will be called amdtp.
+
endmenu
diff --git a/trunk/drivers/ieee1394/Makefile b/trunk/drivers/ieee1394/Makefile
index 6f53611fe255..e8b4d48d376e 100644
--- a/trunk/drivers/ieee1394/Makefile
+++ b/trunk/drivers/ieee1394/Makefile
@@ -14,6 +14,8 @@ obj-$(CONFIG_IEEE1394_RAWIO) += raw1394.o
obj-$(CONFIG_IEEE1394_SBP2) += sbp2.o
obj-$(CONFIG_IEEE1394_DV1394) += dv1394.o
obj-$(CONFIG_IEEE1394_ETH1394) += eth1394.o
+obj-$(CONFIG_IEEE1394_AMDTP) += amdtp.o
+obj-$(CONFIG_IEEE1394_CMP) += cmp.o
quiet_cmd_oui2c = OUI2C $@
cmd_oui2c = $(CONFIG_SHELL) $(srctree)/$(src)/oui2c.sh < $< > $@
diff --git a/trunk/drivers/ieee1394/csr1212.c b/trunk/drivers/ieee1394/csr1212.c
index 15773544234b..61ddd5d37eff 100644
--- a/trunk/drivers/ieee1394/csr1212.c
+++ b/trunk/drivers/ieee1394/csr1212.c
@@ -1261,7 +1261,7 @@ static int csr1212_parse_bus_info_block(struct csr1212_csr *csr)
return CSR1212_EINVAL;
#endif
- cr = CSR1212_MALLOC(sizeof(*cr));
+ cr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
if (!cr)
return CSR1212_ENOMEM;
@@ -1393,7 +1393,8 @@ int csr1212_parse_keyval(struct csr1212_keyval *kv,
case CSR1212_KV_TYPE_LEAF:
if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) {
kv->value.leaf.data = CSR1212_MALLOC(quads_to_bytes(kvi_len));
- if (!kv->value.leaf.data) {
+ if (!kv->value.leaf.data)
+ {
ret = CSR1212_ENOMEM;
goto fail;
}
@@ -1461,7 +1462,7 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
cache->next = NULL;
csr->cache_tail = cache;
cache->filled_head =
- CSR1212_MALLOC(sizeof(*cache->filled_head));
+ CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
if (!cache->filled_head) {
return CSR1212_ENOMEM;
}
@@ -1483,7 +1484,7 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
/* Now seach read portions of the cache to see if it is there. */
for (cr = cache->filled_head; cr; cr = cr->next) {
if (cache_index < cr->offset_start) {
- newcr = CSR1212_MALLOC(sizeof(*newcr));
+ newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
if (!newcr)
return CSR1212_ENOMEM;
@@ -1507,7 +1508,7 @@ int _csr1212_read_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv)
if (!cr) {
cr = cache->filled_tail;
- newcr = CSR1212_MALLOC(sizeof(*newcr));
+ newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
if (!newcr)
return CSR1212_ENOMEM;
@@ -1610,17 +1611,15 @@ int csr1212_parse_csr(struct csr1212_csr *csr)
csr->root_kv->valid = 0;
csr->root_kv->next = csr->root_kv;
csr->root_kv->prev = csr->root_kv;
- ret = _csr1212_read_keyval(csr, csr->root_kv);
- if (ret != CSR1212_SUCCESS)
- return ret;
+ csr1212_get_keyval(csr, csr->root_kv);
/* Scan through the Root directory finding all extended ROM regions
* and make cache regions for them */
for (dentry = csr->root_kv->value.directory.dentries_head;
dentry; dentry = dentry->next) {
- if (dentry->kv->key.id == CSR1212_KV_ID_EXTENDED_ROM &&
- !dentry->kv->valid) {
- ret = _csr1212_read_keyval(csr, dentry->kv);
+ if (dentry->kv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
+ csr1212_get_keyval(csr, dentry->kv);
+
if (ret != CSR1212_SUCCESS)
return ret;
}
diff --git a/trunk/drivers/ieee1394/csr1212.h b/trunk/drivers/ieee1394/csr1212.h
index cecd5871f2de..28c5f4b726e2 100644
--- a/trunk/drivers/ieee1394/csr1212.h
+++ b/trunk/drivers/ieee1394/csr1212.h
@@ -646,7 +646,7 @@ static inline struct csr1212_csr_rom_cache *csr1212_rom_cache_malloc(u_int32_t o
{
struct csr1212_csr_rom_cache *cache;
- cache = CSR1212_MALLOC(sizeof(*cache) + size);
+ cache = CSR1212_MALLOC(sizeof(struct csr1212_csr_rom_cache) + size);
if (!cache)
return NULL;
diff --git a/trunk/drivers/ieee1394/dma.c b/trunk/drivers/ieee1394/dma.c
index 9fb2769d9abc..b79ddb43e746 100644
--- a/trunk/drivers/ieee1394/dma.c
+++ b/trunk/drivers/ieee1394/dma.c
@@ -23,8 +23,7 @@ void dma_prog_region_init(struct dma_prog_region *prog)
prog->bus_addr = 0;
}
-int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes,
- struct pci_dev *dev)
+int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, struct pci_dev *dev)
{
/* round up to page size */
n_bytes = PAGE_ALIGN(n_bytes);
@@ -33,8 +32,7 @@ int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes,
prog->kvirt = pci_alloc_consistent(dev, n_bytes, &prog->bus_addr);
if (!prog->kvirt) {
- printk(KERN_ERR
- "dma_prog_region_alloc: pci_alloc_consistent() failed\n");
+ printk(KERN_ERR "dma_prog_region_alloc: pci_alloc_consistent() failed\n");
dma_prog_region_free(prog);
return -ENOMEM;
}
@@ -47,8 +45,7 @@ int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes,
void dma_prog_region_free(struct dma_prog_region *prog)
{
if (prog->kvirt) {
- pci_free_consistent(prog->dev, prog->n_pages << PAGE_SHIFT,
- prog->kvirt, prog->bus_addr);
+ pci_free_consistent(prog->dev, prog->n_pages << PAGE_SHIFT, prog->kvirt, prog->bus_addr);
}
prog->kvirt = NULL;
@@ -68,8 +65,7 @@ void dma_region_init(struct dma_region *dma)
dma->sglist = NULL;
}
-int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
- struct pci_dev *dev, int direction)
+int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_dev *dev, int direction)
{
unsigned int i;
@@ -99,16 +95,14 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
/* fill scatter/gather list with pages */
for (i = 0; i < dma->n_pages; i++) {
- unsigned long va =
- (unsigned long)dma->kvirt + (i << PAGE_SHIFT);
+ unsigned long va = (unsigned long) dma->kvirt + (i << PAGE_SHIFT);
dma->sglist[i].page = vmalloc_to_page((void *)va);
dma->sglist[i].length = PAGE_SIZE;
}
/* map sglist to the IOMMU */
- dma->n_dma_pages =
- pci_map_sg(dev, dma->sglist, dma->n_pages, direction);
+ dma->n_dma_pages = pci_map_sg(dev, dma->sglist, dma->n_pages, direction);
if (dma->n_dma_pages == 0) {
printk(KERN_ERR "dma_region_alloc: pci_map_sg() failed\n");
@@ -120,7 +114,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
return 0;
- err:
+err:
dma_region_free(dma);
return -ENOMEM;
}
@@ -128,8 +122,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
void dma_region_free(struct dma_region *dma)
{
if (dma->n_dma_pages) {
- pci_unmap_sg(dma->dev, dma->sglist, dma->n_pages,
- dma->direction);
+ pci_unmap_sg(dma->dev, dma->sglist, dma->n_pages, dma->direction);
dma->n_dma_pages = 0;
dma->dev = NULL;
}
@@ -144,8 +137,7 @@ void dma_region_free(struct dma_region *dma)
/* find the scatterlist index and remaining offset corresponding to a
given offset from the beginning of the buffer */
-static inline int dma_region_find(struct dma_region *dma, unsigned long offset,
- unsigned long *rem)
+static inline int dma_region_find(struct dma_region *dma, unsigned long offset, unsigned long *rem)
{
int i;
unsigned long off = offset;
@@ -164,18 +156,15 @@ static inline int dma_region_find(struct dma_region *dma, unsigned long offset,
return i;
}
-dma_addr_t dma_region_offset_to_bus(struct dma_region * dma,
- unsigned long offset)
+dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset)
{
unsigned long rem = 0;
- struct scatterlist *sg =
- &dma->sglist[dma_region_find(dma, offset, &rem)];
+ struct scatterlist *sg = &dma->sglist[dma_region_find(dma, offset, &rem)];
return sg_dma_address(sg) + rem;
}
-void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset,
- unsigned long len)
+void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset, unsigned long len)
{
int first, last;
unsigned long rem;
@@ -186,12 +175,10 @@ void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset,
first = dma_region_find(dma, offset, &rem);
last = dma_region_find(dma, offset + len - 1, &rem);
- pci_dma_sync_sg_for_cpu(dma->dev, &dma->sglist[first], last - first + 1,
- dma->direction);
+ pci_dma_sync_sg_for_cpu(dma->dev, &dma->sglist[first], last - first + 1, dma->direction);
}
-void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset,
- unsigned long len)
+void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset, unsigned long len)
{
int first, last;
unsigned long rem;
@@ -202,47 +189,44 @@ void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset,
first = dma_region_find(dma, offset, &rem);
last = dma_region_find(dma, offset + len - 1, &rem);
- pci_dma_sync_sg_for_device(dma->dev, &dma->sglist[first],
- last - first + 1, dma->direction);
+ pci_dma_sync_sg_for_device(dma->dev, &dma->sglist[first], last - first + 1, dma->direction);
}
#ifdef CONFIG_MMU
/* nopage() handler for mmap access */
-static struct page *dma_region_pagefault(struct vm_area_struct *area,
- unsigned long address, int *type)
+static struct page*
+dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int *type)
{
unsigned long offset;
unsigned long kernel_virt_addr;
struct page *ret = NOPAGE_SIGBUS;
- struct dma_region *dma = (struct dma_region *)area->vm_private_data;
+ struct dma_region *dma = (struct dma_region*) area->vm_private_data;
if (!dma->kvirt)
goto out;
- if ((address < (unsigned long)area->vm_start) ||
- (address >
- (unsigned long)area->vm_start + (dma->n_pages << PAGE_SHIFT)))
+ if ( (address < (unsigned long) area->vm_start) ||
+ (address > (unsigned long) area->vm_start + (dma->n_pages << PAGE_SHIFT)) )
goto out;
if (type)
*type = VM_FAULT_MINOR;
offset = address - area->vm_start;
- kernel_virt_addr = (unsigned long)dma->kvirt + offset;
- ret = vmalloc_to_page((void *)kernel_virt_addr);
+ kernel_virt_addr = (unsigned long) dma->kvirt + offset;
+ ret = vmalloc_to_page((void*) kernel_virt_addr);
get_page(ret);
- out:
+out:
return ret;
}
static struct vm_operations_struct dma_region_vm_ops = {
- .nopage = dma_region_pagefault,
+ .nopage = dma_region_pagefault,
};
-int dma_region_mmap(struct dma_region *dma, struct file *file,
- struct vm_area_struct *vma)
+int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma)
{
unsigned long size;
@@ -266,12 +250,11 @@ int dma_region_mmap(struct dma_region *dma, struct file *file,
return 0;
}
-#else /* CONFIG_MMU */
+#else /* CONFIG_MMU */
-int dma_region_mmap(struct dma_region *dma, struct file *file,
- struct vm_area_struct *vma)
+int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma)
{
return -EINVAL;
}
-#endif /* CONFIG_MMU */
+#endif /* CONFIG_MMU */
diff --git a/trunk/drivers/ieee1394/dv1394.c b/trunk/drivers/ieee1394/dv1394.c
index 196db7439272..cbbbe14b8849 100644
--- a/trunk/drivers/ieee1394/dv1394.c
+++ b/trunk/drivers/ieee1394/dv1394.c
@@ -123,6 +123,15 @@
#include "ohci1394.h"
+#ifndef virt_to_page
+#define virt_to_page(x) MAP_NR(x)
+#endif
+
+#ifndef vmalloc_32
+#define vmalloc_32(x) vmalloc(x)
+#endif
+
+
/* DEBUG LEVELS:
0 - no debugging messages
1 - some debugging messages, but none during DMA frame transmission
@@ -2209,12 +2218,14 @@ static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes
unsigned long flags;
int i;
- video = kzalloc(sizeof(*video), GFP_KERNEL);
+ video = kmalloc(sizeof(struct video_card), GFP_KERNEL);
if (!video) {
printk(KERN_ERR "dv1394: cannot allocate video_card\n");
goto err;
}
+ memset(video, 0, sizeof(struct video_card));
+
video->ohci = ohci;
/* lower 2 bits of id indicate which of four "plugs"
per host */
diff --git a/trunk/drivers/ieee1394/eth1394.c b/trunk/drivers/ieee1394/eth1394.c
index 30fa0d43a43a..c9e92d85c893 100644
--- a/trunk/drivers/ieee1394/eth1394.c
+++ b/trunk/drivers/ieee1394/eth1394.c
@@ -88,6 +88,9 @@
printk(KERN_ERR "%s:%s[%d]: " fmt "\n", driver_name, __FUNCTION__, __LINE__, ## args)
#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
+static char version[] __devinitdata =
+ "$Rev: 1312 $ Ben Collins ";
+
struct fragment_info {
struct list_head list;
int offset;
@@ -352,12 +355,12 @@ static int eth1394_probe(struct device *dev)
if (!hi)
return -ENOENT;
- new_node = kmalloc(sizeof(*new_node),
+ new_node = kmalloc(sizeof(struct eth1394_node_ref),
in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
if (!new_node)
return -ENOMEM;
- node_info = kmalloc(sizeof(*node_info),
+ node_info = kmalloc(sizeof(struct eth1394_node_info),
in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
if (!node_info) {
kfree(new_node);
@@ -433,12 +436,12 @@ static int eth1394_update(struct unit_directory *ud)
node = eth1394_find_node(&priv->ip_node_list, ud);
if (!node) {
- node = kmalloc(sizeof(*node),
+ node = kmalloc(sizeof(struct eth1394_node_ref),
in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
if (!node)
return -ENOMEM;
- node_info = kmalloc(sizeof(*node_info),
+ node_info = kmalloc(sizeof(struct eth1394_node_info),
in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
if (!node_info) {
kfree(node);
@@ -563,6 +566,7 @@ static void ether1394_add_host (struct hpsb_host *host)
struct eth1394_host_info *hi = NULL;
struct net_device *dev = NULL;
struct eth1394_priv *priv;
+ static int version_printed = 0;
u64 fifo_addr;
if (!(host->config_roms & HPSB_CONFIG_ROM_ENTRY_IP1394))
@@ -577,6 +581,9 @@ static void ether1394_add_host (struct hpsb_host *host)
if (fifo_addr == ~0ULL)
goto out;
+ if (version_printed++ == 0)
+ ETH1394_PRINT_G (KERN_INFO, "%s\n", version);
+
/* We should really have our own alloc_hpsbdev() function in
* net_init.c instead of calling the one for ethernet then hijacking
* it for ourselves. That way we'd be a real networking device. */
@@ -1014,7 +1021,7 @@ static inline int new_fragment(struct list_head *frag_info, int offset, int len)
}
}
- new = kmalloc(sizeof(*new), GFP_ATOMIC);
+ new = kmalloc(sizeof(struct fragment_info), GFP_ATOMIC);
if (!new)
return -ENOMEM;
@@ -1033,7 +1040,7 @@ static inline int new_partial_datagram(struct net_device *dev,
{
struct partial_datagram *new;
- new = kmalloc(sizeof(*new), GFP_ATOMIC);
+ new = kmalloc(sizeof(struct partial_datagram), GFP_ATOMIC);
if (!new)
return -ENOMEM;
@@ -1761,6 +1768,7 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
static void ether1394_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
strcpy (info->driver, driver_name);
+ strcpy (info->version, "$Rev: 1312 $");
/* FIXME XXX provide sane businfo */
strcpy (info->bus_info, "ieee1394");
}
diff --git a/trunk/drivers/ieee1394/highlevel.c b/trunk/drivers/ieee1394/highlevel.c
index 734b121a0554..997e1bf6297f 100644
--- a/trunk/drivers/ieee1394/highlevel.c
+++ b/trunk/drivers/ieee1394/highlevel.c
@@ -101,10 +101,12 @@ void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
return NULL;
}
- hi = kzalloc(sizeof(*hi) + data_size, GFP_ATOMIC);
+ hi = kmalloc(sizeof(*hi) + data_size, GFP_ATOMIC);
if (!hi)
return NULL;
+ memset(hi, 0, sizeof(*hi) + data_size);
+
if (data_size) {
data = hi->data = hi + 1;
hi->size = data_size;
@@ -324,9 +326,11 @@ u64 hpsb_allocate_and_register_addrspace(struct hpsb_highlevel *hl,
return retval;
}
- as = kmalloc(sizeof(*as), GFP_KERNEL);
- if (!as)
+ as = (struct hpsb_address_serve *)
+ kmalloc(sizeof(struct hpsb_address_serve), GFP_KERNEL);
+ if (as == NULL) {
return retval;
+ }
INIT_LIST_HEAD(&as->host_list);
INIT_LIST_HEAD(&as->hl_list);
@@ -379,9 +383,11 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
return 0;
}
- as = kmalloc(sizeof(*as), GFP_ATOMIC);
- if (!as)
- return 0;
+ as = (struct hpsb_address_serve *)
+ kmalloc(sizeof(struct hpsb_address_serve), GFP_ATOMIC);
+ if (as == NULL) {
+ return 0;
+ }
INIT_LIST_HEAD(&as->host_list);
INIT_LIST_HEAD(&as->hl_list);
diff --git a/trunk/drivers/ieee1394/hosts.c b/trunk/drivers/ieee1394/hosts.c
index ba09741fc826..aeeaeb670d03 100644
--- a/trunk/drivers/ieee1394/hosts.c
+++ b/trunk/drivers/ieee1394/hosts.c
@@ -61,12 +61,12 @@ static void delayed_reset_bus(void * __reset_info)
static int dummy_transmit_packet(struct hpsb_host *h, struct hpsb_packet *p)
{
- return 0;
+ return 0;
}
static int dummy_devctl(struct hpsb_host *h, enum devctl_cmd c, int arg)
{
- return -1;
+ return -1;
}
static int dummy_isoctl(struct hpsb_iso *iso, enum isoctl_cmd command, unsigned long arg)
@@ -75,9 +75,9 @@ static int dummy_isoctl(struct hpsb_iso *iso, enum isoctl_cmd command, unsigned
}
static struct hpsb_host_driver dummy_driver = {
- .transmit_packet = dummy_transmit_packet,
- .devctl = dummy_devctl,
- .isoctl = dummy_isoctl
+ .transmit_packet = dummy_transmit_packet,
+ .devctl = dummy_devctl,
+ .isoctl = dummy_isoctl
};
static int alloc_hostnum_cb(struct hpsb_host *host, void *__data)
@@ -110,13 +110,13 @@ static DECLARE_MUTEX(host_num_alloc);
struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
struct device *dev)
{
- struct hpsb_host *h;
+ struct hpsb_host *h;
int i;
int hostnum = 0;
- h = kzalloc(sizeof(*h) + extra, SLAB_KERNEL);
- if (!h)
- return NULL;
+ h = kmalloc(sizeof(struct hpsb_host) + extra, SLAB_KERNEL);
+ if (!h) return NULL;
+ memset(h, 0, sizeof(struct hpsb_host) + extra);
h->csr.rom = csr1212_create_csr(&csr_bus_ops, CSR_BUS_INFO_SIZE, h);
if (!h->csr.rom) {
@@ -125,7 +125,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
}
h->hostdata = h + 1;
- h->driver = drv;
+ h->driver = drv;
skb_queue_head_init(&h->pending_packet_queue);
INIT_LIST_HEAD(&h->addr_space);
@@ -145,8 +145,8 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
h->timeout.function = abort_timedouts;
h->timeout_interval = HZ / 20; // 50ms by default
- h->topology_map = h->csr.topology_map + 3;
- h->speed_map = (u8 *)(h->csr.speed_map + 2);
+ h->topology_map = h->csr.topology_map + 3;
+ h->speed_map = (u8 *)(h->csr.speed_map + 2);
down(&host_num_alloc);
@@ -186,14 +186,14 @@ int hpsb_add_host(struct hpsb_host *host)
void hpsb_remove_host(struct hpsb_host *host)
{
- host->is_shutdown = 1;
+ host->is_shutdown = 1;
cancel_delayed_work(&host->delayed_reset);
flush_scheduled_work();
- host->driver = &dummy_driver;
+ host->driver = &dummy_driver;
- highlevel_remove_host(host);
+ highlevel_remove_host(host);
hpsb_remove_extra_config_roms(host);
diff --git a/trunk/drivers/ieee1394/hosts.h b/trunk/drivers/ieee1394/hosts.h
index 07d188ca8495..ae9b02cc013f 100644
--- a/trunk/drivers/ieee1394/hosts.h
+++ b/trunk/drivers/ieee1394/hosts.h
@@ -17,47 +17,47 @@ struct hpsb_packet;
struct hpsb_iso;
struct hpsb_host {
- struct list_head host_list;
+ struct list_head host_list;
- void *hostdata;
+ void *hostdata;
- atomic_t generation;
+ atomic_t generation;
struct sk_buff_head pending_packet_queue;
struct timer_list timeout;
unsigned long timeout_interval;
- unsigned char iso_listen_count[64];
+ unsigned char iso_listen_count[64];
- int node_count; /* number of identified nodes on this bus */
- int selfid_count; /* total number of SelfIDs received */
+ int node_count; /* number of identified nodes on this bus */
+ int selfid_count; /* total number of SelfIDs received */
int nodes_active; /* number of nodes that are actually active */
- nodeid_t node_id; /* node ID of this host */
- nodeid_t irm_id; /* ID of this bus' isochronous resource manager */
- nodeid_t busmgr_id; /* ID of this bus' bus manager */
+ nodeid_t node_id; /* node ID of this host */
+ nodeid_t irm_id; /* ID of this bus' isochronous resource manager */
+ nodeid_t busmgr_id; /* ID of this bus' bus manager */
- /* this nodes state */
- unsigned in_bus_reset:1;
- unsigned is_shutdown:1;
+ /* this nodes state */
+ unsigned in_bus_reset:1;
+ unsigned is_shutdown:1;
unsigned resume_packet_sent:1;
- /* this nodes' duties on the bus */
- unsigned is_root:1;
- unsigned is_cycmst:1;
- unsigned is_irm:1;
- unsigned is_busmgr:1;
+ /* this nodes' duties on the bus */
+ unsigned is_root:1;
+ unsigned is_cycmst:1;
+ unsigned is_irm:1;
+ unsigned is_busmgr:1;
- int reset_retries;
- quadlet_t *topology_map;
- u8 *speed_map;
- struct csr_control csr;
+ int reset_retries;
+ quadlet_t *topology_map;
+ u8 *speed_map;
+ struct csr_control csr;
/* Per node tlabel pool allocation */
struct hpsb_tlabel_pool tpool[64];
- struct hpsb_host_driver *driver;
+ struct hpsb_host_driver *driver;
struct pci_dev *pdev;
@@ -77,34 +77,34 @@ struct hpsb_host {
enum devctl_cmd {
- /* Host is requested to reset its bus and cancel all outstanding async
- * requests. If arg == 1, it shall also attempt to become root on the
- * bus. Return void. */
- RESET_BUS,
-
- /* Arg is void, return value is the hardware cycle counter value. */
- GET_CYCLE_COUNTER,
-
- /* Set the hardware cycle counter to the value in arg, return void.
- * FIXME - setting is probably not required. */
- SET_CYCLE_COUNTER,
-
- /* Configure hardware for new bus ID in arg, return void. */
- SET_BUS_ID,
-
- /* If arg true, start sending cycle start packets, stop if arg == 0.
- * Return void. */
- ACT_CYCLE_MASTER,
-
- /* Cancel all outstanding async requests without resetting the bus.
- * Return void. */
- CANCEL_REQUESTS,
-
- /* Start or stop receiving isochronous channel in arg. Return void.
- * This acts as an optimization hint, hosts are not required not to
- * listen on unrequested channels. */
- ISO_LISTEN_CHANNEL,
- ISO_UNLISTEN_CHANNEL
+ /* Host is requested to reset its bus and cancel all outstanding async
+ * requests. If arg == 1, it shall also attempt to become root on the
+ * bus. Return void. */
+ RESET_BUS,
+
+ /* Arg is void, return value is the hardware cycle counter value. */
+ GET_CYCLE_COUNTER,
+
+ /* Set the hardware cycle counter to the value in arg, return void.
+ * FIXME - setting is probably not required. */
+ SET_CYCLE_COUNTER,
+
+ /* Configure hardware for new bus ID in arg, return void. */
+ SET_BUS_ID,
+
+ /* If arg true, start sending cycle start packets, stop if arg == 0.
+ * Return void. */
+ ACT_CYCLE_MASTER,
+
+ /* Cancel all outstanding async requests without resetting the bus.
+ * Return void. */
+ CANCEL_REQUESTS,
+
+ /* Start or stop receiving isochronous channel in arg. Return void.
+ * This acts as an optimization hint, hosts are not required not to
+ * listen on unrequested channels. */
+ ISO_LISTEN_CHANNEL,
+ ISO_UNLISTEN_CHANNEL
};
enum isoctl_cmd {
@@ -135,13 +135,13 @@ enum isoctl_cmd {
};
enum reset_types {
- /* 166 microsecond reset -- only type of reset available on
- non-1394a capable controllers */
- LONG_RESET,
+ /* 166 microsecond reset -- only type of reset available on
+ non-1394a capable controllers */
+ LONG_RESET,
- /* Short (arbitrated) reset -- only available on 1394a capable
- controllers */
- SHORT_RESET,
+ /* Short (arbitrated) reset -- only available on 1394a capable
+ controllers */
+ SHORT_RESET,
/* Variants that set force_root before issueing the bus reset */
LONG_RESET_FORCE_ROOT, SHORT_RESET_FORCE_ROOT,
@@ -159,22 +159,22 @@ struct hpsb_host_driver {
* reads to the ConfigROM on its own. */
void (*set_hw_config_rom) (struct hpsb_host *host, quadlet_t *config_rom);
- /* This function shall implement packet transmission based on
- * packet->type. It shall CRC both parts of the packet (unless
- * packet->type == raw) and do byte-swapping as necessary or instruct
- * the hardware to do so. It can return immediately after the packet
- * was queued for sending. After sending, hpsb_sent_packet() has to be
- * called. Return 0 on success, negative errno on failure.
- * NOTE: The function must be callable in interrupt context.
- */
- int (*transmit_packet) (struct hpsb_host *host,
- struct hpsb_packet *packet);
-
- /* This function requests miscellanous services from the driver, see
- * above for command codes and expected actions. Return -1 for unknown
- * command, though that should never happen.
- */
- int (*devctl) (struct hpsb_host *host, enum devctl_cmd command, int arg);
+ /* This function shall implement packet transmission based on
+ * packet->type. It shall CRC both parts of the packet (unless
+ * packet->type == raw) and do byte-swapping as necessary or instruct
+ * the hardware to do so. It can return immediately after the packet
+ * was queued for sending. After sending, hpsb_sent_packet() has to be
+ * called. Return 0 on success, negative errno on failure.
+ * NOTE: The function must be callable in interrupt context.
+ */
+ int (*transmit_packet) (struct hpsb_host *host,
+ struct hpsb_packet *packet);
+
+ /* This function requests miscellanous services from the driver, see
+ * above for command codes and expected actions. Return -1 for unknown
+ * command, though that should never happen.
+ */
+ int (*devctl) (struct hpsb_host *host, enum devctl_cmd command, int arg);
/* ISO transmission/reception functions. Return 0 on success, -1
* (or -EXXX errno code) on failure. If the low-level driver does not
@@ -182,15 +182,15 @@ struct hpsb_host_driver {
*/
int (*isoctl) (struct hpsb_iso *iso, enum isoctl_cmd command, unsigned long arg);
- /* This function is mainly to redirect local CSR reads/locks to the iso
- * management registers (bus manager id, bandwidth available, channels
- * available) to the hardware registers in OHCI. reg is 0,1,2,3 for bus
- * mgr, bwdth avail, ch avail hi, ch avail lo respectively (the same ids
- * as OHCI uses). data and compare are the new data and expected data
- * respectively, return value is the old value.
- */
- quadlet_t (*hw_csr_reg) (struct hpsb_host *host, int reg,
- quadlet_t data, quadlet_t compare);
+ /* This function is mainly to redirect local CSR reads/locks to the iso
+ * management registers (bus manager id, bandwidth available, channels
+ * available) to the hardware registers in OHCI. reg is 0,1,2,3 for bus
+ * mgr, bwdth avail, ch avail hi, ch avail lo respectively (the same ids
+ * as OHCI uses). data and compare are the new data and expected data
+ * respectively, return value is the old value.
+ */
+ quadlet_t (*hw_csr_reg) (struct hpsb_host *host, int reg,
+ quadlet_t data, quadlet_t compare);
};
diff --git a/trunk/drivers/ieee1394/ieee1394-ioctl.h b/trunk/drivers/ieee1394/ieee1394-ioctl.h
index 156703986348..f92b566363d5 100644
--- a/trunk/drivers/ieee1394/ieee1394-ioctl.h
+++ b/trunk/drivers/ieee1394/ieee1394-ioctl.h
@@ -7,6 +7,14 @@
#include
#include
+
+/* AMDTP Gets 6 */
+#define AMDTP_IOC_CHANNEL _IOW('#', 0x00, struct amdtp_ioctl)
+#define AMDTP_IOC_PLUG _IOW('#', 0x01, struct amdtp_ioctl)
+#define AMDTP_IOC_PING _IOW('#', 0x02, struct amdtp_ioctl)
+#define AMDTP_IOC_ZAP _IO ('#', 0x03)
+
+
/* DV1394 Gets 10 */
/* Get the driver ready to transmit video. pass a struct dv1394_init* as
diff --git a/trunk/drivers/ieee1394/ieee1394.h b/trunk/drivers/ieee1394/ieee1394.h
index 936d776de00a..b634a9bb365c 100644
--- a/trunk/drivers/ieee1394/ieee1394.h
+++ b/trunk/drivers/ieee1394/ieee1394.h
@@ -62,7 +62,6 @@
extern const char *hpsb_speedto_str[];
-/* 1394a cable PHY packets */
#define SELFID_PWRCL_NO_POWER 0x0
#define SELFID_PWRCL_PROVIDE_15W 0x1
#define SELFID_PWRCL_PROVIDE_30W 0x2
@@ -77,24 +76,8 @@ extern const char *hpsb_speedto_str[];
#define SELFID_PORT_NCONN 0x1
#define SELFID_PORT_NONE 0x0
-#define PHYPACKET_LINKON 0x40000000
-#define PHYPACKET_PHYCONFIG_R 0x00800000
-#define PHYPACKET_PHYCONFIG_T 0x00400000
-#define EXTPHYPACKET_TYPE_PING 0x00000000
-#define EXTPHYPACKET_TYPE_REMOTEACCESS_BASE 0x00040000
-#define EXTPHYPACKET_TYPE_REMOTEACCESS_PAGED 0x00140000
-#define EXTPHYPACKET_TYPE_REMOTEREPLY_BASE 0x000C0000
-#define EXTPHYPACKET_TYPE_REMOTEREPLY_PAGED 0x001C0000
-#define EXTPHYPACKET_TYPE_REMOTECOMMAND 0x00200000
-#define EXTPHYPACKET_TYPE_REMOTECONFIRMATION 0x00280000
-#define EXTPHYPACKET_TYPE_RESUME 0x003C0000
-#define EXTPHYPACKET_TYPEMASK 0xC0FC0000
-
-#define PHYPACKET_PORT_SHIFT 24
-#define PHYPACKET_GAPCOUNT_SHIFT 16
-
-/* 1394a PHY register map bitmasks */
+/* 1394a PHY bitmasks */
#define PHY_00_PHYSICAL_ID 0xFC
#define PHY_00_R 0x02 /* Root */
#define PHY_00_PS 0x01 /* Power Status*/
diff --git a/trunk/drivers/ieee1394/ieee1394_core.c b/trunk/drivers/ieee1394/ieee1394_core.c
index 64fbbb01d52a..32a1e016c85e 100644
--- a/trunk/drivers/ieee1394/ieee1394_core.c
+++ b/trunk/drivers/ieee1394/ieee1394_core.c
@@ -179,34 +179,34 @@ void hpsb_free_packet(struct hpsb_packet *packet)
int hpsb_reset_bus(struct hpsb_host *host, int type)
{
- if (!host->in_bus_reset) {
- host->driver->devctl(host, RESET_BUS, type);
- return 0;
- } else {
- return 1;
- }
+ if (!host->in_bus_reset) {
+ host->driver->devctl(host, RESET_BUS, type);
+ return 0;
+ } else {
+ return 1;
+ }
}
int hpsb_bus_reset(struct hpsb_host *host)
{
- if (host->in_bus_reset) {
- HPSB_NOTICE("%s called while bus reset already in progress",
+ if (host->in_bus_reset) {
+ HPSB_NOTICE("%s called while bus reset already in progress",
__FUNCTION__);
- return 1;
- }
+ return 1;
+ }
- abort_requests(host);
- host->in_bus_reset = 1;
- host->irm_id = -1;
+ abort_requests(host);
+ host->in_bus_reset = 1;
+ host->irm_id = -1;
host->is_irm = 0;
- host->busmgr_id = -1;
+ host->busmgr_id = -1;
host->is_busmgr = 0;
host->is_cycmst = 0;
- host->node_count = 0;
- host->selfid_count = 0;
+ host->node_count = 0;
+ host->selfid_count = 0;
- return 0;
+ return 0;
}
@@ -216,156 +216,150 @@ int hpsb_bus_reset(struct hpsb_host *host)
*/
static int check_selfids(struct hpsb_host *host)
{
- int nodeid = -1;
- int rest_of_selfids = host->selfid_count;
- struct selfid *sid = (struct selfid *)host->topology_map;
- struct ext_selfid *esid;
- int esid_seq = 23;
+ int nodeid = -1;
+ int rest_of_selfids = host->selfid_count;
+ struct selfid *sid = (struct selfid *)host->topology_map;
+ struct ext_selfid *esid;
+ int esid_seq = 23;
host->nodes_active = 0;
- while (rest_of_selfids--) {
- if (!sid->extended) {
- nodeid++;
- esid_seq = 0;
+ while (rest_of_selfids--) {
+ if (!sid->extended) {
+ nodeid++;
+ esid_seq = 0;
- if (sid->phy_id != nodeid) {
- HPSB_INFO("SelfIDs failed monotony check with "
- "%d", sid->phy_id);
- return 0;
- }
+ if (sid->phy_id != nodeid) {
+ HPSB_INFO("SelfIDs failed monotony check with "
+ "%d", sid->phy_id);
+ return 0;
+ }
if (sid->link_active) {
host->nodes_active++;
if (sid->contender)
host->irm_id = LOCAL_BUS | sid->phy_id;
}
- } else {
- esid = (struct ext_selfid *)sid;
-
- if ((esid->phy_id != nodeid)
- || (esid->seq_nr != esid_seq)) {
- HPSB_INFO("SelfIDs failed monotony check with "
- "%d/%d", esid->phy_id, esid->seq_nr);
- return 0;
- }
- esid_seq++;
- }
- sid++;
- }
-
- esid = (struct ext_selfid *)(sid - 1);
- while (esid->extended) {
- if ((esid->porta == SELFID_PORT_PARENT) ||
- (esid->portb == SELFID_PORT_PARENT) ||
- (esid->portc == SELFID_PORT_PARENT) ||
- (esid->portd == SELFID_PORT_PARENT) ||
- (esid->porte == SELFID_PORT_PARENT) ||
- (esid->portf == SELFID_PORT_PARENT) ||
- (esid->portg == SELFID_PORT_PARENT) ||
- (esid->porth == SELFID_PORT_PARENT)) {
+ } else {
+ esid = (struct ext_selfid *)sid;
+
+ if ((esid->phy_id != nodeid)
+ || (esid->seq_nr != esid_seq)) {
+ HPSB_INFO("SelfIDs failed monotony check with "
+ "%d/%d", esid->phy_id, esid->seq_nr);
+ return 0;
+ }
+ esid_seq++;
+ }
+ sid++;
+ }
+
+ esid = (struct ext_selfid *)(sid - 1);
+ while (esid->extended) {
+ if ((esid->porta == 0x2) || (esid->portb == 0x2)
+ || (esid->portc == 0x2) || (esid->portd == 0x2)
+ || (esid->porte == 0x2) || (esid->portf == 0x2)
+ || (esid->portg == 0x2) || (esid->porth == 0x2)) {
HPSB_INFO("SelfIDs failed root check on "
"extended SelfID");
return 0;
- }
- esid--;
- }
+ }
+ esid--;
+ }
- sid = (struct selfid *)esid;
- if ((sid->port0 == SELFID_PORT_PARENT) ||
- (sid->port1 == SELFID_PORT_PARENT) ||
- (sid->port2 == SELFID_PORT_PARENT)) {
+ sid = (struct selfid *)esid;
+ if ((sid->port0 == 0x2) || (sid->port1 == 0x2) || (sid->port2 == 0x2)) {
HPSB_INFO("SelfIDs failed root check");
return 0;
- }
+ }
host->node_count = nodeid + 1;
- return 1;
+ return 1;
}
static void build_speed_map(struct hpsb_host *host, int nodecount)
{
u8 speedcap[nodecount];
u8 cldcnt[nodecount];
- u8 *map = host->speed_map;
- struct selfid *sid;
- struct ext_selfid *esid;
- int i, j, n;
-
- for (i = 0; i < (nodecount * 64); i += 64) {
- for (j = 0; j < nodecount; j++) {
- map[i+j] = IEEE1394_SPEED_MAX;
- }
- }
-
- for (i = 0; i < nodecount; i++) {
- cldcnt[i] = 0;
- }
-
- /* find direct children count and speed */
- for (sid = (struct selfid *)&host->topology_map[host->selfid_count-1],
- n = nodecount - 1;
- (void *)sid >= (void *)host->topology_map; sid--) {
- if (sid->extended) {
- esid = (struct ext_selfid *)sid;
-
- if (esid->porta == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->portb == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->portc == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->portd == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->porte == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->portf == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->portg == SELFID_PORT_CHILD) cldcnt[n]++;
- if (esid->porth == SELFID_PORT_CHILD) cldcnt[n]++;
+ u8 *map = host->speed_map;
+ struct selfid *sid;
+ struct ext_selfid *esid;
+ int i, j, n;
+
+ for (i = 0; i < (nodecount * 64); i += 64) {
+ for (j = 0; j < nodecount; j++) {
+ map[i+j] = IEEE1394_SPEED_MAX;
+ }
+ }
+
+ for (i = 0; i < nodecount; i++) {
+ cldcnt[i] = 0;
+ }
+
+ /* find direct children count and speed */
+ for (sid = (struct selfid *)&host->topology_map[host->selfid_count-1],
+ n = nodecount - 1;
+ (void *)sid >= (void *)host->topology_map; sid--) {
+ if (sid->extended) {
+ esid = (struct ext_selfid *)sid;
+
+ if (esid->porta == 0x3) cldcnt[n]++;
+ if (esid->portb == 0x3) cldcnt[n]++;
+ if (esid->portc == 0x3) cldcnt[n]++;
+ if (esid->portd == 0x3) cldcnt[n]++;
+ if (esid->porte == 0x3) cldcnt[n]++;
+ if (esid->portf == 0x3) cldcnt[n]++;
+ if (esid->portg == 0x3) cldcnt[n]++;
+ if (esid->porth == 0x3) cldcnt[n]++;
} else {
- if (sid->port0 == SELFID_PORT_CHILD) cldcnt[n]++;
- if (sid->port1 == SELFID_PORT_CHILD) cldcnt[n]++;
- if (sid->port2 == SELFID_PORT_CHILD) cldcnt[n]++;
-
- speedcap[n] = sid->speed;
- n--;
- }
- }
-
- /* set self mapping */
- for (i = 0; i < nodecount; i++) {
- map[64*i + i] = speedcap[i];
- }
-
- /* fix up direct children count to total children count;
- * also fix up speedcaps for sibling and parent communication */
- for (i = 1; i < nodecount; i++) {
- for (j = cldcnt[i], n = i - 1; j > 0; j--) {
- cldcnt[i] += cldcnt[n];
- speedcap[n] = min(speedcap[n], speedcap[i]);
- n -= cldcnt[n] + 1;
- }
- }
-
- for (n = 0; n < nodecount; n++) {
- for (i = n - cldcnt[n]; i <= n; i++) {
- for (j = 0; j < (n - cldcnt[n]); j++) {
- map[j*64 + i] = map[i*64 + j] =
- min(map[i*64 + j], speedcap[n]);
- }
- for (j = n + 1; j < nodecount; j++) {
- map[j*64 + i] = map[i*64 + j] =
- min(map[i*64 + j], speedcap[n]);
- }
- }
- }
+ if (sid->port0 == 0x3) cldcnt[n]++;
+ if (sid->port1 == 0x3) cldcnt[n]++;
+ if (sid->port2 == 0x3) cldcnt[n]++;
+
+ speedcap[n] = sid->speed;
+ n--;
+ }
+ }
+
+ /* set self mapping */
+ for (i = 0; i < nodecount; i++) {
+ map[64*i + i] = speedcap[i];
+ }
+
+ /* fix up direct children count to total children count;
+ * also fix up speedcaps for sibling and parent communication */
+ for (i = 1; i < nodecount; i++) {
+ for (j = cldcnt[i], n = i - 1; j > 0; j--) {
+ cldcnt[i] += cldcnt[n];
+ speedcap[n] = min(speedcap[n], speedcap[i]);
+ n -= cldcnt[n] + 1;
+ }
+ }
+
+ for (n = 0; n < nodecount; n++) {
+ for (i = n - cldcnt[n]; i <= n; i++) {
+ for (j = 0; j < (n - cldcnt[n]); j++) {
+ map[j*64 + i] = map[i*64 + j] =
+ min(map[i*64 + j], speedcap[n]);
+ }
+ for (j = n + 1; j < nodecount; j++) {
+ map[j*64 + i] = map[i*64 + j] =
+ min(map[i*64 + j], speedcap[n]);
+ }
+ }
+ }
}
void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid)
{
- if (host->in_bus_reset) {
- HPSB_VERBOSE("Including SelfID 0x%x", sid);
- host->topology_map[host->selfid_count++] = sid;
- } else {
- HPSB_NOTICE("Spurious SelfID packet (0x%08x) received from bus %d",
+ if (host->in_bus_reset) {
+ HPSB_VERBOSE("Including SelfID 0x%x", sid);
+ host->topology_map[host->selfid_count++] = sid;
+ } else {
+ HPSB_NOTICE("Spurious SelfID packet (0x%08x) received from bus %d",
sid, NODEID_TO_BUS(host->node_id));
- }
+ }
}
void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
@@ -373,50 +367,50 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
if (!host->in_bus_reset)
HPSB_NOTICE("SelfID completion called outside of bus reset!");
- host->node_id = LOCAL_BUS | phyid;
- host->is_root = isroot;
+ host->node_id = LOCAL_BUS | phyid;
+ host->is_root = isroot;
- if (!check_selfids(host)) {
- if (host->reset_retries++ < 20) {
- /* selfid stage did not complete without error */
- HPSB_NOTICE("Error in SelfID stage, resetting");
+ if (!check_selfids(host)) {
+ if (host->reset_retries++ < 20) {
+ /* selfid stage did not complete without error */
+ HPSB_NOTICE("Error in SelfID stage, resetting");
host->in_bus_reset = 0;
/* this should work from ohci1394 now... */
- hpsb_reset_bus(host, LONG_RESET);
- return;
- } else {
- HPSB_NOTICE("Stopping out-of-control reset loop");
- HPSB_NOTICE("Warning - topology map and speed map will not be valid");
+ hpsb_reset_bus(host, LONG_RESET);
+ return;
+ } else {
+ HPSB_NOTICE("Stopping out-of-control reset loop");
+ HPSB_NOTICE("Warning - topology map and speed map will not be valid");
host->reset_retries = 0;
- }
- } else {
+ }
+ } else {
host->reset_retries = 0;
- build_speed_map(host, host->node_count);
- }
+ build_speed_map(host, host->node_count);
+ }
HPSB_VERBOSE("selfid_complete called with successful SelfID stage "
"... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id);
- /* irm_id is kept up to date by check_selfids() */
- if (host->irm_id == host->node_id) {
- host->is_irm = 1;
- } else {
- host->is_busmgr = 0;
- host->is_irm = 0;
- }
+ /* irm_id is kept up to date by check_selfids() */
+ if (host->irm_id == host->node_id) {
+ host->is_irm = 1;
+ } else {
+ host->is_busmgr = 0;
+ host->is_irm = 0;
+ }
- if (isroot) {
+ if (isroot) {
host->driver->devctl(host, ACT_CYCLE_MASTER, 1);
host->is_cycmst = 1;
}
atomic_inc(&host->generation);
host->in_bus_reset = 0;
- highlevel_host_reset(host);
+ highlevel_host_reset(host);
}
void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
- int ackcode)
+ int ackcode)
{
unsigned long flags;
@@ -463,7 +457,6 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt)
{
struct hpsb_packet *packet;
- quadlet_t d = 0;
int retval = 0;
if (rootid >= ALL_NODES || rootid < -1 || gapcnt > 0x3f || gapcnt < -1 ||
@@ -473,16 +466,26 @@ int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt)
return -EINVAL;
}
+ packet = hpsb_alloc_packet(0);
+ if (!packet)
+ return -ENOMEM;
+
+ packet->host = host;
+ packet->header_size = 8;
+ packet->data_size = 0;
+ packet->expect_response = 0;
+ packet->no_waiter = 0;
+ packet->type = hpsb_raw;
+ packet->header[0] = 0;
if (rootid != -1)
- d |= PHYPACKET_PHYCONFIG_R | rootid << PHYPACKET_PORT_SHIFT;
+ packet->header[0] |= rootid << 24 | 1 << 23;
if (gapcnt != -1)
- d |= PHYPACKET_PHYCONFIG_T | gapcnt << PHYPACKET_GAPCOUNT_SHIFT;
+ packet->header[0] |= gapcnt << 16 | 1 << 22;
- packet = hpsb_make_phypacket(host, d);
- if (!packet)
- return -ENOMEM;
+ packet->header[1] = ~packet->header[0];
packet->generation = get_hpsb_generation(host);
+
retval = hpsb_send_packet_and_wait(packet);
hpsb_free_packet(packet);
@@ -507,13 +510,13 @@ int hpsb_send_packet(struct hpsb_packet *packet)
{
struct hpsb_host *host = packet->host;
- if (host->is_shutdown)
+ if (host->is_shutdown)
return -EINVAL;
if (host->in_bus_reset ||
(packet->generation != get_hpsb_generation(host)))
- return -EAGAIN;
+ return -EAGAIN;
- packet->state = hpsb_queued;
+ packet->state = hpsb_queued;
/* This just seems silly to me */
WARN_ON(packet->no_waiter && packet->expect_response);
@@ -527,42 +530,42 @@ int hpsb_send_packet(struct hpsb_packet *packet)
skb_queue_tail(&host->pending_packet_queue, packet->skb);
}
- if (packet->node_id == host->node_id) {
+ if (packet->node_id == host->node_id) {
/* it is a local request, so handle it locally */
- quadlet_t *data;
- size_t size = packet->data_size + packet->header_size;
+ quadlet_t *data;
+ size_t size = packet->data_size + packet->header_size;
- data = kmalloc(size, GFP_ATOMIC);
- if (!data) {
- HPSB_ERR("unable to allocate memory for concatenating header and data");
- return -ENOMEM;
- }
+ data = kmalloc(size, GFP_ATOMIC);
+ if (!data) {
+ HPSB_ERR("unable to allocate memory for concatenating header and data");
+ return -ENOMEM;
+ }
- memcpy(data, packet->header, packet->header_size);
+ memcpy(data, packet->header, packet->header_size);
- if (packet->data_size)
+ if (packet->data_size)
memcpy(((u8*)data) + packet->header_size, packet->data, packet->data_size);
- dump_packet("send packet local", packet->header, packet->header_size, -1);
+ dump_packet("send packet local", packet->header, packet->header_size, -1);
- hpsb_packet_sent(host, packet, packet->expect_response ? ACK_PENDING : ACK_COMPLETE);
- hpsb_packet_received(host, data, size, 0);
+ hpsb_packet_sent(host, packet, packet->expect_response ? ACK_PENDING : ACK_COMPLETE);
+ hpsb_packet_received(host, data, size, 0);
- kfree(data);
+ kfree(data);
- return 0;
- }
+ return 0;
+ }
- if (packet->type == hpsb_async && packet->node_id != ALL_NODES) {
- packet->speed_code =
- host->speed_map[NODEID_TO_NODE(host->node_id) * 64
- + NODEID_TO_NODE(packet->node_id)];
- }
+ if (packet->type == hpsb_async && packet->node_id != ALL_NODES) {
+ packet->speed_code =
+ host->speed_map[NODEID_TO_NODE(host->node_id) * 64
+ + NODEID_TO_NODE(packet->node_id)];
+ }
- dump_packet("send packet", packet->header, packet->header_size, packet->speed_code);
+ dump_packet("send packet", packet->header, packet->header_size, packet->speed_code);
- return host->driver->transmit_packet(host, packet);
+ return host->driver->transmit_packet(host, packet);
}
/* We could just use complete() directly as the packet complete
@@ -590,81 +593,81 @@ int hpsb_send_packet_and_wait(struct hpsb_packet *packet)
static void send_packet_nocare(struct hpsb_packet *packet)
{
- if (hpsb_send_packet(packet) < 0) {
- hpsb_free_packet(packet);
- }
+ if (hpsb_send_packet(packet) < 0) {
+ hpsb_free_packet(packet);
+ }
}
static void handle_packet_response(struct hpsb_host *host, int tcode,
quadlet_t *data, size_t size)
{
- struct hpsb_packet *packet = NULL;
+ struct hpsb_packet *packet = NULL;
struct sk_buff *skb;
- int tcode_match = 0;
- int tlabel;
- unsigned long flags;
+ int tcode_match = 0;
+ int tlabel;
+ unsigned long flags;
- tlabel = (data[0] >> 10) & 0x3f;
+ tlabel = (data[0] >> 10) & 0x3f;
spin_lock_irqsave(&host->pending_packet_queue.lock, flags);
skb_queue_walk(&host->pending_packet_queue, skb) {
packet = (struct hpsb_packet *)skb->data;
- if ((packet->tlabel == tlabel)
- && (packet->node_id == (data[1] >> 16))){
- break;
- }
+ if ((packet->tlabel == tlabel)
+ && (packet->node_id == (data[1] >> 16))){
+ break;
+ }
packet = NULL;
- }
+ }
if (packet == NULL) {
- HPSB_DEBUG("unsolicited response packet received - no tlabel match");
- dump_packet("contents", data, 16, -1);
+ HPSB_DEBUG("unsolicited response packet received - no tlabel match");
+ dump_packet("contents", data, 16, -1);
spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);
- return;
- }
+ return;
+ }
- switch (packet->tcode) {
- case TCODE_WRITEQ:
- case TCODE_WRITEB:
- if (tcode != TCODE_WRITE_RESPONSE)
+ switch (packet->tcode) {
+ case TCODE_WRITEQ:
+ case TCODE_WRITEB:
+ if (tcode != TCODE_WRITE_RESPONSE)
break;
tcode_match = 1;
memcpy(packet->header, data, 12);
- break;
- case TCODE_READQ:
- if (tcode != TCODE_READQ_RESPONSE)
+ break;
+ case TCODE_READQ:
+ if (tcode != TCODE_READQ_RESPONSE)
break;
tcode_match = 1;
memcpy(packet->header, data, 16);
- break;
- case TCODE_READB:
- if (tcode != TCODE_READB_RESPONSE)
+ break;
+ case TCODE_READB:
+ if (tcode != TCODE_READB_RESPONSE)
break;
tcode_match = 1;
BUG_ON(packet->skb->len - sizeof(*packet) < size - 16);
memcpy(packet->header, data, 16);
memcpy(packet->data, data + 4, size - 16);
- break;
- case TCODE_LOCK_REQUEST:
- if (tcode != TCODE_LOCK_RESPONSE)
+ break;
+ case TCODE_LOCK_REQUEST:
+ if (tcode != TCODE_LOCK_RESPONSE)
break;
tcode_match = 1;
size = min((size - 16), (size_t)8);
BUG_ON(packet->skb->len - sizeof(*packet) < size);
memcpy(packet->header, data, 16);
memcpy(packet->data, data + 4, size);
- break;
- }
+ break;
+ }
- if (!tcode_match) {
+ if (!tcode_match) {
spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);
- HPSB_INFO("unsolicited response packet received - tcode mismatch");
- dump_packet("contents", data, 16, -1);
- return;
- }
+ HPSB_INFO("unsolicited response packet received - tcode mismatch");
+ dump_packet("contents", data, 16, -1);
+ return;
+ }
__skb_unlink(skb, &host->pending_packet_queue);
@@ -683,27 +686,27 @@ static void handle_packet_response(struct hpsb_host *host, int tcode,
static struct hpsb_packet *create_reply_packet(struct hpsb_host *host,
quadlet_t *data, size_t dsize)
{
- struct hpsb_packet *p;
+ struct hpsb_packet *p;
- p = hpsb_alloc_packet(dsize);
- if (unlikely(p == NULL)) {
- /* FIXME - send data_error response */
- return NULL;
- }
+ p = hpsb_alloc_packet(dsize);
+ if (unlikely(p == NULL)) {
+ /* FIXME - send data_error response */
+ return NULL;
+ }
- p->type = hpsb_async;
- p->state = hpsb_unused;
- p->host = host;
- p->node_id = data[1] >> 16;
- p->tlabel = (data[0] >> 10) & 0x3f;
- p->no_waiter = 1;
+ p->type = hpsb_async;
+ p->state = hpsb_unused;
+ p->host = host;
+ p->node_id = data[1] >> 16;
+ p->tlabel = (data[0] >> 10) & 0x3f;
+ p->no_waiter = 1;
p->generation = get_hpsb_generation(host);
if (dsize % 4)
p->data[dsize / 4] = 0;
- return p;
+ return p;
}
#define PREP_ASYNC_HEAD_RCODE(tc) \
@@ -714,7 +717,7 @@ static struct hpsb_packet *create_reply_packet(struct hpsb_host *host,
packet->header[2] = 0
static void fill_async_readquad_resp(struct hpsb_packet *packet, int rcode,
- quadlet_t data)
+ quadlet_t data)
{
PREP_ASYNC_HEAD_RCODE(TCODE_READQ_RESPONSE);
packet->header[3] = data;
@@ -723,7 +726,7 @@ static void fill_async_readquad_resp(struct hpsb_packet *packet, int rcode,
}
static void fill_async_readblock_resp(struct hpsb_packet *packet, int rcode,
- int length)
+ int length)
{
if (rcode != RCODE_COMPLETE)
length = 0;
@@ -743,7 +746,7 @@ static void fill_async_write_resp(struct hpsb_packet *packet, int rcode)
}
static void fill_async_lock_resp(struct hpsb_packet *packet, int rcode, int extcode,
- int length)
+ int length)
{
if (rcode != RCODE_COMPLETE)
length = 0;
@@ -755,184 +758,184 @@ static void fill_async_lock_resp(struct hpsb_packet *packet, int rcode, int extc
}
#define PREP_REPLY_PACKET(length) \
- packet = create_reply_packet(host, data, length); \
- if (packet == NULL) break
+ packet = create_reply_packet(host, data, length); \
+ if (packet == NULL) break
static void handle_incoming_packet(struct hpsb_host *host, int tcode,
quadlet_t *data, size_t size, int write_acked)
{
- struct hpsb_packet *packet;
- int length, rcode, extcode;
- quadlet_t buffer;
- nodeid_t source = data[1] >> 16;
- nodeid_t dest = data[0] >> 16;
- u16 flags = (u16) data[0];
- u64 addr;
-
- /* big FIXME - no error checking is done for an out of bounds length */
-
- switch (tcode) {
- case TCODE_WRITEQ:
- addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_write(host, source, dest, data+3,
+ struct hpsb_packet *packet;
+ int length, rcode, extcode;
+ quadlet_t buffer;
+ nodeid_t source = data[1] >> 16;
+ nodeid_t dest = data[0] >> 16;
+ u16 flags = (u16) data[0];
+ u64 addr;
+
+ /* big FIXME - no error checking is done for an out of bounds length */
+
+ switch (tcode) {
+ case TCODE_WRITEQ:
+ addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
+ rcode = highlevel_write(host, source, dest, data+3,
addr, 4, flags);
- if (!write_acked
- && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
- && (rcode >= 0)) {
- /* not a broadcast write, reply */
- PREP_REPLY_PACKET(0);
- fill_async_write_resp(packet, rcode);
- send_packet_nocare(packet);
- }
- break;
-
- case TCODE_WRITEB:
- addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_write(host, source, dest, data+4,
+ if (!write_acked
+ && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
+ && (rcode >= 0)) {
+ /* not a broadcast write, reply */
+ PREP_REPLY_PACKET(0);
+ fill_async_write_resp(packet, rcode);
+ send_packet_nocare(packet);
+ }
+ break;
+
+ case TCODE_WRITEB:
+ addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
+ rcode = highlevel_write(host, source, dest, data+4,
addr, data[3]>>16, flags);
- if (!write_acked
- && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
- && (rcode >= 0)) {
- /* not a broadcast write, reply */
- PREP_REPLY_PACKET(0);
- fill_async_write_resp(packet, rcode);
- send_packet_nocare(packet);
- }
- break;
-
- case TCODE_READQ:
- addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_read(host, source, &buffer, addr, 4, flags);
-
- if (rcode >= 0) {
- PREP_REPLY_PACKET(0);
- fill_async_readquad_resp(packet, rcode, buffer);
- send_packet_nocare(packet);
- }
- break;
-
- case TCODE_READB:
- length = data[3] >> 16;
- PREP_REPLY_PACKET(length);
-
- addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
- rcode = highlevel_read(host, source, packet->data, addr,
- length, flags);
-
- if (rcode >= 0) {
- fill_async_readblock_resp(packet, rcode, length);
- send_packet_nocare(packet);
- } else {
- hpsb_free_packet(packet);
- }
- break;
-
- case TCODE_LOCK_REQUEST:
- length = data[3] >> 16;
- extcode = data[3] & 0xffff;
- addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
-
- PREP_REPLY_PACKET(8);
-
- if ((extcode == 0) || (extcode >= 7)) {
- /* let switch default handle error */
- length = 0;
- }
-
- switch (length) {
- case 4:
- rcode = highlevel_lock(host, source, packet->data, addr,
- data[4], 0, extcode,flags);
- fill_async_lock_resp(packet, rcode, extcode, 4);
- break;
- case 8:
- if ((extcode != EXTCODE_FETCH_ADD)
- && (extcode != EXTCODE_LITTLE_ADD)) {
- rcode = highlevel_lock(host, source,
- packet->data, addr,
- data[5], data[4],
- extcode, flags);
- fill_async_lock_resp(packet, rcode, extcode, 4);
- } else {
- rcode = highlevel_lock64(host, source,
- (octlet_t *)packet->data, addr,
- *(octlet_t *)(data + 4), 0ULL,
- extcode, flags);
- fill_async_lock_resp(packet, rcode, extcode, 8);
- }
- break;
- case 16:
- rcode = highlevel_lock64(host, source,
- (octlet_t *)packet->data, addr,
- *(octlet_t *)(data + 6),
- *(octlet_t *)(data + 4),
- extcode, flags);
- fill_async_lock_resp(packet, rcode, extcode, 8);
- break;
- default:
- rcode = RCODE_TYPE_ERROR;
- fill_async_lock_resp(packet, rcode,
- extcode, 0);
- }
-
- if (rcode >= 0) {
- send_packet_nocare(packet);
- } else {
- hpsb_free_packet(packet);
- }
- break;
- }
+ if (!write_acked
+ && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
+ && (rcode >= 0)) {
+ /* not a broadcast write, reply */
+ PREP_REPLY_PACKET(0);
+ fill_async_write_resp(packet, rcode);
+ send_packet_nocare(packet);
+ }
+ break;
+
+ case TCODE_READQ:
+ addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
+ rcode = highlevel_read(host, source, &buffer, addr, 4, flags);
+
+ if (rcode >= 0) {
+ PREP_REPLY_PACKET(0);
+ fill_async_readquad_resp(packet, rcode, buffer);
+ send_packet_nocare(packet);
+ }
+ break;
+
+ case TCODE_READB:
+ length = data[3] >> 16;
+ PREP_REPLY_PACKET(length);
+
+ addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
+ rcode = highlevel_read(host, source, packet->data, addr,
+ length, flags);
+
+ if (rcode >= 0) {
+ fill_async_readblock_resp(packet, rcode, length);
+ send_packet_nocare(packet);
+ } else {
+ hpsb_free_packet(packet);
+ }
+ break;
+
+ case TCODE_LOCK_REQUEST:
+ length = data[3] >> 16;
+ extcode = data[3] & 0xffff;
+ addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
+
+ PREP_REPLY_PACKET(8);
+
+ if ((extcode == 0) || (extcode >= 7)) {
+ /* let switch default handle error */
+ length = 0;
+ }
+
+ switch (length) {
+ case 4:
+ rcode = highlevel_lock(host, source, packet->data, addr,
+ data[4], 0, extcode,flags);
+ fill_async_lock_resp(packet, rcode, extcode, 4);
+ break;
+ case 8:
+ if ((extcode != EXTCODE_FETCH_ADD)
+ && (extcode != EXTCODE_LITTLE_ADD)) {
+ rcode = highlevel_lock(host, source,
+ packet->data, addr,
+ data[5], data[4],
+ extcode, flags);
+ fill_async_lock_resp(packet, rcode, extcode, 4);
+ } else {
+ rcode = highlevel_lock64(host, source,
+ (octlet_t *)packet->data, addr,
+ *(octlet_t *)(data + 4), 0ULL,
+ extcode, flags);
+ fill_async_lock_resp(packet, rcode, extcode, 8);
+ }
+ break;
+ case 16:
+ rcode = highlevel_lock64(host, source,
+ (octlet_t *)packet->data, addr,
+ *(octlet_t *)(data + 6),
+ *(octlet_t *)(data + 4),
+ extcode, flags);
+ fill_async_lock_resp(packet, rcode, extcode, 8);
+ break;
+ default:
+ rcode = RCODE_TYPE_ERROR;
+ fill_async_lock_resp(packet, rcode,
+ extcode, 0);
+ }
+
+ if (rcode >= 0) {
+ send_packet_nocare(packet);
+ } else {
+ hpsb_free_packet(packet);
+ }
+ break;
+ }
}
#undef PREP_REPLY_PACKET
void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
- int write_acked)
+ int write_acked)
{
- int tcode;
-
- if (host->in_bus_reset) {
- HPSB_INFO("received packet during reset; ignoring");
- return;
- }
-
- dump_packet("received packet", data, size, -1);
-
- tcode = (data[0] >> 4) & 0xf;
-
- switch (tcode) {
- case TCODE_WRITE_RESPONSE:
- case TCODE_READQ_RESPONSE:
- case TCODE_READB_RESPONSE:
- case TCODE_LOCK_RESPONSE:
- handle_packet_response(host, tcode, data, size);
- break;
-
- case TCODE_WRITEQ:
- case TCODE_WRITEB:
- case TCODE_READQ:
- case TCODE_READB:
- case TCODE_LOCK_REQUEST:
- handle_incoming_packet(host, tcode, data, size, write_acked);
- break;
-
-
- case TCODE_ISO_DATA:
- highlevel_iso_receive(host, data, size);
- break;
-
- case TCODE_CYCLE_START:
- /* simply ignore this packet if it is passed on */
- break;
-
- default:
- HPSB_NOTICE("received packet with bogus transaction code %d",
- tcode);
- break;
- }
+ int tcode;
+
+ if (host->in_bus_reset) {
+ HPSB_INFO("received packet during reset; ignoring");
+ return;
+ }
+
+ dump_packet("received packet", data, size, -1);
+
+ tcode = (data[0] >> 4) & 0xf;
+
+ switch (tcode) {
+ case TCODE_WRITE_RESPONSE:
+ case TCODE_READQ_RESPONSE:
+ case TCODE_READB_RESPONSE:
+ case TCODE_LOCK_RESPONSE:
+ handle_packet_response(host, tcode, data, size);
+ break;
+
+ case TCODE_WRITEQ:
+ case TCODE_WRITEB:
+ case TCODE_READQ:
+ case TCODE_READB:
+ case TCODE_LOCK_REQUEST:
+ handle_incoming_packet(host, tcode, data, size, write_acked);
+ break;
+
+
+ case TCODE_ISO_DATA:
+ highlevel_iso_receive(host, data, size);
+ break;
+
+ case TCODE_CYCLE_START:
+ /* simply ignore this packet if it is passed on */
+ break;
+
+ default:
+ HPSB_NOTICE("received packet with bogus transaction code %d",
+ tcode);
+ break;
+ }
}
@@ -1126,7 +1129,7 @@ static int __init ieee1394_init(void)
nodemgr implements functionality required of ieee1394a-2000
IRMs */
hpsb_disable_irm = 1;
-
+
return 0;
}
diff --git a/trunk/drivers/ieee1394/ieee1394_core.h b/trunk/drivers/ieee1394/ieee1394_core.h
index b35466023f00..0b31429d0a68 100644
--- a/trunk/drivers/ieee1394/ieee1394_core.h
+++ b/trunk/drivers/ieee1394/ieee1394_core.h
@@ -10,8 +10,8 @@
struct hpsb_packet {
- /* This struct is basically read-only for hosts with the exception of
- * the data buffer contents and xnext - see below. */
+ /* This struct is basically read-only for hosts with the exception of
+ * the data buffer contents and xnext - see below. */
/* This can be used for host driver internal linking.
*
@@ -21,47 +21,47 @@ struct hpsb_packet {
* driver_list when free'ing it. */
struct list_head driver_list;
- nodeid_t node_id;
+ nodeid_t node_id;
- /* Async and Iso types should be clear, raw means send-as-is, do not
- * CRC! Byte swapping shall still be done in this case. */
- enum { hpsb_async, hpsb_iso, hpsb_raw } __attribute__((packed)) type;
+ /* Async and Iso types should be clear, raw means send-as-is, do not
+ * CRC! Byte swapping shall still be done in this case. */
+ enum { hpsb_async, hpsb_iso, hpsb_raw } __attribute__((packed)) type;
- /* Okay, this is core internal and a no care for hosts.
- * queued = queued for sending
- * pending = sent, waiting for response
- * complete = processing completed, successful or not
- */
- enum {
- hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete
- } __attribute__((packed)) state;
+ /* Okay, this is core internal and a no care for hosts.
+ * queued = queued for sending
+ * pending = sent, waiting for response
+ * complete = processing completed, successful or not
+ */
+ enum {
+ hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete
+ } __attribute__((packed)) state;
- /* These are core internal. */
- signed char tlabel;
+ /* These are core internal. */
+ signed char tlabel;
signed char ack_code;
unsigned char tcode;
- unsigned expect_response:1;
- unsigned no_waiter:1;
+ unsigned expect_response:1;
+ unsigned no_waiter:1;
- /* Speed to transmit with: 0 = 100Mbps, 1 = 200Mbps, 2 = 400Mbps */
- unsigned speed_code:2;
+ /* Speed to transmit with: 0 = 100Mbps, 1 = 200Mbps, 2 = 400Mbps */
+ unsigned speed_code:2;
- /*
- * *header and *data are guaranteed to be 32-bit DMAable and may be
- * overwritten to allow in-place byte swapping. Neither of these is
- * CRCed (the sizes also don't include CRC), but contain space for at
- * least one additional quadlet to allow in-place CRCing. The memory is
- * also guaranteed to be DMA mappable.
- */
- quadlet_t *header;
- quadlet_t *data;
- size_t header_size;
- size_t data_size;
+ /*
+ * *header and *data are guaranteed to be 32-bit DMAable and may be
+ * overwritten to allow in-place byte swapping. Neither of these is
+ * CRCed (the sizes also don't include CRC), but contain space for at
+ * least one additional quadlet to allow in-place CRCing. The memory is
+ * also guaranteed to be DMA mappable.
+ */
+ quadlet_t *header;
+ quadlet_t *data;
+ size_t header_size;
+ size_t data_size;
- struct hpsb_host *host;
- unsigned int generation;
+ struct hpsb_host *host;
+ unsigned int generation;
atomic_t refcnt;
@@ -73,10 +73,10 @@ struct hpsb_packet {
/* XXX This is just a hack at the moment */
struct sk_buff *skb;
- /* Store jiffies for implementing bus timeouts. */
- unsigned long sendtime;
+ /* Store jiffies for implementing bus timeouts. */
+ unsigned long sendtime;
- quadlet_t embedded_header[5];
+ quadlet_t embedded_header[5];
};
/* Set a task for when a packet completes */
@@ -102,7 +102,7 @@ void hpsb_free_packet(struct hpsb_packet *packet);
*/
static inline unsigned int get_hpsb_generation(struct hpsb_host *host)
{
- return atomic_read(&host->generation);
+ return atomic_read(&host->generation);
}
/*
@@ -157,7 +157,7 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot);
* from within a transmit packet routine.
*/
void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
- int ackcode);
+ int ackcode);
/*
* Hand over received packet to the core. The contents of data are expected to
@@ -171,7 +171,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
* packet type.
*/
void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
- int write_acked);
+ int write_acked);
/*
@@ -197,20 +197,20 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
* Block 15 (240-255) reserved for drivers under development, etc.
*/
-#define IEEE1394_MAJOR 171
+#define IEEE1394_MAJOR 171
-#define IEEE1394_MINOR_BLOCK_RAW1394 0
-#define IEEE1394_MINOR_BLOCK_VIDEO1394 1
-#define IEEE1394_MINOR_BLOCK_DV1394 2
-#define IEEE1394_MINOR_BLOCK_AMDTP 3
+#define IEEE1394_MINOR_BLOCK_RAW1394 0
+#define IEEE1394_MINOR_BLOCK_VIDEO1394 1
+#define IEEE1394_MINOR_BLOCK_DV1394 2
+#define IEEE1394_MINOR_BLOCK_AMDTP 3
#define IEEE1394_MINOR_BLOCK_EXPERIMENTAL 15
-#define IEEE1394_CORE_DEV MKDEV(IEEE1394_MAJOR, 0)
-#define IEEE1394_RAW1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)
-#define IEEE1394_VIDEO1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16)
-#define IEEE1394_DV1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16)
-#define IEEE1394_AMDTP_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_AMDTP * 16)
-#define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16)
+#define IEEE1394_CORE_DEV MKDEV(IEEE1394_MAJOR, 0)
+#define IEEE1394_RAW1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)
+#define IEEE1394_VIDEO1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16)
+#define IEEE1394_DV1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16)
+#define IEEE1394_AMDTP_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_AMDTP * 16)
+#define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16)
/* return the index (within a minor number block) of a file */
static inline unsigned char ieee1394_file_to_instance(struct file *file)
diff --git a/trunk/drivers/ieee1394/ieee1394_transactions.c b/trunk/drivers/ieee1394/ieee1394_transactions.c
index 3fe2f6c4a253..0aa876360f9b 100644
--- a/trunk/drivers/ieee1394/ieee1394_transactions.c
+++ b/trunk/drivers/ieee1394/ieee1394_transactions.c
@@ -22,7 +22,7 @@
#include "ieee1394_core.h"
#include "highlevel.h"
#include "nodemgr.h"
-#include "ieee1394_transactions.h"
+
#define PREP_ASYNC_HEAD_ADDRESS(tc) \
packet->tcode = tc; \
@@ -31,82 +31,80 @@
packet->header[1] = (packet->host->node_id << 16) | (addr >> 32); \
packet->header[2] = addr & 0xffffffff
+
static void fill_async_readquad(struct hpsb_packet *packet, u64 addr)
{
- PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ);
- packet->header_size = 12;
- packet->data_size = 0;
- packet->expect_response = 1;
+ PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ);
+ packet->header_size = 12;
+ packet->data_size = 0;
+ packet->expect_response = 1;
}
-static void fill_async_readblock(struct hpsb_packet *packet, u64 addr,
- int length)
+static void fill_async_readblock(struct hpsb_packet *packet, u64 addr, int length)
{
- PREP_ASYNC_HEAD_ADDRESS(TCODE_READB);
- packet->header[3] = length << 16;
- packet->header_size = 16;
- packet->data_size = 0;
- packet->expect_response = 1;
+ PREP_ASYNC_HEAD_ADDRESS(TCODE_READB);
+ packet->header[3] = length << 16;
+ packet->header_size = 16;
+ packet->data_size = 0;
+ packet->expect_response = 1;
}
-static void fill_async_writequad(struct hpsb_packet *packet, u64 addr,
- quadlet_t data)
+static void fill_async_writequad(struct hpsb_packet *packet, u64 addr, quadlet_t data)
{
- PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEQ);
- packet->header[3] = data;
- packet->header_size = 16;
- packet->data_size = 0;
- packet->expect_response = 1;
+ PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEQ);
+ packet->header[3] = data;
+ packet->header_size = 16;
+ packet->data_size = 0;
+ packet->expect_response = 1;
}
-static void fill_async_writeblock(struct hpsb_packet *packet, u64 addr,
- int length)
+static void fill_async_writeblock(struct hpsb_packet *packet, u64 addr, int length)
{
- PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEB);
- packet->header[3] = length << 16;
- packet->header_size = 16;
- packet->expect_response = 1;
- packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0);
+ PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEB);
+ packet->header[3] = length << 16;
+ packet->header_size = 16;
+ packet->expect_response = 1;
+ packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0);
}
static void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode,
- int length)
+ int length)
{
- PREP_ASYNC_HEAD_ADDRESS(TCODE_LOCK_REQUEST);
- packet->header[3] = (length << 16) | extcode;
- packet->header_size = 16;
- packet->data_size = length;
- packet->expect_response = 1;
+ PREP_ASYNC_HEAD_ADDRESS(TCODE_LOCK_REQUEST);
+ packet->header[3] = (length << 16) | extcode;
+ packet->header_size = 16;
+ packet->data_size = length;
+ packet->expect_response = 1;
}
static void fill_iso_packet(struct hpsb_packet *packet, int length, int channel,
- int tag, int sync)
+ int tag, int sync)
{
- packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
- | (TCODE_ISO_DATA << 4) | sync;
+ packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
+ | (TCODE_ISO_DATA << 4) | sync;
- packet->header_size = 4;
- packet->data_size = length;
- packet->type = hpsb_iso;
- packet->tcode = TCODE_ISO_DATA;
+ packet->header_size = 4;
+ packet->data_size = length;
+ packet->type = hpsb_iso;
+ packet->tcode = TCODE_ISO_DATA;
}
static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data)
{
- packet->header[0] = data;
- packet->header[1] = ~data;
- packet->header_size = 8;
- packet->data_size = 0;
- packet->expect_response = 0;
- packet->type = hpsb_raw; /* No CRC added */
- packet->speed_code = IEEE1394_SPEED_100; /* Force speed to be 100Mbps */
+ packet->header[0] = data;
+ packet->header[1] = ~data;
+ packet->header_size = 8;
+ packet->data_size = 0;
+ packet->expect_response = 0;
+ packet->type = hpsb_raw; /* No CRC added */
+ packet->speed_code = IEEE1394_SPEED_100; /* Force speed to be 100Mbps */
}
static void fill_async_stream_packet(struct hpsb_packet *packet, int length,
int channel, int tag, int sync)
{
packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
- | (TCODE_STREAM_DATA << 4) | sync;
+ | (TCODE_STREAM_DATA << 4) | sync;
packet->header_size = 4;
packet->data_size = length;
@@ -173,96 +171,99 @@ int hpsb_get_tlabel(struct hpsb_packet *packet)
*/
void hpsb_free_tlabel(struct hpsb_packet *packet)
{
- unsigned long flags;
+ unsigned long flags;
struct hpsb_tlabel_pool *tp;
tp = &packet->host->tpool[packet->node_id & NODE_MASK];
BUG_ON(packet->tlabel > 63 || packet->tlabel < 0);
- spin_lock_irqsave(&tp->lock, flags);
+ spin_lock_irqsave(&tp->lock, flags);
BUG_ON(!test_and_clear_bit(packet->tlabel, tp->pool));
- spin_unlock_irqrestore(&tp->lock, flags);
+ spin_unlock_irqrestore(&tp->lock, flags);
up(&tp->count);
}
-int hpsb_packet_success(struct hpsb_packet *packet)
-{
- switch (packet->ack_code) {
- case ACK_PENDING:
- switch ((packet->header[1] >> 12) & 0xf) {
- case RCODE_COMPLETE:
- return 0;
- case RCODE_CONFLICT_ERROR:
- return -EAGAIN;
- case RCODE_DATA_ERROR:
- return -EREMOTEIO;
- case RCODE_TYPE_ERROR:
- return -EACCES;
- case RCODE_ADDRESS_ERROR:
- return -EINVAL;
- default:
- HPSB_ERR("received reserved rcode %d from node %d",
- (packet->header[1] >> 12) & 0xf,
- packet->node_id);
- return -EAGAIN;
- }
- HPSB_PANIC("reached unreachable code 1 in %s", __FUNCTION__);
-
- case ACK_BUSY_X:
- case ACK_BUSY_A:
- case ACK_BUSY_B:
- return -EBUSY;
-
- case ACK_TYPE_ERROR:
- return -EACCES;
-
- case ACK_COMPLETE:
- if (packet->tcode == TCODE_WRITEQ
- || packet->tcode == TCODE_WRITEB) {
- return 0;
- } else {
- HPSB_ERR("impossible ack_complete from node %d "
- "(tcode %d)", packet->node_id, packet->tcode);
- return -EAGAIN;
- }
-
- case ACK_DATA_ERROR:
- if (packet->tcode == TCODE_WRITEB
- || packet->tcode == TCODE_LOCK_REQUEST) {
- return -EAGAIN;
- } else {
- HPSB_ERR("impossible ack_data_error from node %d "
- "(tcode %d)", packet->node_id, packet->tcode);
- return -EAGAIN;
- }
-
- case ACK_ADDRESS_ERROR:
- return -EINVAL;
-
- case ACK_TARDY:
- case ACK_CONFLICT_ERROR:
- case ACKX_NONE:
- case ACKX_SEND_ERROR:
- case ACKX_ABORTED:
- case ACKX_TIMEOUT:
- /* error while sending */
- return -EAGAIN;
- default:
- HPSB_ERR("got invalid ack %d from node %d (tcode %d)",
- packet->ack_code, packet->node_id, packet->tcode);
- return -EAGAIN;
- }
- HPSB_PANIC("reached unreachable code 2 in %s", __FUNCTION__);
+int hpsb_packet_success(struct hpsb_packet *packet)
+{
+ switch (packet->ack_code) {
+ case ACK_PENDING:
+ switch ((packet->header[1] >> 12) & 0xf) {
+ case RCODE_COMPLETE:
+ return 0;
+ case RCODE_CONFLICT_ERROR:
+ return -EAGAIN;
+ case RCODE_DATA_ERROR:
+ return -EREMOTEIO;
+ case RCODE_TYPE_ERROR:
+ return -EACCES;
+ case RCODE_ADDRESS_ERROR:
+ return -EINVAL;
+ default:
+ HPSB_ERR("received reserved rcode %d from node %d",
+ (packet->header[1] >> 12) & 0xf,
+ packet->node_id);
+ return -EAGAIN;
+ }
+ HPSB_PANIC("reached unreachable code 1 in %s", __FUNCTION__);
+
+ case ACK_BUSY_X:
+ case ACK_BUSY_A:
+ case ACK_BUSY_B:
+ return -EBUSY;
+
+ case ACK_TYPE_ERROR:
+ return -EACCES;
+
+ case ACK_COMPLETE:
+ if (packet->tcode == TCODE_WRITEQ
+ || packet->tcode == TCODE_WRITEB) {
+ return 0;
+ } else {
+ HPSB_ERR("impossible ack_complete from node %d "
+ "(tcode %d)", packet->node_id, packet->tcode);
+ return -EAGAIN;
+ }
+
+
+ case ACK_DATA_ERROR:
+ if (packet->tcode == TCODE_WRITEB
+ || packet->tcode == TCODE_LOCK_REQUEST) {
+ return -EAGAIN;
+ } else {
+ HPSB_ERR("impossible ack_data_error from node %d "
+ "(tcode %d)", packet->node_id, packet->tcode);
+ return -EAGAIN;
+ }
+
+ case ACK_ADDRESS_ERROR:
+ return -EINVAL;
+
+ case ACK_TARDY:
+ case ACK_CONFLICT_ERROR:
+ case ACKX_NONE:
+ case ACKX_SEND_ERROR:
+ case ACKX_ABORTED:
+ case ACKX_TIMEOUT:
+ /* error while sending */
+ return -EAGAIN;
+
+ default:
+ HPSB_ERR("got invalid ack %d from node %d (tcode %d)",
+ packet->ack_code, packet->node_id, packet->tcode);
+ return -EAGAIN;
+ }
+
+ HPSB_PANIC("reached unreachable code 2 in %s", __FUNCTION__);
}
struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
u64 addr, size_t length)
{
- struct hpsb_packet *packet;
+ struct hpsb_packet *packet;
if (length == 0)
return NULL;
@@ -287,9 +288,8 @@ struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
return packet;
}
-struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host, nodeid_t node,
- u64 addr, quadlet_t * buffer,
- size_t length)
+struct hpsb_packet *hpsb_make_writepacket (struct hpsb_host *host, nodeid_t node,
+ u64 addr, quadlet_t *buffer, size_t length)
{
struct hpsb_packet *packet;
@@ -300,7 +300,7 @@ struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host, nodeid_t node,
if (!packet)
return NULL;
- if (length % 4) { /* zero padding bytes */
+ if (length % 4) { /* zero padding bytes */
packet->data[length >> 2] = 0;
}
packet->host = host;
@@ -322,9 +322,8 @@ struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host, nodeid_t node,
return packet;
}
-struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 * buffer,
- int length, int channel, int tag,
- int sync)
+struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer, int length,
+ int channel, int tag, int sync)
{
struct hpsb_packet *packet;
@@ -335,7 +334,7 @@ struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 * buffer,
if (!packet)
return NULL;
- if (length % 4) { /* zero padding bytes */
+ if (length % 4) { /* zero padding bytes */
packet->data[length >> 2] = 0;
}
packet->host = host;
@@ -353,15 +352,14 @@ struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 * buffer,
}
struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
- u64 addr, int extcode,
- quadlet_t * data, quadlet_t arg)
+ u64 addr, int extcode, quadlet_t *data,
+ quadlet_t arg)
{
struct hpsb_packet *p;
u32 length;
p = hpsb_alloc_packet(8);
- if (!p)
- return NULL;
+ if (!p) return NULL;
p->host = host;
p->node_id = node;
@@ -390,16 +388,15 @@ struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
return p;
}
-struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host,
- nodeid_t node, u64 addr, int extcode,
- octlet_t * data, octlet_t arg)
+struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, nodeid_t node,
+ u64 addr, int extcode, octlet_t *data,
+ octlet_t arg)
{
struct hpsb_packet *p;
u32 length;
p = hpsb_alloc_packet(16);
- if (!p)
- return NULL;
+ if (!p) return NULL;
p->host = host;
p->node_id = node;
@@ -432,18 +429,18 @@ struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host,
return p;
}
-struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data)
+struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host,
+ quadlet_t data)
{
- struct hpsb_packet *p;
+ struct hpsb_packet *p;
- p = hpsb_alloc_packet(0);
- if (!p)
- return NULL;
+ p = hpsb_alloc_packet(0);
+ if (!p) return NULL;
- p->host = host;
- fill_phy_packet(p, data);
+ p->host = host;
+ fill_phy_packet(p, data);
- return p;
+ return p;
}
struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host,
@@ -453,8 +450,7 @@ struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host,
struct hpsb_packet *p;
p = hpsb_alloc_packet(length);
- if (!p)
- return NULL;
+ if (!p) return NULL;
p->host = host;
fill_iso_packet(p, length, channel, tag, sync);
@@ -470,46 +466,47 @@ struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host,
*/
int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
- u64 addr, quadlet_t * buffer, size_t length)
+ u64 addr, quadlet_t *buffer, size_t length)
{
- struct hpsb_packet *packet;
- int retval = 0;
+ struct hpsb_packet *packet;
+ int retval = 0;
- if (length == 0)
- return -EINVAL;
+ if (length == 0)
+ return -EINVAL;
- BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
+ BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
packet = hpsb_make_readpacket(host, node, addr, length);
- if (!packet) {
- return -ENOMEM;
- }
+ if (!packet) {
+ return -ENOMEM;
+ }
packet->generation = generation;
- retval = hpsb_send_packet_and_wait(packet);
+ retval = hpsb_send_packet_and_wait(packet);
if (retval < 0)
goto hpsb_read_fail;
- retval = hpsb_packet_success(packet);
+ retval = hpsb_packet_success(packet);
- if (retval == 0) {
- if (length == 4) {
- *buffer = packet->header[3];
- } else {
- memcpy(buffer, packet->data, length);
- }
- }
+ if (retval == 0) {
+ if (length == 4) {
+ *buffer = packet->header[3];
+ } else {
+ memcpy(buffer, packet->data, length);
+ }
+ }
- hpsb_read_fail:
- hpsb_free_tlabel(packet);
- hpsb_free_packet(packet);
+hpsb_read_fail:
+ hpsb_free_tlabel(packet);
+ hpsb_free_packet(packet);
- return retval;
+ return retval;
}
+
int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
- u64 addr, quadlet_t * buffer, size_t length)
+ u64 addr, quadlet_t *buffer, size_t length)
{
struct hpsb_packet *packet;
int retval;
@@ -517,61 +514,62 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
if (length == 0)
return -EINVAL;
- BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
+ BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
- packet = hpsb_make_writepacket(host, node, addr, buffer, length);
+ packet = hpsb_make_writepacket (host, node, addr, buffer, length);
if (!packet)
return -ENOMEM;
packet->generation = generation;
- retval = hpsb_send_packet_and_wait(packet);
+ retval = hpsb_send_packet_and_wait(packet);
if (retval < 0)
goto hpsb_write_fail;
- retval = hpsb_packet_success(packet);
+ retval = hpsb_packet_success(packet);
- hpsb_write_fail:
- hpsb_free_tlabel(packet);
- hpsb_free_packet(packet);
+hpsb_write_fail:
+ hpsb_free_tlabel(packet);
+ hpsb_free_packet(packet);
- return retval;
+ return retval;
}
#if 0
int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
- u64 addr, int extcode, quadlet_t * data, quadlet_t arg)
+ u64 addr, int extcode, quadlet_t *data, quadlet_t arg)
{
- struct hpsb_packet *packet;
- int retval = 0;
+ struct hpsb_packet *packet;
+ int retval = 0;
- BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
+ BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg);
- if (!packet)
- return -ENOMEM;
+ if (!packet)
+ return -ENOMEM;
packet->generation = generation;
- retval = hpsb_send_packet_and_wait(packet);
+ retval = hpsb_send_packet_and_wait(packet);
if (retval < 0)
goto hpsb_lock_fail;
- retval = hpsb_packet_success(packet);
+ retval = hpsb_packet_success(packet);
- if (retval == 0) {
- *data = packet->data[0];
- }
+ if (retval == 0) {
+ *data = packet->data[0];
+ }
- hpsb_lock_fail:
- hpsb_free_tlabel(packet);
- hpsb_free_packet(packet);
+hpsb_lock_fail:
+ hpsb_free_tlabel(packet);
+ hpsb_free_packet(packet);
- return retval;
+ return retval;
}
+
int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
- quadlet_t * buffer, size_t length, u32 specifier_id,
+ quadlet_t *buffer, size_t length, u32 specifier_id,
unsigned int version)
{
struct hpsb_packet *packet;
@@ -588,8 +586,7 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
return -ENOMEM;
packet->data[0] = cpu_to_be32((host->node_id << 16) | specifier_id_hi);
- packet->data[1] =
- cpu_to_be32((specifier_id_lo << 24) | (version & 0x00ffffff));
+ packet->data[1] = cpu_to_be32((specifier_id_lo << 24) | (version & 0x00ffffff));
memcpy(&(packet->data[2]), buffer, length - 8);
@@ -604,4 +601,4 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
return retval;
}
-#endif /* 0 */
+#endif /* 0 */
diff --git a/trunk/drivers/ieee1394/iso.c b/trunk/drivers/ieee1394/iso.c
index f26680ebef7c..615541b8b90f 100644
--- a/trunk/drivers/ieee1394/iso.c
+++ b/trunk/drivers/ieee1394/iso.c
@@ -36,22 +36,20 @@ void hpsb_iso_shutdown(struct hpsb_iso *iso)
kfree(iso);
}
-static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host,
- enum hpsb_iso_type type,
+static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_iso_type type,
unsigned int data_buf_size,
unsigned int buf_packets,
- int channel, int dma_mode,
+ int channel,
+ int dma_mode,
int irq_interval,
- void (*callback) (struct hpsb_iso
- *))
+ void (*callback)(struct hpsb_iso*))
{
struct hpsb_iso *iso;
int dma_direction;
/* make sure driver supports the ISO API */
if (!host->driver->isoctl) {
- printk(KERN_INFO
- "ieee1394: host driver '%s' does not support the rawiso API\n",
+ printk(KERN_INFO "ieee1394: host driver '%s' does not support the rawiso API\n",
host->driver->name);
return NULL;
}
@@ -61,13 +59,12 @@ static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host,
if (buf_packets < 2)
buf_packets = 2;
- if ((dma_mode < HPSB_ISO_DMA_DEFAULT)
- || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER))
- dma_mode = HPSB_ISO_DMA_DEFAULT;
+ if ((dma_mode < HPSB_ISO_DMA_DEFAULT) || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER))
+ dma_mode=HPSB_ISO_DMA_DEFAULT;
if ((irq_interval < 0) || (irq_interval > buf_packets / 4))
- irq_interval = buf_packets / 4;
- if (irq_interval == 0) /* really interrupt for each packet */
+ irq_interval = buf_packets / 4;
+ if (irq_interval == 0) /* really interrupt for each packet*/
irq_interval = 1;
if (channel < -1 || channel >= 64)
@@ -79,10 +76,7 @@ static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host,
/* allocate and write the struct hpsb_iso */
- iso =
- kmalloc(sizeof(*iso) +
- buf_packets * sizeof(struct hpsb_iso_packet_info),
- GFP_KERNEL);
+ iso = kmalloc(sizeof(*iso) + buf_packets * sizeof(struct hpsb_iso_packet_info), GFP_KERNEL);
if (!iso)
return NULL;
@@ -117,18 +111,17 @@ static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host,
iso->prebuffer = 0;
/* allocate the packet buffer */
- if (dma_region_alloc
- (&iso->data_buf, iso->buf_size, host->pdev, dma_direction))
+ if (dma_region_alloc(&iso->data_buf, iso->buf_size, host->pdev, dma_direction))
goto err;
return iso;
- err:
+err:
hpsb_iso_shutdown(iso);
return NULL;
}
-int hpsb_iso_n_ready(struct hpsb_iso *iso)
+int hpsb_iso_n_ready(struct hpsb_iso* iso)
{
unsigned long flags;
int val;
@@ -140,19 +133,18 @@ int hpsb_iso_n_ready(struct hpsb_iso *iso)
return val;
}
-struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host,
+
+struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host,
unsigned int data_buf_size,
unsigned int buf_packets,
int channel,
int speed,
int irq_interval,
- void (*callback) (struct hpsb_iso *))
+ void (*callback)(struct hpsb_iso*))
{
struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT,
data_buf_size, buf_packets,
- channel,
- HPSB_ISO_DMA_DEFAULT,
- irq_interval, callback);
+ channel, HPSB_ISO_DMA_DEFAULT, irq_interval, callback);
if (!iso)
return NULL;
@@ -165,23 +157,22 @@ struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host,
iso->flags |= HPSB_ISO_DRIVER_INIT;
return iso;
- err:
+err:
hpsb_iso_shutdown(iso);
return NULL;
}
-struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host,
+struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host,
unsigned int data_buf_size,
unsigned int buf_packets,
int channel,
int dma_mode,
int irq_interval,
- void (*callback) (struct hpsb_iso *))
+ void (*callback)(struct hpsb_iso*))
{
struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV,
data_buf_size, buf_packets,
- channel, dma_mode,
- irq_interval, callback);
+ channel, dma_mode, irq_interval, callback);
if (!iso)
return NULL;
@@ -192,7 +183,7 @@ struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host,
iso->flags |= HPSB_ISO_DRIVER_INIT;
return iso;
- err:
+err:
hpsb_iso_shutdown(iso);
return NULL;
}
@@ -206,17 +197,16 @@ int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel)
int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel)
{
- if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
- return -EINVAL;
- return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel);
+ if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
+ return -EINVAL;
+ return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel);
}
int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask)
{
if (iso->type != HPSB_ISO_RECV || iso->channel != -1)
return -EINVAL;
- return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK,
- (unsigned long)&mask);
+ return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, (unsigned long) &mask);
}
int hpsb_iso_recv_flush(struct hpsb_iso *iso)
@@ -293,9 +283,7 @@ int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync)
isoctl_args[2] = sync;
- retval =
- iso->host->driver->isoctl(iso, RECV_START,
- (unsigned long)&isoctl_args[0]);
+ retval = iso->host->driver->isoctl(iso, RECV_START, (unsigned long) &isoctl_args[0]);
if (retval)
return retval;
@@ -308,8 +296,7 @@ int hpsb_iso_recv_start(struct hpsb_iso *iso, int cycle, int tag_mask, int sync)
static int hpsb_iso_check_offset_len(struct hpsb_iso *iso,
unsigned int offset, unsigned short len,
- unsigned int *out_offset,
- unsigned short *out_len)
+ unsigned int *out_offset, unsigned short *out_len)
{
if (offset >= iso->buf_size)
return -EFAULT;
@@ -329,8 +316,8 @@ static int hpsb_iso_check_offset_len(struct hpsb_iso *iso,
return 0;
}
-int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len,
- u8 tag, u8 sy)
+
+int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag, u8 sy)
{
struct hpsb_iso_packet_info *info;
unsigned long flags;
@@ -347,8 +334,7 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len,
info = &iso->infos[iso->first_packet];
/* check for bogus offset/length */
- if (hpsb_iso_check_offset_len
- (iso, offset, len, &info->offset, &info->len))
+ if (hpsb_iso_check_offset_len(iso, offset, len, &info->offset, &info->len))
return -EFAULT;
info->tag = tag;
@@ -356,13 +342,13 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len,
spin_lock_irqsave(&iso->lock, flags);
- rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long)info);
+ rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long) info);
if (rv)
goto out;
/* increment cursors */
- iso->first_packet = (iso->first_packet + 1) % iso->buf_packets;
- iso->xmit_cycle = (iso->xmit_cycle + 1) % 8000;
+ iso->first_packet = (iso->first_packet+1) % iso->buf_packets;
+ iso->xmit_cycle = (iso->xmit_cycle+1) % 8000;
iso->n_ready_packets--;
if (iso->prebuffer != 0) {
@@ -373,7 +359,7 @@ int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len,
}
}
- out:
+out:
spin_unlock_irqrestore(&iso->lock, flags);
return rv;
}
@@ -383,9 +369,7 @@ int hpsb_iso_xmit_sync(struct hpsb_iso *iso)
if (iso->type != HPSB_ISO_XMIT)
return -EINVAL;
- return wait_event_interruptible(iso->waitq,
- hpsb_iso_n_ready(iso) ==
- iso->buf_packets);
+ return wait_event_interruptible(iso->waitq, hpsb_iso_n_ready(iso) == iso->buf_packets);
}
void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error)
@@ -412,8 +396,7 @@ void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error)
}
void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
- u16 total_len, u16 cycle, u8 channel, u8 tag,
- u8 sy)
+ u16 total_len, u16 cycle, u8 channel, u8 tag, u8 sy)
{
unsigned long flags;
spin_lock_irqsave(&iso->lock, flags);
@@ -433,7 +416,7 @@ void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
info->tag = tag;
info->sy = sy;
- iso->pkt_dma = (iso->pkt_dma + 1) % iso->buf_packets;
+ iso->pkt_dma = (iso->pkt_dma+1) % iso->buf_packets;
iso->n_ready_packets++;
}
@@ -452,21 +435,20 @@ int hpsb_iso_recv_release_packets(struct hpsb_iso *iso, unsigned int n_packets)
spin_lock_irqsave(&iso->lock, flags);
for (i = 0; i < n_packets; i++) {
rv = iso->host->driver->isoctl(iso, RECV_RELEASE,
- (unsigned long)&iso->infos[iso->
- first_packet]);
+ (unsigned long) &iso->infos[iso->first_packet]);
if (rv)
break;
- iso->first_packet = (iso->first_packet + 1) % iso->buf_packets;
+ iso->first_packet = (iso->first_packet+1) % iso->buf_packets;
iso->n_ready_packets--;
/* release memory from packets discarded when queue was full */
- if (iso->n_ready_packets == 0) { /* Release only after all prior packets handled */
+ if (iso->n_ready_packets == 0) { /* Release only after all prior packets handled */
if (iso->bytes_discarded != 0) {
struct hpsb_iso_packet_info inf;
inf.total_len = iso->bytes_discarded;
iso->host->driver->isoctl(iso, RECV_RELEASE,
- (unsigned long)&inf);
+ (unsigned long) &inf);
iso->bytes_discarded = 0;
}
}
diff --git a/trunk/drivers/ieee1394/nodemgr.c b/trunk/drivers/ieee1394/nodemgr.c
index 082c7fd239f5..0ea37b1bccb2 100644
--- a/trunk/drivers/ieee1394/nodemgr.c
+++ b/trunk/drivers/ieee1394/nodemgr.c
@@ -121,8 +121,8 @@ struct host_info {
};
static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
-static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
- char *buffer, int buffer_size);
+static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp,
+ char *buffer, int buffer_size);
static void nodemgr_resume_ne(struct node_entry *ne);
static void nodemgr_remove_ne(struct node_entry *ne);
static struct node_entry *find_entry_by_guid(u64 guid);
@@ -162,7 +162,7 @@ static void ud_cls_release(struct class_device *class_dev)
static struct class nodemgr_ud_class = {
.name = "ieee1394",
.release = ud_cls_release,
- .uevent = nodemgr_uevent,
+ .hotplug = nodemgr_hotplug,
};
static struct hpsb_highlevel nodemgr_highlevel;
@@ -743,20 +743,21 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
unsigned int generation)
{
struct hpsb_host *host = hi->host;
- struct node_entry *ne;
+ struct node_entry *ne;
- ne = kzalloc(sizeof(*ne), GFP_KERNEL);
- if (!ne)
- return NULL;
+ ne = kmalloc(sizeof(struct node_entry), GFP_KERNEL);
+ if (!ne) return NULL;
+
+ memset(ne, 0, sizeof(struct node_entry));
ne->tpool = &host->tpool[nodeid & NODE_MASK];
- ne->host = host;
- ne->nodeid = nodeid;
+ ne->host = host;
+ ne->nodeid = nodeid;
ne->generation = generation;
ne->needs_probe = 1;
- ne->guid = guid;
+ ne->guid = guid;
ne->guid_vendor_id = (guid >> 40) & 0xffffff;
ne->guid_vendor_oui = nodemgr_find_oui_name(ne->guid_vendor_id);
ne->csr = csr;
@@ -786,7 +787,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
(host->node_id == nodeid) ? "Host" : "Node",
NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid);
- return ne;
+ return ne;
}
@@ -871,10 +872,12 @@ static struct unit_directory *nodemgr_process_unit_directory
struct csr1212_keyval *kv;
u8 last_key_id = 0;
- ud = kzalloc(sizeof(*ud), GFP_KERNEL);
+ ud = kmalloc(sizeof(struct unit_directory), GFP_KERNEL);
if (!ud)
goto unit_directory_error;
+ memset (ud, 0, sizeof(struct unit_directory));
+
ud->ne = ne;
ud->ignore_driver = ignore_drivers;
ud->address = ud_kv->offset + CSR1212_CONFIG_ROM_SPACE_BASE;
@@ -934,10 +937,10 @@ static struct unit_directory *nodemgr_process_unit_directory
/* Logical Unit Number */
if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) {
if (ud->flags & UNIT_DIRECTORY_HAS_LUN) {
- ud_child = kmalloc(sizeof(*ud_child), GFP_KERNEL);
+ ud_child = kmalloc(sizeof(struct unit_directory), GFP_KERNEL);
if (!ud_child)
goto unit_directory_error;
- memcpy(ud_child, ud, sizeof(*ud_child));
+ memcpy(ud_child, ud, sizeof(struct unit_directory));
nodemgr_register_device(ne, ud_child, &ne->device);
ud_child = NULL;
@@ -963,7 +966,7 @@ static struct unit_directory *nodemgr_process_unit_directory
if (ud_child == NULL)
break;
- /* inherit unspecified values, the driver core picks it up */
+ /* inherit unspecified values so hotplug picks it up */
if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) &&
!(ud_child->flags & UNIT_DIRECTORY_MODEL_ID))
{
@@ -1059,8 +1062,8 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
#ifdef CONFIG_HOTPLUG
-static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
- char *buffer, int buffer_size)
+static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp,
+ char *buffer, int buffer_size)
{
struct unit_directory *ud;
int i = 0;
@@ -1109,8 +1112,8 @@ do { \
#else
-static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
- char *buffer, int buffer_size)
+static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp,
+ char *buffer, int buffer_size)
{
return -ENODEV;
}
@@ -1197,7 +1200,7 @@ static void nodemgr_node_scan_one(struct host_info *hi,
struct csr1212_csr *csr;
struct nodemgr_csr_info *ci;
- ci = kmalloc(sizeof(*ci), GFP_KERNEL);
+ ci = kmalloc(sizeof(struct nodemgr_csr_info), GFP_KERNEL);
if (!ci)
return;
@@ -1407,28 +1410,14 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
struct hpsb_host *host = hi->host;
struct class *class = &nodemgr_ne_class;
struct class_device *cdev;
- struct node_entry *ne;
/* Do some processing of the nodes we've probed. This pulls them
* into the sysfs layer if needed, and can result in processing of
* unit-directories, or just updating the node and it's
- * unit-directories.
- *
- * Run updates before probes. Usually, updates are time-critical
- * while probes are time-consuming. (Well, those probes need some
- * improvement...) */
-
+ * unit-directories. */
down_read(&class->subsys.rwsem);
- list_for_each_entry(cdev, &class->children, node) {
- ne = container_of(cdev, struct node_entry, class_dev);
- if (!ne->needs_probe)
- nodemgr_probe_ne(hi, ne, generation);
- }
- list_for_each_entry(cdev, &class->children, node) {
- ne = container_of(cdev, struct node_entry, class_dev);
- if (ne->needs_probe)
- nodemgr_probe_ne(hi, ne, generation);
- }
+ list_for_each_entry(cdev, &class->children, node)
+ nodemgr_probe_ne(hi, container_of(cdev, struct node_entry, class_dev), generation);
up_read(&class->subsys.rwsem);
@@ -1459,8 +1448,7 @@ static int nodemgr_send_resume_packet(struct hpsb_host *host)
int ret = 1;
packet = hpsb_make_phypacket(host,
- EXTPHYPACKET_TYPE_RESUME |
- NODEID_TO_NODE(host->node_id) << PHYPACKET_PORT_SHIFT);
+ 0x003c0000 | NODEID_TO_NODE(host->node_id) << 24);
if (packet) {
packet->no_waiter = 1;
packet->generation = get_hpsb_generation(host);
@@ -1630,8 +1618,8 @@ static int nodemgr_host_thread(void *__hi)
/* Scan our nodes to get the bus options and create node
* entries. This does not do the sysfs stuff, since that
- * would trigger uevents and such, which is a bad idea at
- * this point. */
+ * would trigger hotplug callbacks and such, which is a
+ * bad idea at this point. */
nodemgr_node_scan(hi, generation);
/* This actually does the full probe, with sysfs
diff --git a/trunk/drivers/ieee1394/nodemgr.h b/trunk/drivers/ieee1394/nodemgr.h
index 0b26616e16c3..3a2f0c02fd08 100644
--- a/trunk/drivers/ieee1394/nodemgr.h
+++ b/trunk/drivers/ieee1394/nodemgr.h
@@ -150,6 +150,24 @@ static inline int hpsb_node_entry_valid(struct node_entry *ne)
return ne->generation == get_hpsb_generation(ne->host);
}
+/*
+ * Returns a node entry (which has its reference count incremented) or NULL if
+ * the GUID in question is not known. Getting a valid entry does not mean that
+ * the node with this GUID is currently accessible (might be powered down).
+ */
+struct node_entry *hpsb_guid_get_entry(u64 guid);
+
+/* Same as above, but use the nodeid to get an node entry. This is not
+ * fool-proof by itself, since the nodeid can change. */
+struct node_entry *hpsb_nodeid_get_entry(struct hpsb_host *host, nodeid_t nodeid);
+
+/*
+ * If the entry refers to a local host, this function will return the pointer
+ * to the hpsb_host structure. It will return NULL otherwise. Once you have
+ * established it is a local host, you can use that knowledge from then on (the
+ * GUID won't wander to an external node). */
+struct hpsb_host *hpsb_get_host_by_ne(struct node_entry *ne);
+
/*
* This will fill in the given, pre-initialised hpsb_packet with the current
* information from the node entry (host, node ID, generation number). It will
diff --git a/trunk/drivers/ieee1394/ohci1394.c b/trunk/drivers/ieee1394/ohci1394.c
index b6b96fa04d62..4cf9b8f3e336 100644
--- a/trunk/drivers/ieee1394/ohci1394.c
+++ b/trunk/drivers/ieee1394/ohci1394.c
@@ -161,6 +161,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
#define PRINT(level, fmt, args...) \
printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
+static char version[] __devinitdata =
+ "$Rev: 1313 $ Ben Collins ";
+
/* Module Parameters */
static int phys_dma = 1;
module_param(phys_dma, int, 0644);
@@ -584,13 +587,12 @@ static void ohci_initialize(struct ti_ohci *ohci)
sprintf (irq_buf, "%s", __irq_itoa(ohci->dev->irq));
#endif
PRINT(KERN_INFO, "OHCI-1394 %d.%d (PCI): IRQ=[%s] "
- "MMIO=[%lx-%lx] Max Packet=[%d] IR/IT contexts=[%d/%d]",
+ "MMIO=[%lx-%lx] Max Packet=[%d]",
((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10),
((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), irq_buf,
pci_resource_start(ohci->dev, 0),
pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1,
- ohci->max_packet_size,
- ohci->nb_iso_rcv_ctx, ohci->nb_iso_xmit_ctx);
+ ohci->max_packet_size);
/* Check all of our ports to make sure that if anything is
* connected, we enable that port. */
@@ -2958,23 +2960,28 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
d->ctrlClear = 0;
d->cmdPtr = 0;
- d->buf_cpu = kzalloc(d->num_desc * sizeof(*d->buf_cpu), GFP_ATOMIC);
- d->buf_bus = kzalloc(d->num_desc * sizeof(*d->buf_bus), GFP_ATOMIC);
+ d->buf_cpu = kmalloc(d->num_desc * sizeof(quadlet_t*), GFP_ATOMIC);
+ d->buf_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_ATOMIC);
if (d->buf_cpu == NULL || d->buf_bus == NULL) {
PRINT(KERN_ERR, "Failed to allocate dma buffer");
free_dma_rcv_ctx(d);
return -ENOMEM;
}
+ memset(d->buf_cpu, 0, d->num_desc * sizeof(quadlet_t*));
+ memset(d->buf_bus, 0, d->num_desc * sizeof(dma_addr_t));
- d->prg_cpu = kzalloc(d->num_desc * sizeof(*d->prg_cpu), GFP_ATOMIC);
- d->prg_bus = kzalloc(d->num_desc * sizeof(*d->prg_bus), GFP_ATOMIC);
+ d->prg_cpu = kmalloc(d->num_desc * sizeof(struct dma_cmd*),
+ GFP_ATOMIC);
+ d->prg_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_ATOMIC);
if (d->prg_cpu == NULL || d->prg_bus == NULL) {
PRINT(KERN_ERR, "Failed to allocate dma prg");
free_dma_rcv_ctx(d);
return -ENOMEM;
}
+ memset(d->prg_cpu, 0, d->num_desc * sizeof(struct dma_cmd*));
+ memset(d->prg_bus, 0, d->num_desc * sizeof(dma_addr_t));
d->spb = kmalloc(d->split_buf_size, GFP_ATOMIC);
@@ -3086,14 +3093,17 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
d->ctrlClear = 0;
d->cmdPtr = 0;
- d->prg_cpu = kzalloc(d->num_desc * sizeof(*d->prg_cpu), GFP_KERNEL);
- d->prg_bus = kzalloc(d->num_desc * sizeof(*d->prg_bus), GFP_KERNEL);
+ d->prg_cpu = kmalloc(d->num_desc * sizeof(struct at_dma_prg*),
+ GFP_KERNEL);
+ d->prg_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_KERNEL);
if (d->prg_cpu == NULL || d->prg_bus == NULL) {
PRINT(KERN_ERR, "Failed to allocate at dma prg");
free_dma_trm_ctx(d);
return -ENOMEM;
}
+ memset(d->prg_cpu, 0, d->num_desc * sizeof(struct at_dma_prg*));
+ memset(d->prg_bus, 0, d->num_desc * sizeof(dma_addr_t));
len = sprintf(pool_name, "ohci1394_trm_prg");
sprintf(pool_name+len, "%d", num_allocs);
@@ -3191,6 +3201,8 @@ static struct hpsb_host_driver ohci1394_driver = {
.hw_csr_reg = ohci_hw_csr_reg,
};
+
+
/***********************************
* PCI Driver Interface functions *
***********************************/
@@ -3205,10 +3217,15 @@ do { \
static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
+ static int version_printed = 0;
+
struct hpsb_host *host;
struct ti_ohci *ohci; /* shortcut to currently handled device */
unsigned long ohci_base;
+ if (version_printed++ == 0)
+ PRINT_G(KERN_INFO, "%s", version);
+
if (pci_enable_device(dev))
FAIL(-ENXIO, "Failed to enable OHCI hardware");
pci_set_master(dev);
@@ -3352,8 +3369,13 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
/* Determine the number of available IR and IT contexts. */
ohci->nb_iso_rcv_ctx =
get_nb_iso_ctx(ohci, OHCI1394_IsoRecvIntMaskSet);
+ DBGMSG("%d iso receive contexts available",
+ ohci->nb_iso_rcv_ctx);
+
ohci->nb_iso_xmit_ctx =
get_nb_iso_ctx(ohci, OHCI1394_IsoXmitIntMaskSet);
+ DBGMSG("%d iso transmit contexts available",
+ ohci->nb_iso_xmit_ctx);
/* Set the usage bits for non-existent contexts so they can't
* be allocated */
@@ -3584,6 +3606,8 @@ static struct pci_driver ohci1394_pci_driver = {
.suspend = ohci1394_pci_suspend,
};
+
+
/***********************************
* OHCI1394 Video Interface *
***********************************/
@@ -3690,6 +3714,7 @@ EXPORT_SYMBOL(ohci1394_init_iso_tasklet);
EXPORT_SYMBOL(ohci1394_register_iso_tasklet);
EXPORT_SYMBOL(ohci1394_unregister_iso_tasklet);
+
/***********************************
* General module initialization *
***********************************/
diff --git a/trunk/drivers/ieee1394/ohci1394.h b/trunk/drivers/ieee1394/ohci1394.h
index 7df0962144e3..cc66c1cae250 100644
--- a/trunk/drivers/ieee1394/ohci1394.h
+++ b/trunk/drivers/ieee1394/ohci1394.h
@@ -219,8 +219,8 @@ struct ti_ohci {
int self_id_errors;
- /* Tasklets for iso receive and transmit, used by video1394
- * and dv1394 */
+ /* Tasklets for iso receive and transmit, used by video1394,
+ * amdtp and dv1394 */
struct list_head iso_tasklet_list;
spinlock_t iso_tasklet_list_lock;
diff --git a/trunk/drivers/ieee1394/pcilynx.c b/trunk/drivers/ieee1394/pcilynx.c
index e2edc41e1b6f..6b1ab875333b 100644
--- a/trunk/drivers/ieee1394/pcilynx.c
+++ b/trunk/drivers/ieee1394/pcilynx.c
@@ -1435,7 +1435,7 @@ static int __devinit add_card(struct pci_dev *dev,
struct i2c_algo_bit_data i2c_adapter_data;
error = -ENOMEM;
- i2c_ad = kmalloc(sizeof(*i2c_ad), SLAB_KERNEL);
+ i2c_ad = kmalloc(sizeof(struct i2c_adapter), SLAB_KERNEL);
if (!i2c_ad) FAIL("failed to allocate I2C adapter memory");
memcpy(i2c_ad, &bit_ops, sizeof(struct i2c_adapter));
diff --git a/trunk/drivers/ieee1394/raw1394.c b/trunk/drivers/ieee1394/raw1394.c
index b05235639918..24411e666b21 100644
--- a/trunk/drivers/ieee1394/raw1394.c
+++ b/trunk/drivers/ieee1394/raw1394.c
@@ -102,9 +102,12 @@ static struct pending_request *__alloc_pending_request(gfp_t flags)
{
struct pending_request *req;
- req = kzalloc(sizeof(*req), flags);
- if (req)
+ req = (struct pending_request *)kmalloc(sizeof(struct pending_request),
+ flags);
+ if (req != NULL) {
+ memset(req, 0, sizeof(struct pending_request));
INIT_LIST_HEAD(&req->list);
+ }
return req;
}
@@ -189,9 +192,9 @@ static void add_host(struct hpsb_host *host)
struct host_info *hi;
unsigned long flags;
- hi = kmalloc(sizeof(*hi), GFP_KERNEL);
+ hi = (struct host_info *)kmalloc(sizeof(struct host_info), GFP_KERNEL);
- if (hi) {
+ if (hi != NULL) {
INIT_LIST_HEAD(&hi->list);
hi->host = host;
INIT_LIST_HEAD(&hi->file_info_list);
@@ -312,8 +315,8 @@ static void iso_receive(struct hpsb_host *host, int channel, quadlet_t * data,
break;
if (!ibs) {
- ibs = kmalloc(sizeof(*ibs) + length,
- SLAB_ATOMIC);
+ ibs = kmalloc(sizeof(struct iso_block_store)
+ + length, SLAB_ATOMIC);
if (!ibs) {
kfree(req);
break;
@@ -373,8 +376,8 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
break;
if (!ibs) {
- ibs = kmalloc(sizeof(*ibs) + length,
- SLAB_ATOMIC);
+ ibs = kmalloc(sizeof(struct iso_block_store)
+ + length, SLAB_ATOMIC);
if (!ibs) {
kfree(req);
break;
@@ -499,9 +502,10 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
switch (req->req.type) {
case RAW1394_REQ_LIST_CARDS:
spin_lock_irqsave(&host_info_lock, flags);
- khl = kmalloc(sizeof(*khl) * host_count, SLAB_ATOMIC);
+ khl = kmalloc(sizeof(struct raw1394_khost_list) * host_count,
+ SLAB_ATOMIC);
- if (khl) {
+ if (khl != NULL) {
req->req.misc = host_count;
req->data = (quadlet_t *) khl;
@@ -513,7 +517,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
}
spin_unlock_irqrestore(&host_info_lock, flags);
- if (khl) {
+ if (khl != NULL) {
req->req.error = RAW1394_ERROR_NONE;
req->req.length = min(req->req.length,
(u32) (sizeof
@@ -1643,13 +1647,13 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
return (-EINVAL);
}
/* addr-list-entry for fileinfo */
- addr = kmalloc(sizeof(*addr), SLAB_KERNEL);
+ addr = (struct arm_addr *)kmalloc(sizeof(struct arm_addr), SLAB_KERNEL);
if (!addr) {
req->req.length = 0;
return (-ENOMEM);
}
/* allocation of addr_space_buffer */
- addr->addr_space_buffer = vmalloc(req->req.length);
+ addr->addr_space_buffer = (u8 *) vmalloc(req->req.length);
if (!(addr->addr_space_buffer)) {
kfree(addr);
req->req.length = 0;
@@ -2118,7 +2122,8 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
return -ENOMEM;
}
- cache->filled_head = kmalloc(sizeof(*cache->filled_head), GFP_KERNEL);
+ cache->filled_head =
+ kmalloc(sizeof(struct csr1212_cache_region), GFP_KERNEL);
if (!cache->filled_head) {
csr1212_release_keyval(fi->csr1212_dirs[dr]);
fi->csr1212_dirs[dr] = NULL;
@@ -2131,6 +2136,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
req->req.length)) {
csr1212_release_keyval(fi->csr1212_dirs[dr]);
fi->csr1212_dirs[dr] = NULL;
+ CSR1212_FREE(cache);
ret = -EFAULT;
} else {
cache->len = req->req.length;
@@ -2166,7 +2172,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
}
}
kfree(cache->filled_head);
- CSR1212_FREE(cache);
+ kfree(cache);
if (ret >= 0) {
/* we have to free the request, because we queue no response,
@@ -2482,8 +2488,8 @@ static int raw1394_iso_recv_packets(struct file_info *fi, void __user * uaddr)
/* ensure user-supplied buffer is accessible and big enough */
if (!access_ok(VERIFY_WRITE, upackets.infos,
- upackets.n_packets *
- sizeof(struct raw1394_iso_packet_info)))
+ upackets.n_packets *
+ sizeof(struct raw1394_iso_packet_info)))
return -EFAULT;
/* copy the packet_infos out */
@@ -2516,8 +2522,8 @@ static int raw1394_iso_send_packets(struct file_info *fi, void __user * uaddr)
/* ensure user-supplied buffer is accessible and big enough */
if (!access_ok(VERIFY_READ, upackets.infos,
- upackets.n_packets *
- sizeof(struct raw1394_iso_packet_info)))
+ upackets.n_packets *
+ sizeof(struct raw1394_iso_packet_info)))
return -EFAULT;
/* copy the infos structs in and queue the packets */
@@ -2678,10 +2684,11 @@ static int raw1394_open(struct inode *inode, struct file *file)
{
struct file_info *fi;
- fi = kzalloc(sizeof(*fi), SLAB_KERNEL);
- if (!fi)
+ fi = kmalloc(sizeof(struct file_info), SLAB_KERNEL);
+ if (fi == NULL)
return -ENOMEM;
+ memset(fi, 0, sizeof(struct file_info));
fi->notification = (u8) RAW1394_NOTIFY_ON; /* busreset notification */
INIT_LIST_HEAD(&fi->list);
@@ -2741,7 +2748,8 @@ static int raw1394_release(struct inode *inode, struct file *file)
list) {
entry = fi_hlp->addr_list.next;
while (entry != &(fi_hlp->addr_list)) {
- arm_addr = list_entry(entry, struct
+ arm_addr = list_entry(entry,
+ struct
arm_addr,
addr_list);
if (arm_addr->start ==
@@ -2904,17 +2912,16 @@ static int __init init_raw1394(void)
hpsb_register_highlevel(&raw1394_highlevel);
- if (IS_ERR
- (class_device_create
- (hpsb_protocol_class, NULL,
- MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), NULL,
- RAW1394_DEVICE_NAME))) {
+ if (IS_ERR(class_device_create(hpsb_protocol_class, NULL, MKDEV(
+ IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
+ NULL, RAW1394_DEVICE_NAME))) {
ret = -EFAULT;
goto out_unreg;
}
-
- devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
- S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME);
+
+ devfs_mk_cdev(MKDEV(
+ IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
+ S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME);
cdev_init(&raw1394_cdev, &raw1394_fops);
raw1394_cdev.owner = THIS_MODULE;
@@ -2936,22 +2943,20 @@ static int __init init_raw1394(void)
goto out;
- out_dev:
+out_dev:
devfs_remove(RAW1394_DEVICE_NAME);
class_device_destroy(hpsb_protocol_class,
- MKDEV(IEEE1394_MAJOR,
- IEEE1394_MINOR_BLOCK_RAW1394 * 16));
- out_unreg:
+ MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
+out_unreg:
hpsb_unregister_highlevel(&raw1394_highlevel);
- out:
+out:
return ret;
}
static void __exit cleanup_raw1394(void)
{
class_device_destroy(hpsb_protocol_class,
- MKDEV(IEEE1394_MAJOR,
- IEEE1394_MINOR_BLOCK_RAW1394 * 16));
+ MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
cdev_del(&raw1394_cdev);
devfs_remove(RAW1394_DEVICE_NAME);
hpsb_unregister_highlevel(&raw1394_highlevel);
diff --git a/trunk/drivers/ieee1394/sbp2.c b/trunk/drivers/ieee1394/sbp2.c
index 18d7eda38851..f7e18ccc5c0a 100644
--- a/trunk/drivers/ieee1394/sbp2.c
+++ b/trunk/drivers/ieee1394/sbp2.c
@@ -80,6 +80,9 @@
#include "ieee1394_transactions.h"
#include "sbp2.h"
+static char version[] __devinitdata =
+ "$Rev: 1306 $ Ben Collins ";
+
/*
* Module load parameter definitions
*/
@@ -148,15 +151,18 @@ static int force_inquiry_hack;
module_param(force_inquiry_hack, int, 0444);
MODULE_PARM_DESC(force_inquiry_hack, "Force SCSI inquiry hack (default = 0)");
+
/*
* Export information about protocols/devices supported by this driver.
*/
static struct ieee1394_device_id sbp2_id_table[] = {
{
- .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
- .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
- .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
- {}
+ .match_flags =IEEE1394_MATCH_SPECIFIER_ID |
+ IEEE1394_MATCH_VERSION,
+ .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
+ .version = SBP2_SW_VERSION_ENTRY & 0xffffff
+ },
+ { }
};
MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
@@ -215,6 +221,7 @@ static u32 global_outstanding_dmas = 0;
#define SBP2_ERR(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args)
+
/*
* Globals
*/
@@ -247,8 +254,8 @@ static struct hpsb_address_ops sbp2_ops = {
#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
static struct hpsb_address_ops sbp2_physdma_ops = {
- .read = sbp2_handle_physdma_read,
- .write = sbp2_handle_physdma_write,
+ .read = sbp2_handle_physdma_read,
+ .write = sbp2_handle_physdma_write,
};
#endif
@@ -280,6 +287,7 @@ static u32 sbp2_broken_inquiry_list[] = {
* General utility functions
**************************************/
+
#ifndef __BIG_ENDIAN
/*
* Converts a buffer from be32 to cpu byte ordering. Length is in bytes.
@@ -316,8 +324,7 @@ static __inline__ void sbp2util_cpu_to_be32_buffer(void *buffer, int length)
/*
* Debug packet dump routine. Length is in bytes.
*/
-static void sbp2util_packet_dump(void *buffer, int length, char *dump_name,
- u32 dump_phys_addr)
+static void sbp2util_packet_dump(void *buffer, int length, char *dump_name, u32 dump_phys_addr)
{
int i;
unsigned char *dump = buffer;
@@ -338,7 +345,7 @@ static void sbp2util_packet_dump(void *buffer, int length, char *dump_name,
printk(" ");
if ((i & 0xf) == 0)
printk("\n ");
- printk("%02x ", (int)dump[i]);
+ printk("%02x ", (int) dump[i]);
}
printk("\n");
@@ -357,9 +364,9 @@ static int sbp2util_down_timeout(atomic_t *done, int timeout)
for (i = timeout; (i > 0 && atomic_read(done) == 0); i-= HZ/10) {
if (msleep_interruptible(100)) /* 100ms */
- return 1;
+ return(1);
}
- return (i > 0) ? 0 : 1;
+ return ((i > 0) ? 0:1);
}
/* Free's an allocated packet */
@@ -373,22 +380,21 @@ static void sbp2_free_packet(struct hpsb_packet *packet)
* subaction and returns immediately. Can be used from interrupts.
*/
static int sbp2util_node_write_no_wait(struct node_entry *ne, u64 addr,
- quadlet_t *buffer, size_t length)
+ quadlet_t *buffer, size_t length)
{
struct hpsb_packet *packet;
packet = hpsb_make_writepacket(ne->host, ne->nodeid,
addr, buffer, length);
- if (!packet)
- return -ENOMEM;
+ if (!packet)
+ return -ENOMEM;
- hpsb_set_packet_complete_task(packet,
- (void (*)(void *))sbp2_free_packet,
+ hpsb_set_packet_complete_task(packet, (void (*)(void*))sbp2_free_packet,
packet);
hpsb_node_fill_packet(ne, packet);
- if (hpsb_send_packet(packet) < 0) {
+ if (hpsb_send_packet(packet) < 0) {
sbp2_free_packet(packet);
return -EIO;
}
@@ -411,22 +417,22 @@ static int sbp2util_create_command_orb_pool(struct scsi_id_instance_data *scsi_i
spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
for (i = 0; i < orbs; i++) {
- command = kzalloc(sizeof(*command), GFP_ATOMIC);
+ command = (struct sbp2_command_info *)
+ kmalloc(sizeof(struct sbp2_command_info), GFP_ATOMIC);
if (!command) {
- spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock,
- flags);
- return -ENOMEM;
+ spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
+ return(-ENOMEM);
}
+ memset(command, '\0', sizeof(struct sbp2_command_info));
command->command_orb_dma =
- pci_map_single(hi->host->pdev, &command->command_orb,
- sizeof(struct sbp2_command_orb),
- PCI_DMA_BIDIRECTIONAL);
+ pci_map_single (hi->host->pdev, &command->command_orb,
+ sizeof(struct sbp2_command_orb),
+ PCI_DMA_BIDIRECTIONAL);
SBP2_DMA_ALLOC("single command orb DMA");
command->sge_dma =
- pci_map_single(hi->host->pdev,
- &command->scatter_gather_element,
- sizeof(command->scatter_gather_element),
- PCI_DMA_BIDIRECTIONAL);
+ pci_map_single (hi->host->pdev, &command->scatter_gather_element,
+ sizeof(command->scatter_gather_element),
+ PCI_DMA_BIDIRECTIONAL);
SBP2_DMA_ALLOC("scatter_gather_element");
INIT_LIST_HEAD(&command->list);
list_add_tail(&command->list, &scsi_id->sbp2_command_orb_completed);
@@ -482,7 +488,7 @@ static struct sbp2_command_info *sbp2util_find_command_for_orb(
list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) {
if (command->command_orb_dma == orb) {
spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
- return command;
+ return (command);
}
}
}
@@ -490,7 +496,7 @@ static struct sbp2_command_info *sbp2util_find_command_for_orb(
SBP2_ORB_DEBUG("could not match command orb %x", (unsigned int)orb);
- return NULL;
+ return(NULL);
}
/*
@@ -507,12 +513,12 @@ static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_
list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) {
if (command->Current_SCpnt == SCpnt) {
spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
- return command;
+ return (command);
}
}
}
spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
- return NULL;
+ return(NULL);
}
/*
@@ -539,7 +545,7 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb(
SBP2_ERR("sbp2util_allocate_command_orb - No orbs available!");
}
spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
- return command;
+ return (command);
}
/* Free our DMA's */
@@ -581,8 +587,7 @@ static void sbp2util_free_command_dma(struct sbp2_command_info *command)
/*
* This function moves a command to the completed orb list.
*/
-static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id,
- struct sbp2_command_info *command)
+static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id, struct sbp2_command_info *command)
{
unsigned long flags;
@@ -601,6 +606,8 @@ static inline int sbp2util_node_is_available(struct scsi_id_instance_data *scsi_
return scsi_id && scsi_id->ne && !scsi_id->ne->in_limbo;
}
+
+
/*********************************************
* IEEE-1394 core driver stack related section
*********************************************/
@@ -620,14 +627,14 @@ static int sbp2_probe(struct device *dev)
if (ud->flags & UNIT_DIRECTORY_HAS_LUN_DIRECTORY)
return -ENODEV;
- scsi_id = sbp2_alloc_device(ud);
+ scsi_id = sbp2_alloc_device(ud);
- if (!scsi_id)
- return -ENOMEM;
+ if (!scsi_id)
+ return -ENOMEM;
- sbp2_parse_unit_directory(scsi_id, ud);
+ sbp2_parse_unit_directory(scsi_id, ud);
- return sbp2_start_device(scsi_id);
+ return sbp2_start_device(scsi_id);
}
static int sbp2_remove(struct device *dev)
@@ -712,11 +719,12 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud
SBP2_DEBUG("sbp2_alloc_device");
- scsi_id = kzalloc(sizeof(*scsi_id), GFP_KERNEL);
+ scsi_id = kmalloc(sizeof(*scsi_id), GFP_KERNEL);
if (!scsi_id) {
SBP2_ERR("failed to create scsi_id");
goto failed_alloc;
}
+ memset(scsi_id, 0, sizeof(*scsi_id));
scsi_id->ne = ud->ne;
scsi_id->ud = ud;
@@ -727,7 +735,7 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud
INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed);
INIT_LIST_HEAD(&scsi_id->scsi_list);
spin_lock_init(&scsi_id->sbp2_command_orb_lock);
- scsi_id->sbp2_lun = 0;
+ scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED;
ud->device.driver_data = scsi_id;
@@ -761,7 +769,7 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud
/* Register our host with the SCSI stack. */
scsi_host = scsi_host_alloc(&scsi_driver_template,
- sizeof(unsigned long));
+ sizeof (unsigned long));
if (!scsi_host) {
SBP2_ERR("failed to register scsi host");
goto failed_alloc;
@@ -782,6 +790,7 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud
return NULL;
}
+
static void sbp2_host_reset(struct hpsb_host *host)
{
struct sbp2scsi_host_info *hi;
@@ -795,6 +804,7 @@ static void sbp2_host_reset(struct hpsb_host *host)
}
}
+
/*
* This function is where we first pull the node unique ids, and then
* allocate memory and register a SBP-2 device.
@@ -808,8 +818,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
/* Login FIFO DMA */
scsi_id->login_response =
- pci_alloc_consistent(hi->host->pdev,
- sizeof(struct sbp2_login_response),
+ pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_login_response),
&scsi_id->login_response_dma);
if (!scsi_id->login_response)
goto alloc_fail;
@@ -817,8 +826,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
/* Query logins ORB DMA */
scsi_id->query_logins_orb =
- pci_alloc_consistent(hi->host->pdev,
- sizeof(struct sbp2_query_logins_orb),
+ pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_query_logins_orb),
&scsi_id->query_logins_orb_dma);
if (!scsi_id->query_logins_orb)
goto alloc_fail;
@@ -826,8 +834,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
/* Query logins response DMA */
scsi_id->query_logins_response =
- pci_alloc_consistent(hi->host->pdev,
- sizeof(struct sbp2_query_logins_response),
+ pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_query_logins_response),
&scsi_id->query_logins_response_dma);
if (!scsi_id->query_logins_response)
goto alloc_fail;
@@ -835,8 +842,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
/* Reconnect ORB DMA */
scsi_id->reconnect_orb =
- pci_alloc_consistent(hi->host->pdev,
- sizeof(struct sbp2_reconnect_orb),
+ pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_reconnect_orb),
&scsi_id->reconnect_orb_dma);
if (!scsi_id->reconnect_orb)
goto alloc_fail;
@@ -844,8 +850,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
/* Logout ORB DMA */
scsi_id->logout_orb =
- pci_alloc_consistent(hi->host->pdev,
- sizeof(struct sbp2_logout_orb),
+ pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_logout_orb),
&scsi_id->logout_orb_dma);
if (!scsi_id->logout_orb)
goto alloc_fail;
@@ -853,11 +858,58 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
/* Login ORB DMA */
scsi_id->login_orb =
- pci_alloc_consistent(hi->host->pdev,
- sizeof(struct sbp2_login_orb),
+ pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_login_orb),
&scsi_id->login_orb_dma);
- if (!scsi_id->login_orb)
- goto alloc_fail;
+ if (!scsi_id->login_orb) {
+alloc_fail:
+ if (scsi_id->query_logins_response) {
+ pci_free_consistent(hi->host->pdev,
+ sizeof(struct sbp2_query_logins_response),
+ scsi_id->query_logins_response,
+ scsi_id->query_logins_response_dma);
+ SBP2_DMA_FREE("query logins response DMA");
+ }
+
+ if (scsi_id->query_logins_orb) {
+ pci_free_consistent(hi->host->pdev,
+ sizeof(struct sbp2_query_logins_orb),
+ scsi_id->query_logins_orb,
+ scsi_id->query_logins_orb_dma);
+ SBP2_DMA_FREE("query logins ORB DMA");
+ }
+
+ if (scsi_id->logout_orb) {
+ pci_free_consistent(hi->host->pdev,
+ sizeof(struct sbp2_logout_orb),
+ scsi_id->logout_orb,
+ scsi_id->logout_orb_dma);
+ SBP2_DMA_FREE("logout ORB DMA");
+ }
+
+ if (scsi_id->reconnect_orb) {
+ pci_free_consistent(hi->host->pdev,
+ sizeof(struct sbp2_reconnect_orb),
+ scsi_id->reconnect_orb,
+ scsi_id->reconnect_orb_dma);
+ SBP2_DMA_FREE("reconnect ORB DMA");
+ }
+
+ if (scsi_id->login_response) {
+ pci_free_consistent(hi->host->pdev,
+ sizeof(struct sbp2_login_response),
+ scsi_id->login_response,
+ scsi_id->login_response_dma);
+ SBP2_DMA_FREE("login FIFO DMA");
+ }
+
+ list_del(&scsi_id->scsi_list);
+
+ kfree(scsi_id);
+
+ SBP2_ERR ("Could not allocate memory for scsi_id");
+
+ return -ENOMEM;
+ }
SBP2_DMA_ALLOC("consistent DMA region for login ORB");
SBP2_DEBUG("New SBP-2 device inserted, SCSI ID = %x", scsi_id->ud->id);
@@ -883,7 +935,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
sbp2_remove_device(scsi_id);
return -EINTR;
}
-
+
/*
* Login to the sbp-2 device
*/
@@ -912,17 +964,10 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
error = scsi_add_device(scsi_id->scsi_host, 0, scsi_id->ud->id, 0);
if (error) {
SBP2_ERR("scsi_add_device failed");
- sbp2_logout_device(scsi_id);
- sbp2_remove_device(scsi_id);
return error;
}
return 0;
-
-alloc_fail:
- SBP2_ERR("Could not allocate memory for scsi_id");
- sbp2_remove_device(scsi_id);
- return -ENOMEM;
}
/*
@@ -1009,43 +1054,50 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id)
* This function deals with physical dma write requests (for adapters that do not support
* physical dma in hardware). Mostly just here for debugging...
*/
-static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid,
- int destid, quadlet_t *data, u64 addr,
- size_t length, u16 flags)
+static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data,
+ u64 addr, size_t length, u16 flags)
{
- /*
- * Manually put the data in the right place.
- */
- memcpy(bus_to_virt((u32) addr), data, length);
- sbp2util_packet_dump(data, length, "sbp2 phys dma write by device",
- (u32) addr);
- return RCODE_COMPLETE;
+ /*
+ * Manually put the data in the right place.
+ */
+ memcpy(bus_to_virt((u32)addr), data, length);
+ sbp2util_packet_dump(data, length, "sbp2 phys dma write by device", (u32)addr);
+ return(RCODE_COMPLETE);
}
/*
* This function deals with physical dma read requests (for adapters that do not support
* physical dma in hardware). Mostly just here for debugging...
*/
-static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid,
- quadlet_t *data, u64 addr, size_t length,
- u16 flags)
+static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data,
+ u64 addr, size_t length, u16 flags)
{
- /*
- * Grab data from memory and send a read response.
- */
- memcpy(data, bus_to_virt((u32) addr), length);
- sbp2util_packet_dump(data, length, "sbp2 phys dma read by device",
- (u32) addr);
- return RCODE_COMPLETE;
+ /*
+ * Grab data from memory and send a read response.
+ */
+ memcpy(data, bus_to_virt((u32)addr), length);
+ sbp2util_packet_dump(data, length, "sbp2 phys dma read by device", (u32)addr);
+ return(RCODE_COMPLETE);
}
#endif
+
/**************************************
* SBP-2 protocol related section
**************************************/
+/*
+ * This function determines if we should convert scsi commands for a particular sbp2 device type
+ */
+static __inline__ int sbp2_command_conversion_device_type(u8 device_type)
+{
+ return (((device_type == TYPE_DISK) ||
+ (device_type == TYPE_RBC) ||
+ (device_type == TYPE_ROM)) ? 1:0);
+}
+
/*
* This function queries the device for the maximum concurrent logins it
* supports.
@@ -1068,7 +1120,11 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id)
scsi_id->query_logins_orb->lun_misc = ORB_SET_FUNCTION(SBP2_QUERY_LOGINS_REQUEST);
scsi_id->query_logins_orb->lun_misc |= ORB_SET_NOTIFY(1);
- scsi_id->query_logins_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_lun);
+ if (scsi_id->sbp2_device_type_and_lun != SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) {
+ scsi_id->query_logins_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun);
+ SBP2_DEBUG("sbp2_query_logins: set lun to %d",
+ ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun));
+ }
SBP2_DEBUG("sbp2_query_logins: lun_misc initialized");
scsi_id->query_logins_orb->reserved_resp_length =
@@ -1105,12 +1161,12 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id)
if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 2*HZ)) {
SBP2_INFO("Error querying logins to SBP-2 device - timed out");
- return -EIO;
+ return(-EIO);
}
if (scsi_id->status_block.ORB_offset_lo != scsi_id->query_logins_orb_dma) {
SBP2_INFO("Error querying logins to SBP-2 device - timed out");
- return -EIO;
+ return(-EIO);
}
if (STATUS_GET_RESP(scsi_id->status_block.ORB_offset_hi_misc) ||
@@ -1118,7 +1174,7 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id)
STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
SBP2_INFO("Error querying logins to SBP-2 device - timed out");
- return -EIO;
+ return(-EIO);
}
sbp2util_cpu_to_be32_buffer(scsi_id->query_logins_response, sizeof(struct sbp2_query_logins_response));
@@ -1135,7 +1191,7 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id)
SBP2_DEBUG("Number of active logins: %d", active_logins);
if (active_logins >= max_logins) {
- return -EIO;
+ return(-EIO);
}
return 0;
@@ -1154,13 +1210,13 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id)
if (!scsi_id->login_orb) {
SBP2_DEBUG("sbp2_login_device: login_orb not alloc'd!");
- return -EIO;
+ return(-EIO);
}
if (!exclusive_login) {
if (sbp2_query_logins(scsi_id)) {
SBP2_INFO("Device does not support any more concurrent logins");
- return -EIO;
+ return(-EIO);
}
}
@@ -1177,7 +1233,12 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id)
scsi_id->login_orb->lun_misc |= ORB_SET_RECONNECT(0); /* One second reconnect time */
scsi_id->login_orb->lun_misc |= ORB_SET_EXCLUSIVE(exclusive_login); /* Exclusive access to device */
scsi_id->login_orb->lun_misc |= ORB_SET_NOTIFY(1); /* Notify us of login complete */
- scsi_id->login_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_lun);
+ /* Set the lun if we were able to pull it from the device's unit directory */
+ if (scsi_id->sbp2_device_type_and_lun != SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) {
+ scsi_id->login_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun);
+ SBP2_DEBUG("sbp2_query_logins: set lun to %d",
+ ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun));
+ }
SBP2_DEBUG("sbp2_login_device: lun_misc initialized");
scsi_id->login_orb->passwd_resp_lengths =
@@ -1227,7 +1288,7 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id)
*/
if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 20*HZ)) {
SBP2_ERR("Error logging into SBP-2 device - login timed-out");
- return -EIO;
+ return(-EIO);
}
/*
@@ -1235,7 +1296,7 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id)
*/
if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma) {
SBP2_ERR("Error logging into SBP-2 device - login timed-out");
- return -EIO;
+ return(-EIO);
}
/*
@@ -1246,7 +1307,7 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id)
STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
SBP2_ERR("Error logging into SBP-2 device - login failed");
- return -EIO;
+ return(-EIO);
}
/*
@@ -1270,7 +1331,7 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id)
SBP2_INFO("Logged into SBP-2 device");
- return 0;
+ return(0);
}
@@ -1324,7 +1385,8 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id)
atomic_set(&scsi_id->sbp2_login_complete, 0);
error = hpsb_node_write(scsi_id->ne,
- scsi_id->sbp2_management_agent_addr, data, 8);
+ scsi_id->sbp2_management_agent_addr,
+ data, 8);
if (error)
return error;
@@ -1334,7 +1396,7 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id)
SBP2_INFO("Logged out of SBP-2 device");
- return 0;
+ return(0);
}
@@ -1394,7 +1456,8 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id)
atomic_set(&scsi_id->sbp2_login_complete, 0);
error = hpsb_node_write(scsi_id->ne,
- scsi_id->sbp2_management_agent_addr, data, 8);
+ scsi_id->sbp2_management_agent_addr,
+ data, 8);
if (error)
return error;
@@ -1403,7 +1466,7 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id)
*/
if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, HZ)) {
SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out");
- return -EIO;
+ return(-EIO);
}
/*
@@ -1411,7 +1474,7 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id)
*/
if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma) {
SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out");
- return -EIO;
+ return(-EIO);
}
/*
@@ -1422,12 +1485,12 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id)
STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
SBP2_ERR("Error reconnecting to SBP-2 device - reconnect failed");
- return -EIO;
+ return(-EIO);
}
HPSB_DEBUG("Reconnected to SBP-2 device");
- return 0;
+ return(0);
}
@@ -1450,9 +1513,10 @@ static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id)
SBP2_ERR("sbp2_set_busy_timeout error");
}
- return 0;
+ return(0);
}
+
/*
* This function is called to parse sbp2 device's config rom unit
* directory. Used to determine things like sbp2 management agent offset,
@@ -1465,7 +1529,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
struct csr1212_dentry *dentry;
u64 management_agent_addr;
u32 command_set_spec_id, command_set, unit_characteristics,
- firmware_revision, workarounds;
+ firmware_revision, workarounds;
int i;
SBP2_DEBUG("sbp2_parse_unit_directory");
@@ -1483,14 +1547,13 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
if (kv->key.type == CSR1212_KV_TYPE_CSR_OFFSET) {
/* Save off the management agent address */
management_agent_addr =
- CSR1212_REGISTER_SPACE_BASE +
- (kv->value.csr_offset << 2);
+ CSR1212_REGISTER_SPACE_BASE +
+ (kv->value.csr_offset << 2);
SBP2_DEBUG("sbp2_management_agent_addr = %x",
- (unsigned int)management_agent_addr);
+ (unsigned int) management_agent_addr);
} else if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) {
- scsi_id->sbp2_lun =
- ORB_SET_LUN(kv->value.immediate);
+ scsi_id->sbp2_device_type_and_lun = kv->value.immediate;
}
break;
@@ -1498,14 +1561,14 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
/* Command spec organization */
command_set_spec_id = kv->value.immediate;
SBP2_DEBUG("sbp2_command_set_spec_id = %x",
- (unsigned int)command_set_spec_id);
+ (unsigned int) command_set_spec_id);
break;
case SBP2_COMMAND_SET_KEY:
/* Command set used by sbp2 device */
command_set = kv->value.immediate;
SBP2_DEBUG("sbp2_command_set = %x",
- (unsigned int)command_set);
+ (unsigned int) command_set);
break;
case SBP2_UNIT_CHARACTERISTICS_KEY:
@@ -1515,7 +1578,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
*/
unit_characteristics = kv->value.immediate;
SBP2_DEBUG("sbp2_unit_characteristics = %x",
- (unsigned int)unit_characteristics);
+ (unsigned int) unit_characteristics);
break;
case SBP2_FIRMWARE_REVISION_KEY:
@@ -1523,10 +1586,9 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
firmware_revision = kv->value.immediate;
if (force_inquiry_hack)
SBP2_INFO("sbp2_firmware_revision = %x",
- (unsigned int)firmware_revision);
- else
- SBP2_DEBUG("sbp2_firmware_revision = %x",
- (unsigned int)firmware_revision);
+ (unsigned int) firmware_revision);
+ else SBP2_DEBUG("sbp2_firmware_revision = %x",
+ (unsigned int) firmware_revision);
break;
default:
@@ -1584,7 +1646,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
scsi_id->sbp2_firmware_revision = firmware_revision;
scsi_id->workarounds = workarounds;
if (ud->flags & UNIT_DIRECTORY_HAS_LUN)
- scsi_id->sbp2_lun = ORB_SET_LUN(ud->lun);
+ scsi_id->sbp2_device_type_and_lun = ud->lun;
}
}
@@ -1604,9 +1666,8 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id)
SBP2_DEBUG("sbp2_max_speed_and_size");
/* Initial setting comes from the hosts speed map */
- scsi_id->speed_code =
- hi->host->speed_map[NODEID_TO_NODE(hi->host->node_id) * 64 +
- NODEID_TO_NODE(scsi_id->ne->nodeid)];
+ scsi_id->speed_code = hi->host->speed_map[NODEID_TO_NODE(hi->host->node_id) * 64
+ + NODEID_TO_NODE(scsi_id->ne->nodeid)];
/* Bump down our speed if the user requested it */
if (scsi_id->speed_code > max_speed) {
@@ -1617,16 +1678,15 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id)
/* Payload size is the lesser of what our speed supports and what
* our host supports. */
- scsi_id->max_payload_size =
- min(sbp2_speedto_max_payload[scsi_id->speed_code],
- (u8) (hi->host->csr.max_rec - 1));
+ scsi_id->max_payload_size = min(sbp2_speedto_max_payload[scsi_id->speed_code],
+ (u8)(hi->host->csr.max_rec - 1));
HPSB_DEBUG("Node " NODE_BUS_FMT ": Max speed [%s] - Max payload [%u]",
NODE_BUS_ARGS(hi->host, scsi_id->ne->nodeid),
hpsb_speedto_str[scsi_id->speed_code],
- 1 << ((u32) scsi_id->max_payload_size + 2));
+ 1 << ((u32)scsi_id->max_payload_size + 2));
- return 0;
+ return(0);
}
/*
@@ -1661,187 +1721,30 @@ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait)
*/
scsi_id->last_orb = NULL;
- return 0;
-}
-
-static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
- struct sbp2scsi_host_info *hi,
- struct sbp2_command_info *command,
- unsigned int scsi_use_sg,
- struct scatterlist *sgpnt,
- u32 orb_direction,
- enum dma_data_direction dma_dir)
-{
- command->dma_dir = dma_dir;
- orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
- orb->misc |= ORB_SET_DIRECTION(orb_direction);
-
- /* Special case if only one element (and less than 64KB in size) */
- if ((scsi_use_sg == 1) &&
- (sgpnt[0].length <= SBP2_MAX_SG_ELEMENT_LENGTH)) {
-
- SBP2_DEBUG("Only one s/g element");
- command->dma_size = sgpnt[0].length;
- command->dma_type = CMD_DMA_PAGE;
- command->cmd_dma = pci_map_page(hi->host->pdev,
- sgpnt[0].page,
- sgpnt[0].offset,
- command->dma_size,
- command->dma_dir);
- SBP2_DMA_ALLOC("single page scatter element");
-
- orb->data_descriptor_lo = command->cmd_dma;
- orb->misc |= ORB_SET_DATA_SIZE(command->dma_size);
-
- } else {
- struct sbp2_unrestricted_page_table *sg_element =
- &command->scatter_gather_element[0];
- u32 sg_count, sg_len;
- dma_addr_t sg_addr;
- int i, count = pci_map_sg(hi->host->pdev, sgpnt, scsi_use_sg,
- dma_dir);
-
- SBP2_DMA_ALLOC("scatter list");
-
- command->dma_size = scsi_use_sg;
- command->sge_buffer = sgpnt;
-
- /* use page tables (s/g) */
- orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
- orb->data_descriptor_lo = command->sge_dma;
-
- /*
- * Loop through and fill out our sbp-2 page tables
- * (and split up anything too large)
- */
- for (i = 0, sg_count = 0 ; i < count; i++, sgpnt++) {
- sg_len = sg_dma_len(sgpnt);
- sg_addr = sg_dma_address(sgpnt);
- while (sg_len) {
- sg_element[sg_count].segment_base_lo = sg_addr;
- if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
- sg_element[sg_count].length_segment_base_hi =
- PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH);
- sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH;
- sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH;
- } else {
- sg_element[sg_count].length_segment_base_hi =
- PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len);
- sg_len = 0;
- }
- sg_count++;
- }
- }
-
- /* Number of page table (s/g) elements */
- orb->misc |= ORB_SET_DATA_SIZE(sg_count);
-
- sbp2util_packet_dump(sg_element,
- (sizeof(struct sbp2_unrestricted_page_table)) * sg_count,
- "sbp2 s/g list", command->sge_dma);
-
- /* Byte swap page tables if necessary */
- sbp2util_cpu_to_be32_buffer(sg_element,
- (sizeof(struct sbp2_unrestricted_page_table)) *
- sg_count);
- }
-}
-
-static void sbp2_prep_command_orb_no_sg(struct sbp2_command_orb *orb,
- struct sbp2scsi_host_info *hi,
- struct sbp2_command_info *command,
- struct scatterlist *sgpnt,
- u32 orb_direction,
- unsigned int scsi_request_bufflen,
- void *scsi_request_buffer,
- enum dma_data_direction dma_dir)
-{
- command->dma_dir = dma_dir;
- command->dma_size = scsi_request_bufflen;
- command->dma_type = CMD_DMA_SINGLE;
- command->cmd_dma = pci_map_single(hi->host->pdev, scsi_request_buffer,
- command->dma_size, command->dma_dir);
- orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
- orb->misc |= ORB_SET_DIRECTION(orb_direction);
-
- SBP2_DMA_ALLOC("single bulk");
-
- /*
- * Handle case where we get a command w/o s/g enabled (but
- * check for transfers larger than 64K)
- */
- if (scsi_request_bufflen <= SBP2_MAX_SG_ELEMENT_LENGTH) {
-
- orb->data_descriptor_lo = command->cmd_dma;
- orb->misc |= ORB_SET_DATA_SIZE(scsi_request_bufflen);
-
- } else {
- struct sbp2_unrestricted_page_table *sg_element =
- &command->scatter_gather_element[0];
- u32 sg_count, sg_len;
- dma_addr_t sg_addr;
-
- /*
- * Need to turn this into page tables, since the
- * buffer is too large.
- */
- orb->data_descriptor_lo = command->sge_dma;
-
- /* Use page tables (s/g) */
- orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
-
- /*
- * fill out our sbp-2 page tables (and split up
- * the large buffer)
- */
- sg_count = 0;
- sg_len = scsi_request_bufflen;
- sg_addr = command->cmd_dma;
- while (sg_len) {
- sg_element[sg_count].segment_base_lo = sg_addr;
- if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
- sg_element[sg_count].length_segment_base_hi =
- PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH);
- sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH;
- sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH;
- } else {
- sg_element[sg_count].length_segment_base_hi =
- PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len);
- sg_len = 0;
- }
- sg_count++;
- }
-
- /* Number of page table (s/g) elements */
- orb->misc |= ORB_SET_DATA_SIZE(sg_count);
-
- sbp2util_packet_dump(sg_element,
- (sizeof(struct sbp2_unrestricted_page_table)) * sg_count,
- "sbp2 s/g list", command->sge_dma);
-
- /* Byte swap page tables if necessary */
- sbp2util_cpu_to_be32_buffer(sg_element,
- (sizeof(struct sbp2_unrestricted_page_table)) *
- sg_count);
- }
+ return(0);
}
/*
* This function is called to create the actual command orb and s/g list
* out of the scsi command itself.
*/
-static void sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id,
- struct sbp2_command_info *command,
- unchar *scsi_cmd,
- unsigned int scsi_use_sg,
- unsigned int scsi_request_bufflen,
- void *scsi_request_buffer,
- enum dma_data_direction dma_dir)
+static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id,
+ struct sbp2_command_info *command,
+ unchar *scsi_cmd,
+ unsigned int scsi_use_sg,
+ unsigned int scsi_request_bufflen,
+ void *scsi_request_buffer,
+ enum dma_data_direction dma_dir)
+
{
struct sbp2scsi_host_info *hi = scsi_id->hi;
- struct scatterlist *sgpnt = (struct scatterlist *)scsi_request_buffer;
+ struct scatterlist *sgpnt = (struct scatterlist *) scsi_request_buffer;
struct sbp2_command_orb *command_orb = &command->command_orb;
- u32 orb_direction;
+ struct sbp2_unrestricted_page_table *scatter_gather_element =
+ &command->scatter_gather_element[0];
+ u32 sg_count, sg_len, orb_direction;
+ dma_addr_t sg_addr;
+ int i;
/*
* Set-up our command ORB..
@@ -1855,42 +1758,222 @@ static void sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id,
command_orb->next_ORB_lo = 0x0;
command_orb->misc = ORB_SET_MAX_PAYLOAD(scsi_id->max_payload_size);
command_orb->misc |= ORB_SET_SPEED(scsi_id->speed_code);
- command_orb->misc |= ORB_SET_NOTIFY(1); /* Notify us when complete */
+ command_orb->misc |= ORB_SET_NOTIFY(1); /* Notify us when complete */
- if (dma_dir == DMA_NONE)
- orb_direction = ORB_DIRECTION_NO_DATA_TRANSFER;
- else if (dma_dir == DMA_TO_DEVICE && scsi_request_bufflen)
- orb_direction = ORB_DIRECTION_WRITE_TO_MEDIA;
- else if (dma_dir == DMA_FROM_DEVICE && scsi_request_bufflen)
- orb_direction = ORB_DIRECTION_READ_FROM_MEDIA;
- else {
- SBP2_WARN("Falling back to DMA_NONE");
- orb_direction = ORB_DIRECTION_NO_DATA_TRANSFER;
+ /*
+ * Get the direction of the transfer. If the direction is unknown, then use our
+ * goofy table as a back-up.
+ */
+ switch (dma_dir) {
+ case DMA_NONE:
+ orb_direction = ORB_DIRECTION_NO_DATA_TRANSFER;
+ break;
+ case DMA_TO_DEVICE:
+ orb_direction = ORB_DIRECTION_WRITE_TO_MEDIA;
+ break;
+ case DMA_FROM_DEVICE:
+ orb_direction = ORB_DIRECTION_READ_FROM_MEDIA;
+ break;
+ case DMA_BIDIRECTIONAL:
+ default:
+ SBP2_ERR("SCSI data transfer direction not specified. "
+ "Update the SBP2 direction table in sbp2.h if "
+ "necessary for your application");
+ __scsi_print_command(scsi_cmd);
+ orb_direction = sbp2scsi_direction_table[*scsi_cmd];
+ break;
}
- /* Set-up our pagetable stuff */
+ /*
+ * Set-up our pagetable stuff... unfortunately, this has become
+ * messier than I'd like. Need to clean this up a bit. ;-)
+ */
if (orb_direction == ORB_DIRECTION_NO_DATA_TRANSFER) {
+
SBP2_DEBUG("No data transfer");
+
+ /*
+ * Handle no data transfer
+ */
command_orb->data_descriptor_hi = 0x0;
command_orb->data_descriptor_lo = 0x0;
command_orb->misc |= ORB_SET_DIRECTION(1);
+
} else if (scsi_use_sg) {
+
SBP2_DEBUG("Use scatter/gather");
- sbp2_prep_command_orb_sg(command_orb, hi, command, scsi_use_sg,
- sgpnt, orb_direction, dma_dir);
+
+ /*
+ * Special case if only one element (and less than 64KB in size)
+ */
+ if ((scsi_use_sg == 1) && (sgpnt[0].length <= SBP2_MAX_SG_ELEMENT_LENGTH)) {
+
+ SBP2_DEBUG("Only one s/g element");
+ command->dma_dir = dma_dir;
+ command->dma_size = sgpnt[0].length;
+ command->dma_type = CMD_DMA_PAGE;
+ command->cmd_dma = pci_map_page(hi->host->pdev,
+ sgpnt[0].page,
+ sgpnt[0].offset,
+ command->dma_size,
+ command->dma_dir);
+ SBP2_DMA_ALLOC("single page scatter element");
+
+ command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
+ command_orb->data_descriptor_lo = command->cmd_dma;
+ command_orb->misc |= ORB_SET_DATA_SIZE(command->dma_size);
+ command_orb->misc |= ORB_SET_DIRECTION(orb_direction);
+
+ } else {
+ int count = pci_map_sg(hi->host->pdev, sgpnt, scsi_use_sg, dma_dir);
+ SBP2_DMA_ALLOC("scatter list");
+
+ command->dma_size = scsi_use_sg;
+ command->dma_dir = dma_dir;
+ command->sge_buffer = sgpnt;
+
+ /* use page tables (s/g) */
+ command_orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
+ command_orb->misc |= ORB_SET_DIRECTION(orb_direction);
+ command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
+ command_orb->data_descriptor_lo = command->sge_dma;
+
+ /*
+ * Loop through and fill out our sbp-2 page tables
+ * (and split up anything too large)
+ */
+ for (i = 0, sg_count = 0 ; i < count; i++, sgpnt++) {
+ sg_len = sg_dma_len(sgpnt);
+ sg_addr = sg_dma_address(sgpnt);
+ while (sg_len) {
+ scatter_gather_element[sg_count].segment_base_lo = sg_addr;
+ if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
+ scatter_gather_element[sg_count].length_segment_base_hi =
+ PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH);
+ sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH;
+ sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH;
+ } else {
+ scatter_gather_element[sg_count].length_segment_base_hi =
+ PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len);
+ sg_len = 0;
+ }
+ sg_count++;
+ }
+ }
+
+ /* Number of page table (s/g) elements */
+ command_orb->misc |= ORB_SET_DATA_SIZE(sg_count);
+
+ sbp2util_packet_dump(scatter_gather_element,
+ (sizeof(struct sbp2_unrestricted_page_table)) * sg_count,
+ "sbp2 s/g list", command->sge_dma);
+
+ /*
+ * Byte swap page tables if necessary
+ */
+ sbp2util_cpu_to_be32_buffer(scatter_gather_element,
+ (sizeof(struct sbp2_unrestricted_page_table)) *
+ sg_count);
+
+ }
+
} else {
+
SBP2_DEBUG("No scatter/gather");
- sbp2_prep_command_orb_no_sg(command_orb, hi, command, sgpnt,
- orb_direction, scsi_request_bufflen,
- scsi_request_buffer, dma_dir);
+
+ command->dma_dir = dma_dir;
+ command->dma_size = scsi_request_bufflen;
+ command->dma_type = CMD_DMA_SINGLE;
+ command->cmd_dma = pci_map_single (hi->host->pdev, scsi_request_buffer,
+ command->dma_size,
+ command->dma_dir);
+ SBP2_DMA_ALLOC("single bulk");
+
+ /*
+ * Handle case where we get a command w/o s/g enabled (but
+ * check for transfers larger than 64K)
+ */
+ if (scsi_request_bufflen <= SBP2_MAX_SG_ELEMENT_LENGTH) {
+
+ command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
+ command_orb->data_descriptor_lo = command->cmd_dma;
+ command_orb->misc |= ORB_SET_DATA_SIZE(scsi_request_bufflen);
+ command_orb->misc |= ORB_SET_DIRECTION(orb_direction);
+
+ /*
+ * Sanity, in case our direction table is not
+ * up-to-date
+ */
+ if (!scsi_request_bufflen) {
+ command_orb->data_descriptor_hi = 0x0;
+ command_orb->data_descriptor_lo = 0x0;
+ command_orb->misc |= ORB_SET_DIRECTION(1);
+ }
+
+ } else {
+ /*
+ * Need to turn this into page tables, since the
+ * buffer is too large.
+ */
+ command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
+ command_orb->data_descriptor_lo = command->sge_dma;
+
+ /* Use page tables (s/g) */
+ command_orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
+ command_orb->misc |= ORB_SET_DIRECTION(orb_direction);
+
+ /*
+ * fill out our sbp-2 page tables (and split up
+ * the large buffer)
+ */
+ sg_count = 0;
+ sg_len = scsi_request_bufflen;
+ sg_addr = command->cmd_dma;
+ while (sg_len) {
+ scatter_gather_element[sg_count].segment_base_lo = sg_addr;
+ if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
+ scatter_gather_element[sg_count].length_segment_base_hi =
+ PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH);
+ sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH;
+ sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH;
+ } else {
+ scatter_gather_element[sg_count].length_segment_base_hi =
+ PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len);
+ sg_len = 0;
+ }
+ sg_count++;
+ }
+
+ /* Number of page table (s/g) elements */
+ command_orb->misc |= ORB_SET_DATA_SIZE(sg_count);
+
+ sbp2util_packet_dump(scatter_gather_element,
+ (sizeof(struct sbp2_unrestricted_page_table)) * sg_count,
+ "sbp2 s/g list", command->sge_dma);
+
+ /*
+ * Byte swap page tables if necessary
+ */
+ sbp2util_cpu_to_be32_buffer(scatter_gather_element,
+ (sizeof(struct sbp2_unrestricted_page_table)) *
+ sg_count);
+
+ }
+
}
- /* Byte swap command ORB if necessary */
+ /*
+ * Byte swap command ORB if necessary
+ */
sbp2util_cpu_to_be32_buffer(command_orb, sizeof(struct sbp2_command_orb));
- /* Put our scsi command in the command ORB */
+ /*
+ * Put our scsi command in the command ORB
+ */
memset(command_orb->cdb, 0, 12);
memcpy(command_orb->cdb, scsi_cmd, COMMAND_SIZE(*scsi_cmd));
+
+ return(0);
}
/*
@@ -1906,7 +1989,7 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
outstanding_orb_incr;
SBP2_ORB_DEBUG("sending command orb %p, total orbs = %x",
- command_orb, global_outstanding_command_orbs);
+ command_orb, global_outstanding_command_orbs);
pci_dma_sync_single_for_device(hi->host->pdev, command->command_orb_dma,
sizeof(struct sbp2_command_orb),
@@ -1951,11 +2034,10 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
* both by the sbp2 device and us.
*/
scsi_id->last_orb->next_ORB_lo =
- cpu_to_be32(command->command_orb_dma);
+ cpu_to_be32(command->command_orb_dma);
/* Tells hardware that this pointer is valid */
scsi_id->last_orb->next_ORB_hi = 0x0;
- pci_dma_sync_single_for_device(hi->host->pdev,
- scsi_id->last_orb_dma,
+ pci_dma_sync_single_for_device(hi->host->pdev, scsi_id->last_orb_dma,
sizeof(struct sbp2_command_orb),
PCI_DMA_BIDIRECTIONAL);
@@ -1969,14 +2051,14 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
if (sbp2util_node_write_no_wait(ne, addr, &data, 4) < 0) {
SBP2_ERR("sbp2util_node_write_no_wait failed");
- return -EIO;
+ return(-EIO);
}
scsi_id->last_orb = command_orb;
scsi_id->last_orb_dma = command->command_orb_dma;
}
- return 0;
+ return(0);
}
/*
@@ -2003,7 +2085,7 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
*/
command = sbp2util_allocate_command_orb(scsi_id, SCpnt, done);
if (!command) {
- return -EIO;
+ return(-EIO);
}
/*
@@ -2024,6 +2106,11 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
sbp2_create_command_orb(scsi_id, command, cmd, SCpnt->use_sg,
request_bufflen, SCpnt->request_buffer,
SCpnt->sc_data_direction);
+ /*
+ * Update our cdb if necessary (to handle sbp2 RBC command set
+ * differences). This is where the command set hacks go! =)
+ */
+ sbp2_check_sbp2_command(scsi_id, command->command_orb.cdb);
sbp2util_packet_dump(&command->command_orb, sizeof(struct sbp2_command_orb),
"sbp2 command orb", command->command_orb_dma);
@@ -2038,7 +2125,112 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
*/
sbp2_link_orb_command(scsi_id, command);
- return 0;
+ return(0);
+}
+
+
+/*
+ * This function deals with command set differences between Linux scsi
+ * command set and sbp2 RBC command set.
+ */
+static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd)
+{
+ unchar new_cmd[16];
+ u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
+
+ SBP2_DEBUG("sbp2_check_sbp2_command");
+
+ switch (*cmd) {
+
+ case READ_6:
+
+ if (sbp2_command_conversion_device_type(device_type)) {
+
+ SBP2_DEBUG("Convert READ_6 to READ_10");
+
+ /*
+ * Need to turn read_6 into read_10
+ */
+ new_cmd[0] = 0x28;
+ new_cmd[1] = (cmd[1] & 0xe0);
+ new_cmd[2] = 0x0;
+ new_cmd[3] = (cmd[1] & 0x1f);
+ new_cmd[4] = cmd[2];
+ new_cmd[5] = cmd[3];
+ new_cmd[6] = 0x0;
+ new_cmd[7] = 0x0;
+ new_cmd[8] = cmd[4];
+ new_cmd[9] = cmd[5];
+
+ memcpy(cmd, new_cmd, 10);
+
+ }
+
+ break;
+
+ case WRITE_6:
+
+ if (sbp2_command_conversion_device_type(device_type)) {
+
+ SBP2_DEBUG("Convert WRITE_6 to WRITE_10");
+
+ /*
+ * Need to turn write_6 into write_10
+ */
+ new_cmd[0] = 0x2a;
+ new_cmd[1] = (cmd[1] & 0xe0);
+ new_cmd[2] = 0x0;
+ new_cmd[3] = (cmd[1] & 0x1f);
+ new_cmd[4] = cmd[2];
+ new_cmd[5] = cmd[3];
+ new_cmd[6] = 0x0;
+ new_cmd[7] = 0x0;
+ new_cmd[8] = cmd[4];
+ new_cmd[9] = cmd[5];
+
+ memcpy(cmd, new_cmd, 10);
+
+ }
+
+ break;
+
+ case MODE_SENSE:
+
+ if (sbp2_command_conversion_device_type(device_type)) {
+
+ SBP2_DEBUG("Convert MODE_SENSE_6 to MODE_SENSE_10");
+
+ /*
+ * Need to turn mode_sense_6 into mode_sense_10
+ */
+ new_cmd[0] = 0x5a;
+ new_cmd[1] = cmd[1];
+ new_cmd[2] = cmd[2];
+ new_cmd[3] = 0x0;
+ new_cmd[4] = 0x0;
+ new_cmd[5] = 0x0;
+ new_cmd[6] = 0x0;
+ new_cmd[7] = 0x0;
+ new_cmd[8] = cmd[4];
+ new_cmd[9] = cmd[5];
+
+ memcpy(cmd, new_cmd, 10);
+
+ }
+
+ break;
+
+ case MODE_SELECT:
+
+ /*
+ * TODO. Probably need to change mode select to 10 byte version
+ */
+
+ default:
+ break;
+ }
+
+ return;
}
/*
@@ -2068,40 +2260,80 @@ static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense
sense_data[14] = sbp2_status[20];
sense_data[15] = sbp2_status[21];
- return sbp2_status[8] & 0x3f; /* return scsi status */
+ return(sbp2_status[8] & 0x3f); /* return scsi status */
}
/*
* This function is called after a command is completed, in order to do any necessary SBP-2
* response data translations for the SCSI stack
*/
-static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
+static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
struct scsi_cmnd *SCpnt)
{
u8 *scsi_buf = SCpnt->request_buffer;
+ u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
SBP2_DEBUG("sbp2_check_sbp2_response");
switch (SCpnt->cmnd[0]) {
- case INQUIRY:
- /*
- * Make sure data length is ok. Minimum length is 36 bytes
- */
- if (scsi_buf[4] == 0) {
- scsi_buf[4] = 36 - 5;
- }
+ case INQUIRY:
- /*
- * Fix ansi revision and response data format
- */
- scsi_buf[2] |= 2;
- scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2;
+ /*
+ * If scsi_id->sbp2_device_type_and_lun is uninitialized, then fill
+ * this information in from the inquiry response data. Lun is set to zero.
+ */
+ if (scsi_id->sbp2_device_type_and_lun == SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) {
+ SBP2_DEBUG("Creating sbp2_device_type_and_lun from scsi inquiry data");
+ scsi_id->sbp2_device_type_and_lun = (scsi_buf[0] & 0x1f) << 16;
+ }
+
+ /*
+ * Make sure data length is ok. Minimum length is 36 bytes
+ */
+ if (scsi_buf[4] == 0) {
+ scsi_buf[4] = 36 - 5;
+ }
+
+ /*
+ * Check for Simple Direct Access Device and change it to TYPE_DISK
+ */
+ if ((scsi_buf[0] & 0x1f) == TYPE_RBC) {
+ SBP2_DEBUG("Changing TYPE_RBC to TYPE_DISK");
+ scsi_buf[0] &= 0xe0;
+ }
+
+ /*
+ * Fix ansi revision and response data format
+ */
+ scsi_buf[2] |= 2;
+ scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2;
+
+ break;
+
+ case MODE_SENSE:
+
+ if (sbp2_command_conversion_device_type(device_type)) {
+
+ SBP2_DEBUG("Modify mode sense response (10 byte version)");
+
+ scsi_buf[0] = scsi_buf[1]; /* Mode data length */
+ scsi_buf[1] = scsi_buf[2]; /* Medium type */
+ scsi_buf[2] = scsi_buf[3]; /* Device specific parameter */
+ scsi_buf[3] = scsi_buf[7]; /* Block descriptor length */
+ memcpy(scsi_buf + 4, scsi_buf + 8, scsi_buf[0]);
+ }
+
+ break;
- break;
+ case MODE_SELECT:
- default:
- break;
+ /*
+ * TODO. Probably need to change mode select to 10 byte version
+ */
+
+ default:
+ break;
}
return;
}
@@ -2126,14 +2358,14 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
if (!host) {
SBP2_ERR("host is NULL - this is bad!");
- return RCODE_ADDRESS_ERROR;
+ return(RCODE_ADDRESS_ERROR);
}
hi = hpsb_get_hostinfo(&sbp2_highlevel, host);
if (!hi) {
SBP2_ERR("host info is NULL - this is bad!");
- return RCODE_ADDRESS_ERROR;
+ return(RCODE_ADDRESS_ERROR);
}
/*
@@ -2150,7 +2382,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
if (!scsi_id) {
SBP2_ERR("scsi_id is NULL - device is gone?");
- return RCODE_ADDRESS_ERROR;
+ return(RCODE_ADDRESS_ERROR);
}
/*
@@ -2248,9 +2480,10 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
SBP2_ORB_DEBUG("command orb completed");
}
- return RCODE_COMPLETE;
+ return(RCODE_COMPLETE);
}
+
/**************************************
* SCSI interface related section
**************************************/
@@ -2307,16 +2540,6 @@ static int sbp2scsi_queuecommand(struct scsi_cmnd *SCpnt,
goto done;
}
- /*
- * Bidirectional commands are not yet implemented,
- * and unknown transfer direction not handled.
- */
- if (SCpnt->sc_data_direction == DMA_BIDIRECTIONAL) {
- SBP2_ERR("Cannot handle DMA_BIDIRECTIONAL - rejecting command");
- result = DID_ERROR << 16;
- goto done;
- }
-
/*
* Try and send our SCSI command
*/
@@ -2393,56 +2616,55 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
* complete the command, just let it get retried at the end of the
* bus reset.
*/
- if (!hpsb_node_entry_valid(scsi_id->ne)
- && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
+ if (!hpsb_node_entry_valid(scsi_id->ne) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
SBP2_ERR("Bus reset in progress - retry command later");
return;
}
-
+
/*
* Switch on scsi status
*/
switch (scsi_status) {
- case SBP2_SCSI_STATUS_GOOD:
- SCpnt->result = DID_OK;
- break;
+ case SBP2_SCSI_STATUS_GOOD:
+ SCpnt->result = DID_OK;
+ break;
- case SBP2_SCSI_STATUS_BUSY:
- SBP2_ERR("SBP2_SCSI_STATUS_BUSY");
- SCpnt->result = DID_BUS_BUSY << 16;
- break;
+ case SBP2_SCSI_STATUS_BUSY:
+ SBP2_ERR("SBP2_SCSI_STATUS_BUSY");
+ SCpnt->result = DID_BUS_BUSY << 16;
+ break;
- case SBP2_SCSI_STATUS_CHECK_CONDITION:
- SBP2_DEBUG("SBP2_SCSI_STATUS_CHECK_CONDITION");
- SCpnt->result = CHECK_CONDITION << 1;
+ case SBP2_SCSI_STATUS_CHECK_CONDITION:
+ SBP2_DEBUG("SBP2_SCSI_STATUS_CHECK_CONDITION");
+ SCpnt->result = CHECK_CONDITION << 1;
- /*
- * Debug stuff
- */
+ /*
+ * Debug stuff
+ */
#if CONFIG_IEEE1394_SBP2_DEBUG >= 1
- scsi_print_command(SCpnt);
- scsi_print_sense("bh", SCpnt);
+ scsi_print_command(SCpnt);
+ scsi_print_sense("bh", SCpnt);
#endif
- break;
+ break;
- case SBP2_SCSI_STATUS_SELECTION_TIMEOUT:
- SBP2_ERR("SBP2_SCSI_STATUS_SELECTION_TIMEOUT");
- SCpnt->result = DID_NO_CONNECT << 16;
- scsi_print_command(SCpnt);
- break;
+ case SBP2_SCSI_STATUS_SELECTION_TIMEOUT:
+ SBP2_ERR("SBP2_SCSI_STATUS_SELECTION_TIMEOUT");
+ SCpnt->result = DID_NO_CONNECT << 16;
+ scsi_print_command(SCpnt);
+ break;
- case SBP2_SCSI_STATUS_CONDITION_MET:
- case SBP2_SCSI_STATUS_RESERVATION_CONFLICT:
- case SBP2_SCSI_STATUS_COMMAND_TERMINATED:
- SBP2_ERR("Bad SCSI status = %x", scsi_status);
- SCpnt->result = DID_ERROR << 16;
- scsi_print_command(SCpnt);
- break;
+ case SBP2_SCSI_STATUS_CONDITION_MET:
+ case SBP2_SCSI_STATUS_RESERVATION_CONFLICT:
+ case SBP2_SCSI_STATUS_COMMAND_TERMINATED:
+ SBP2_ERR("Bad SCSI status = %x", scsi_status);
+ SCpnt->result = DID_ERROR << 16;
+ scsi_print_command(SCpnt);
+ break;
- default:
- SBP2_ERR("Unsupported SCSI status = %x", scsi_status);
- SCpnt->result = DID_ERROR << 16;
+ default:
+ SBP2_ERR("Unsupported SCSI status = %x", scsi_status);
+ SCpnt->result = DID_ERROR << 16;
}
/*
@@ -2456,8 +2678,7 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
* If a bus reset is in progress and there was an error, complete
* the command as busy so that it will get retried.
*/
- if (!hpsb_node_entry_valid(scsi_id->ne)
- && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
+ if (!hpsb_node_entry_valid(scsi_id->ne) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
SBP2_ERR("Completing command with busy (bus reset)");
SCpnt->result = DID_BUS_BUSY << 16;
}
@@ -2478,29 +2699,31 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
/*
* Tell scsi stack that we're done with this command
*/
- done(SCpnt);
+ done (SCpnt);
}
+
static int sbp2scsi_slave_alloc(struct scsi_device *sdev)
{
((struct scsi_id_instance_data *)sdev->host->hostdata[0])->sdev = sdev;
return 0;
}
+
static int sbp2scsi_slave_configure(struct scsi_device *sdev)
{
blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
- sdev->use_10_for_rw = 1;
- sdev->use_10_for_ms = 1;
return 0;
}
+
static void sbp2scsi_slave_destroy(struct scsi_device *sdev)
{
((struct scsi_id_instance_data *)sdev->host->hostdata[0])->sdev = NULL;
return;
}
+
/*
* Called by scsi stack when something has really gone wrong. Usually
* called when a command has timed-out for some reason.
@@ -2546,7 +2769,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY);
}
- return SUCCESS;
+ return(SUCCESS);
}
/*
@@ -2556,20 +2779,28 @@ static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
{
struct scsi_id_instance_data *scsi_id =
(struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0];
+ unsigned long flags;
SBP2_ERR("reset requested");
+ spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
+
if (sbp2util_node_is_available(scsi_id)) {
SBP2_ERR("Generating sbp2 fetch agent reset");
sbp2_agent_reset(scsi_id, 0);
}
+ spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
+
return SUCCESS;
}
-static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static const char *sbp2scsi_info (struct Scsi_Host *host)
+{
+ return "SCSI emulation for IEEE-1394 SBP-2 Devices";
+}
+
+static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct scsi_device *sdev;
struct scsi_id_instance_data *scsi_id;
@@ -2581,7 +2812,10 @@ static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev,
if (!(scsi_id = (struct scsi_id_instance_data *)sdev->host->hostdata[0]))
return 0;
- lun = ORB_SET_LUN(scsi_id->sbp2_lun);
+ if (scsi_id->sbp2_device_type_and_lun == SBP2_DEVICE_TYPE_LUN_UNINITIALIZED)
+ lun = 0;
+ else
+ lun = ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun);
return sprintf(buf, "%016Lx:%d:%d\n", (unsigned long long)scsi_id->ne->guid,
scsi_id->ud->id, lun);
@@ -2603,9 +2837,12 @@ static struct scsi_host_template scsi_driver_template = {
.module = THIS_MODULE,
.name = "SBP-2 IEEE-1394",
.proc_name = SBP2_DEVICE_NAME,
+ .info = sbp2scsi_info,
.queuecommand = sbp2scsi_queuecommand,
.eh_abort_handler = sbp2scsi_abort,
.eh_device_reset_handler = sbp2scsi_reset,
+ .eh_bus_reset_handler = sbp2scsi_reset,
+ .eh_host_reset_handler = sbp2scsi_reset,
.slave_alloc = sbp2scsi_slave_alloc,
.slave_configure = sbp2scsi_slave_configure,
.slave_destroy = sbp2scsi_slave_destroy,
@@ -2624,6 +2861,8 @@ static int sbp2_module_init(void)
SBP2_DEBUG("sbp2_module_init");
+ printk(KERN_INFO "sbp2: %s\n", version);
+
/* Module load debug option to force one command at a time (serializing I/O) */
if (serialize_io) {
SBP2_INFO("Driver forced to serialize I/O (serialize_io=1)");
@@ -2635,6 +2874,7 @@ static int sbp2_module_init(void)
/* Set max sectors (module load option). Default is 255 sectors. */
scsi_driver_template.max_sectors = max_sectors;
+
/* Register our high level driver with 1394 stack */
hpsb_register_highlevel(&sbp2_highlevel);
diff --git a/trunk/drivers/ieee1394/sbp2.h b/trunk/drivers/ieee1394/sbp2.h
index 900ea1d25e71..cd425be74841 100644
--- a/trunk/drivers/ieee1394/sbp2.h
+++ b/trunk/drivers/ieee1394/sbp2.h
@@ -119,8 +119,8 @@ struct sbp2_query_logins_response {
struct sbp2_reconnect_orb {
u32 reserved1;
u32 reserved2;
- u32 reserved3;
- u32 reserved4;
+ u32 reserved3;
+ u32 reserved4;
u32 login_ID_misc;
u32 reserved5;
u32 status_FIFO_hi;
@@ -130,8 +130,8 @@ struct sbp2_reconnect_orb {
struct sbp2_logout_orb {
u32 reserved1;
u32 reserved2;
- u32 reserved3;
- u32 reserved4;
+ u32 reserved3;
+ u32 reserved4;
u32 login_ID_misc;
u32 reserved5;
u32 status_FIFO_hi;
@@ -188,7 +188,7 @@ struct sbp2_unrestricted_page_table {
struct sbp2_status_block {
u32 ORB_offset_hi_misc;
u32 ORB_offset_lo;
- u8 command_set_dependent[24];
+ u8 command_set_dependent[24];
};
/*
@@ -211,7 +211,7 @@ struct sbp2_status_block {
* specified for write posting, where the ohci controller will
* automatically send an ack_complete when the status is written by the
* sbp2 device... saving a split transaction. =)
- */
+ */
#define SBP2_STATUS_FIFO_ADDRESS 0xfffe00000000ULL
#define SBP2_STATUS_FIFO_ADDRESS_HI 0xfffe
#define SBP2_STATUS_FIFO_ADDRESS_LO 0x0
@@ -229,6 +229,9 @@ struct sbp2_status_block {
#define SBP2_DEVICE_TYPE_AND_LUN_KEY 0x14
#define SBP2_FIRMWARE_REVISION_KEY 0x3c
+#define SBP2_DEVICE_TYPE(q) (((q) >> 16) & 0x1f)
+#define SBP2_DEVICE_LUN(q) ((q) & 0xffff)
+
#define SBP2_AGENT_STATE_OFFSET 0x00ULL
#define SBP2_AGENT_RESET_OFFSET 0x04ULL
#define SBP2_ORB_POINTER_OFFSET 0x08ULL
@@ -253,6 +256,8 @@ struct sbp2_status_block {
*/
#define SBP2_128KB_BROKEN_FIRMWARE 0xa0b800
+#define SBP2_DEVICE_TYPE_LUN_UNINITIALIZED 0xffffffff
+
/*
* SCSI specific stuff
*/
@@ -260,7 +265,45 @@ struct sbp2_status_block {
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
#define SBP2_MAX_UDS_PER_NODE 16 /* Maximum scsi devices per node */
#define SBP2_MAX_SECTORS 255 /* Max sectors supported */
-#define SBP2_MAX_CMDS 8 /* This should be safe */
+
+/*
+ * SCSI direction table...
+ * (now used as a back-up in case the direction passed down from above is "unknown")
+ *
+ * DIN = IN data direction
+ * DOU = OUT data direction
+ * DNO = No data transfer
+ * DUN = Unknown data direction
+ *
+ * Opcode 0xec (Teac specific "opc execute") possibly should be DNO,
+ * but we'll change it when somebody reports a problem with this.
+ */
+#define DIN ORB_DIRECTION_READ_FROM_MEDIA
+#define DOU ORB_DIRECTION_WRITE_TO_MEDIA
+#define DNO ORB_DIRECTION_NO_DATA_TRANSFER
+#define DUN DIN
+
+static unchar sbp2scsi_direction_table[0x100] = {
+ DNO,DNO,DIN,DIN,DOU,DIN,DIN,DOU,DIN,DUN,DOU,DOU,DUN,DUN,DUN,DIN,
+ DNO,DIN,DIN,DOU,DIN,DOU,DNO,DNO,DOU,DNO,DIN,DNO,DIN,DOU,DNO,DUN,
+ DIN,DUN,DIN,DIN,DOU,DIN,DUN,DUN,DIN,DIN,DOU,DNO,DUN,DIN,DOU,DOU,
+ DOU,DOU,DOU,DNO,DIN,DNO,DNO,DIN,DOU,DOU,DOU,DOU,DIN,DOU,DIN,DOU,
+ DOU,DOU,DIN,DIN,DIN,DNO,DIN,DNO,DNO,DNO,DUN,DNO,DOU,DIN,DNO,DUN,
+ DUN,DIN,DIN,DNO,DNO,DOU,DUN,DUN,DNO,DIN,DIN,DNO,DIN,DOU,DUN,DUN,
+ DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
+ DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
+ DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
+ DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
+ DUN,DNO,DOU,DOU,DIN,DNO,DNO,DNO,DIN,DNO,DOU,DUN,DNO,DIN,DOU,DOU,
+ DOU,DOU,DOU,DNO,DUN,DIN,DOU,DIN,DIN,DIN,DNO,DNO,DNO,DIN,DIN,DUN,
+ DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
+ DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
+ DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DOU,DUN,DUN,DUN,DUN,DUN,
+ DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN
+};
+
+/* This should be safe */
+#define SBP2_MAX_CMDS 8
/* This is the two dma types we use for cmd_dma below */
enum cmd_dma_types {
@@ -295,8 +338,10 @@ struct sbp2_command_info {
#define SBP2_BREAKAGE_128K_MAX_TRANSFER 0x1
#define SBP2_BREAKAGE_INQUIRY_HACK 0x2
+
struct sbp2scsi_host_info;
+
/*
* Information needed on a per scsi id basis (one for each sbp2 device)
*/
@@ -334,7 +379,7 @@ struct scsi_id_instance_data {
u32 sbp2_command_set_spec_id;
u32 sbp2_command_set;
u32 sbp2_unit_characteristics;
- u32 sbp2_lun;
+ u32 sbp2_device_type_and_lun;
u32 sbp2_firmware_revision;
/*
@@ -366,6 +411,7 @@ struct scsi_id_instance_data {
u32 workarounds;
};
+
/* Sbp2 host data structure (one per IEEE1394 host) */
struct sbp2scsi_host_info {
struct hpsb_host *host; /* IEEE1394 host */
@@ -410,12 +456,20 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id);
static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, size_t length, u16 flags);
static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait);
+static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id,
+ struct sbp2_command_info *command,
+ unchar *scsi_cmd,
+ unsigned int scsi_use_sg,
+ unsigned int scsi_request_bufflen,
+ void *scsi_request_buffer,
+ enum dma_data_direction dma_dir);
static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
struct sbp2_command_info *command);
static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *));
static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data);
+static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd);
static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
struct scsi_cmnd *SCpnt);
static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
diff --git a/trunk/drivers/ieee1394/video1394.c b/trunk/drivers/ieee1394/video1394.c
index 608479b2df14..23911da50154 100644
--- a/trunk/drivers/ieee1394/video1394.c
+++ b/trunk/drivers/ieee1394/video1394.c
@@ -19,6 +19,12 @@
*
* NOTES:
*
+ * jds -- add private data to file to keep track of iso contexts associated
+ * with each open -- so release won't kill all iso transfers.
+ *
+ * Damien Douxchamps: Fix failure when the number of DMA pages per frame is
+ * one.
+ *
* ioctl return codes:
* EFAULT is only for invalid address for the argp
* EINVAL for out of range values
@@ -28,6 +34,12 @@
* ENOTTY for unsupported ioctl request
*
*/
+
+/* Markus Tavenrath :
+ - fixed checks for valid buffer-numbers in video1394_icotl
+ - changed the ways the dma prg's are used, now it's possible to use
+ even a single dma buffer
+*/
#include
#include
#include
@@ -65,6 +77,14 @@
#define ISO_CHANNELS 64
+#ifndef virt_to_page
+#define virt_to_page(x) MAP_NR(x)
+#endif
+
+#ifndef vmalloc_32
+#define vmalloc_32(x) vmalloc(x)
+#endif
+
struct it_dma_prg {
struct dma_cmd begin;
quadlet_t data[4];
@@ -186,12 +206,14 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc,
struct dma_iso_ctx *d;
int i;
- d = kzalloc(sizeof(*d), GFP_KERNEL);
- if (!d) {
+ d = kmalloc(sizeof(struct dma_iso_ctx), GFP_KERNEL);
+ if (d == NULL) {
PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma_iso_ctx");
return NULL;
}
+ memset(d, 0, sizeof *d);
+
d->ohci = ohci;
d->type = type;
d->channel = channel;
@@ -229,8 +251,9 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc,
}
d->ctx = d->iso_tasklet.context;
- d->prg_reg = kmalloc(d->num_desc * sizeof(*d->prg_reg), GFP_KERNEL);
- if (!d->prg_reg) {
+ d->prg_reg = kmalloc(d->num_desc * sizeof(struct dma_prog_region),
+ GFP_KERNEL);
+ if (d->prg_reg == NULL) {
PRINT(KERN_ERR, ohci->host->id, "Failed to allocate ir prg regs");
free_dma_iso_ctx(d);
return NULL;
@@ -245,14 +268,15 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc,
d->cmdPtr = OHCI1394_IsoRcvCommandPtr+32*d->ctx;
d->ctxMatch = OHCI1394_IsoRcvContextMatch+32*d->ctx;
- d->ir_prg = kzalloc(d->num_desc * sizeof(*d->ir_prg),
+ d->ir_prg = kmalloc(d->num_desc * sizeof(struct dma_cmd *),
GFP_KERNEL);
- if (!d->ir_prg) {
+ if (d->ir_prg == NULL) {
PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma ir prg");
free_dma_iso_ctx(d);
return NULL;
}
+ memset(d->ir_prg, 0, d->num_desc * sizeof(struct dma_cmd *));
d->nb_cmd = d->buf_size / PAGE_SIZE + 1;
d->left_size = (d->frame_size % PAGE_SIZE) ?
@@ -273,15 +297,16 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc,
d->ctrlClear = OHCI1394_IsoXmitContextControlClear+16*d->ctx;
d->cmdPtr = OHCI1394_IsoXmitCommandPtr+16*d->ctx;
- d->it_prg = kzalloc(d->num_desc * sizeof(*d->it_prg),
+ d->it_prg = kmalloc(d->num_desc * sizeof(struct it_dma_prg *),
GFP_KERNEL);
- if (!d->it_prg) {
+ if (d->it_prg == NULL) {
PRINT(KERN_ERR, ohci->host->id,
"Failed to allocate dma it prg");
free_dma_iso_ctx(d);
return NULL;
}
+ memset(d->it_prg, 0, d->num_desc*sizeof(struct it_dma_prg *));
d->packet_size = packet_size;
@@ -312,24 +337,47 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc,
}
}
- d->buffer_status =
- kzalloc(d->num_desc * sizeof(*d->buffer_status), GFP_KERNEL);
- d->buffer_prg_assignment =
- kzalloc(d->num_desc * sizeof(*d->buffer_prg_assignment), GFP_KERNEL);
- d->buffer_time =
- kzalloc(d->num_desc * sizeof(*d->buffer_time), GFP_KERNEL);
- d->last_used_cmd =
- kzalloc(d->num_desc * sizeof(*d->last_used_cmd), GFP_KERNEL);
- d->next_buffer =
- kzalloc(d->num_desc * sizeof(*d->next_buffer), GFP_KERNEL);
-
- if (!d->buffer_status || !d->buffer_prg_assignment || !d->buffer_time ||
- !d->last_used_cmd || !d->next_buffer) {
- PRINT(KERN_ERR, ohci->host->id,
- "Failed to allocate dma_iso_ctx member");
+ d->buffer_status = kmalloc(d->num_desc * sizeof(unsigned int),
+ GFP_KERNEL);
+ d->buffer_prg_assignment = kmalloc(d->num_desc * sizeof(unsigned int),
+ GFP_KERNEL);
+ d->buffer_time = kmalloc(d->num_desc * sizeof(struct timeval),
+ GFP_KERNEL);
+ d->last_used_cmd = kmalloc(d->num_desc * sizeof(unsigned int),
+ GFP_KERNEL);
+ d->next_buffer = kmalloc(d->num_desc * sizeof(int),
+ GFP_KERNEL);
+
+ if (d->buffer_status == NULL) {
+ PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_status");
+ free_dma_iso_ctx(d);
+ return NULL;
+ }
+ if (d->buffer_prg_assignment == NULL) {
+ PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_prg_assignment");
+ free_dma_iso_ctx(d);
+ return NULL;
+ }
+ if (d->buffer_time == NULL) {
+ PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_time");
+ free_dma_iso_ctx(d);
+ return NULL;
+ }
+ if (d->last_used_cmd == NULL) {
+ PRINT(KERN_ERR, ohci->host->id, "Failed to allocate last_used_cmd");
+ free_dma_iso_ctx(d);
+ return NULL;
+ }
+ if (d->next_buffer == NULL) {
+ PRINT(KERN_ERR, ohci->host->id, "Failed to allocate next_buffer");
free_dma_iso_ctx(d);
return NULL;
}
+ memset(d->buffer_status, 0, d->num_desc * sizeof(unsigned int));
+ memset(d->buffer_prg_assignment, 0, d->num_desc * sizeof(unsigned int));
+ memset(d->buffer_time, 0, d->num_desc * sizeof(struct timeval));
+ memset(d->last_used_cmd, 0, d->num_desc * sizeof(unsigned int));
+ memset(d->next_buffer, -1, d->num_desc * sizeof(int));
spin_lock_init(&d->lock);
@@ -491,7 +539,7 @@ static void wakeup_dma_ir_ctx(unsigned long l)
if (d->ir_prg[i][d->nb_cmd-1].status & cpu_to_le32(0xFFFF0000)) {
reset_ir_status(d, i);
d->buffer_status[d->buffer_prg_assignment[i]] = VIDEO1394_BUFFER_READY;
- do_gettimeofday(&d->buffer_time[d->buffer_prg_assignment[i]]);
+ do_gettimeofday(&d->buffer_time[i]);
}
}
@@ -998,6 +1046,7 @@ static int __video1394_ioctl(struct file *file,
/* set time of buffer */
v.filltime = d->buffer_time[v.buffer];
+// printk("Buffer %d time %d\n", v.buffer, (d->buffer_time[v.buffer]).tv_usec);
/*
* Look ahead to see how many more buffers have been received
@@ -1036,7 +1085,7 @@ static int __video1394_ioctl(struct file *file,
}
if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) {
- int buf_size = d->nb_cmd * sizeof(*psizes);
+ int buf_size = d->nb_cmd * sizeof(unsigned int);
struct video1394_queue_variable __user *p = argp;
unsigned int __user *qv;
@@ -1055,7 +1104,7 @@ static int __video1394_ioctl(struct file *file,
spin_lock_irqsave(&d->lock,flags);
- /* last_buffer is last_prg */
+ // last_buffer is last_prg
next_prg = (d->last_buffer + 1) % d->num_desc;
if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) {
PRINT(KERN_ERR, ohci->host->id,
@@ -1202,12 +1251,13 @@ static int video1394_open(struct inode *inode, struct file *file)
if (ohci == NULL)
return -EIO;
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx) {
+ ctx = kmalloc(sizeof(struct file_ctx), GFP_KERNEL);
+ if (ctx == NULL) {
PRINT(KERN_ERR, ohci->host->id, "Cannot malloc file_ctx");
return -ENOMEM;
}
+ memset(ctx, 0, sizeof(struct file_ctx));
ctx->ohci = ohci;
INIT_LIST_HEAD(&ctx->context_list);
ctx->current_ctx = NULL;
diff --git a/trunk/drivers/infiniband/core/sysfs.c b/trunk/drivers/infiniband/core/sysfs.c
index 1f1743c5c9a3..08648b1a387e 100644
--- a/trunk/drivers/infiniband/core/sysfs.c
+++ b/trunk/drivers/infiniband/core/sysfs.c
@@ -434,24 +434,24 @@ static void ib_device_release(struct class_device *cdev)
kfree(dev);
}
-static int ib_device_uevent(struct class_device *cdev, char **envp,
- int num_envp, char *buf, int size)
+static int ib_device_hotplug(struct class_device *cdev, char **envp,
+ int num_envp, char *buf, int size)
{
struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
int i = 0, len = 0;
- if (add_uevent_var(envp, num_envp, &i, buf, size, &len,
- "NAME=%s", dev->name))
+ if (add_hotplug_env_var(envp, num_envp, &i, buf, size, &len,
+ "NAME=%s", dev->name))
return -ENOMEM;
/*
- * It might be nice to pass the node GUID with the event, but
+ * It might be nice to pass the node GUID to hotplug, but
* right now the only way to get it is to query the device
* provider, and this can crash during device removal because
* we are will be running after driver removal has started.
* We could add a node_guid field to struct ib_device, or we
- * could just let userspace read the node GUID from sysfs when
- * devices are added.
+ * could just let the hotplug script read the node GUID from
+ * sysfs when devices are added.
*/
envp[i] = NULL;
@@ -653,7 +653,7 @@ static struct class_device_attribute *ib_class_attributes[] = {
static struct class ib_class = {
.name = "infiniband",
.release = ib_device_release,
- .uevent = ib_device_uevent,
+ .hotplug = ib_device_hotplug,
};
int ib_device_register_sysfs(struct ib_device *device)
diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 780009c7eaa6..475d98fa9e26 100644
--- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -47,8 +47,6 @@
#include
#include
-#include
-
MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
MODULE_LICENSE("Dual BSD/GPL");
diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index ed0c2ead8bc1..ef3ee035bbc8 100644
--- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -43,8 +43,6 @@
#include
#include
-#include
-
#include "ipoib.h"
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c
index ef5824c8846b..bdd2a7fc268d 100644
--- a/trunk/drivers/input/input.c
+++ b/trunk/drivers/input/input.c
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -528,49 +529,10 @@ INPUT_DEV_STRING_ATTR_SHOW(name);
INPUT_DEV_STRING_ATTR_SHOW(phys);
INPUT_DEV_STRING_ATTR_SHOW(uniq);
-static int print_modalias_bits(char *buf, char prefix, unsigned long *arr,
- unsigned int min, unsigned int max)
-{
- int len, i;
-
- len = sprintf(buf, "%c", prefix);
- for (i = min; i < max; i++)
- if (arr[LONG(i)] & BIT(i))
- len += sprintf(buf+len, "%X,", i);
- return len;
-}
-
-static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
-{
- struct input_dev *id = to_input_dev(dev);
- ssize_t len = 0;
-
- len += sprintf(buf+len, "input:b%04Xv%04Xp%04Xe%04X-",
- id->id.bustype,
- id->id.vendor,
- id->id.product,
- id->id.version);
-
- len += print_modalias_bits(buf+len, 'e', id->evbit, 0, EV_MAX);
- len += print_modalias_bits(buf+len, 'k', id->keybit,
- KEY_MIN_INTERESTING, KEY_MAX);
- len += print_modalias_bits(buf+len, 'r', id->relbit, 0, REL_MAX);
- len += print_modalias_bits(buf+len, 'a', id->absbit, 0, ABS_MAX);
- len += print_modalias_bits(buf+len, 'm', id->mscbit, 0, MSC_MAX);
- len += print_modalias_bits(buf+len, 'l', id->ledbit, 0, LED_MAX);
- len += print_modalias_bits(buf+len, 's', id->sndbit, 0, SND_MAX);
- len += print_modalias_bits(buf+len, 'f', id->ffbit, 0, FF_MAX);
- len += print_modalias_bits(buf+len, 'w', id->swbit, 0, SW_MAX);
- len += sprintf(buf+len, "\n");
- return len;
-}
-static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
-
static struct attribute *input_dev_attrs[] = {
&class_device_attr_name.attr,
&class_device_attr_phys.attr,
&class_device_attr_uniq.attr,
- &class_device_attr_modalias.attr,
NULL
};
@@ -649,10 +611,10 @@ static void input_dev_release(struct class_device *class_dev)
}
/*
- * Input uevent interface - loading event handlers based on
+ * Input hotplugging interface - loading event handlers based on
* device bitfields.
*/
-static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
+static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
char *buffer, int buffer_size, int *cur_len,
const char *name, unsigned long *bitmap, int max)
{
@@ -677,7 +639,7 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
#define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \
do { \
- int err = add_uevent_var(envp, num_envp, &i, \
+ int err = add_hotplug_env_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \
fmt, val); \
if (err) \
@@ -686,15 +648,15 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \
do { \
- int err = input_add_uevent_bm_var(envp, num_envp, &i, \
+ int err = input_add_hotplug_bm_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \
name, bm, max); \
if (err) \
return err; \
} while (0)
-static int input_dev_uevent(struct class_device *cdev, char **envp,
- int num_envp, char *buffer, int buffer_size)
+static int input_dev_hotplug(struct class_device *cdev, char **envp,
+ int num_envp, char *buffer, int buffer_size)
{
struct input_dev *dev = to_input_dev(cdev);
int i = 0;
@@ -736,7 +698,7 @@ static int input_dev_uevent(struct class_device *cdev, char **envp,
struct class input_class = {
.name = "input",
.release = input_dev_release,
- .uevent = input_dev_uevent,
+ .hotplug = input_dev_hotplug,
};
struct input_dev *input_allocate_device(void)
diff --git a/trunk/drivers/input/joystick/iforce/iforce-usb.c b/trunk/drivers/input/joystick/iforce/iforce-usb.c
index bc2fce60f9f8..64b4a3080985 100644
--- a/trunk/drivers/input/joystick/iforce/iforce-usb.c
+++ b/trunk/drivers/input/joystick/iforce/iforce-usb.c
@@ -235,6 +235,7 @@ static struct usb_device_id iforce_usb_ids [] = {
MODULE_DEVICE_TABLE (usb, iforce_usb_ids);
struct usb_driver iforce_usb_driver = {
+ .owner = THIS_MODULE,
.name = "iforce",
.probe = iforce_usb_probe,
.disconnect = iforce_usb_disconnect,
diff --git a/trunk/drivers/input/serio/serio.c b/trunk/drivers/input/serio/serio.c
index 8e530cc970e1..fbb69ef6a77b 100644
--- a/trunk/drivers/input/serio/serio.c
+++ b/trunk/drivers/input/serio/serio.c
@@ -800,16 +800,16 @@ static int serio_bus_match(struct device *dev, struct device_driver *drv)
#ifdef CONFIG_HOTPLUG
-#define SERIO_ADD_UEVENT_VAR(fmt, val...) \
+#define SERIO_ADD_HOTPLUG_VAR(fmt, val...) \
do { \
- int err = add_uevent_var(envp, num_envp, &i, \
+ int err = add_hotplug_env_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \
fmt, val); \
if (err) \
return err; \
} while (0)
-static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
+static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
{
struct serio *serio;
int i = 0;
@@ -820,21 +820,21 @@ static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buf
serio = to_serio_port(dev);
- SERIO_ADD_UEVENT_VAR("SERIO_TYPE=%02x", serio->id.type);
- SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto);
- SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id);
- SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra);
- SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
+ SERIO_ADD_HOTPLUG_VAR("SERIO_TYPE=%02x", serio->id.type);
+ SERIO_ADD_HOTPLUG_VAR("SERIO_PROTO=%02x", serio->id.proto);
+ SERIO_ADD_HOTPLUG_VAR("SERIO_ID=%02x", serio->id.id);
+ SERIO_ADD_HOTPLUG_VAR("SERIO_EXTRA=%02x", serio->id.extra);
+ SERIO_ADD_HOTPLUG_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
envp[i] = NULL;
return 0;
}
-#undef SERIO_ADD_UEVENT_VAR
+#undef SERIO_ADD_HOTPLUG_VAR
#else
-static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
+static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
{
return -ENODEV;
}
@@ -908,7 +908,7 @@ static int __init serio_init(void)
serio_bus.dev_attrs = serio_device_attrs;
serio_bus.drv_attrs = serio_driver_attrs;
serio_bus.match = serio_bus_match;
- serio_bus.uevent = serio_uevent;
+ serio_bus.hotplug = serio_hotplug;
serio_bus.resume = serio_resume;
bus_register(&serio_bus);
diff --git a/trunk/drivers/isdn/hardware/avm/avm_cs.c b/trunk/drivers/isdn/hardware/avm/avm_cs.c
index 2a2b03ff096b..27391c32f3eb 100644
--- a/trunk/drivers/isdn/hardware/avm/avm_cs.c
+++ b/trunk/drivers/isdn/hardware/avm/avm_cs.c
@@ -53,6 +53,8 @@ MODULE_LICENSE("GPL");
static void avmcs_config(dev_link_t *link);
static void avmcs_release(dev_link_t *link);
+static int avmcs_event(event_t event, int priority,
+ event_callback_args_t *args);
/*
The attach() and detach() entry points are used to create and destroy
@@ -60,7 +62,16 @@ static void avmcs_release(dev_link_t *link);
needed to manage one actual PCMCIA card.
*/
-static void avmcs_detach(struct pcmcia_device *p_dev);
+static dev_link_t *avmcs_attach(void);
+static void avmcs_detach(dev_link_t *);
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static dev_info_t dev_info = "avm_cs";
/*
A linked list of "instances" of the skeleton device. Each actual
@@ -72,7 +83,15 @@ static void avmcs_detach(struct pcmcia_device *p_dev);
device numbers are used to derive the corresponding array index.
*/
+static dev_link_t *dev_list = NULL;
+
/*
+ A dev_link_t structure has fields for most things that are needed
+ to keep track of a socket, but there will usually be some device
+ specific information that also needs to be kept track of. The
+ 'priv' pointer in a dev_link_t structure can be used to point to
+ a device-specific private data structure, like this.
+
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
@@ -99,11 +118,13 @@ typedef struct local_info_t {
======================================================================*/
-static int avmcs_attach(struct pcmcia_device *p_dev)
+static dev_link_t *avmcs_attach(void)
{
+ client_reg_t client_reg;
dev_link_t *link;
local_info_t *local;
-
+ int ret;
+
/* Initialize the dev_link_t structure */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link)
@@ -134,19 +155,25 @@ static int avmcs_attach(struct pcmcia_device *p_dev)
goto err_kfree;
memset(local, 0, sizeof(local_info_t));
link->priv = local;
-
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- avmcs_config(link);
-
- return 0;
+
+ /* Register with Card Services */
+ link->next = dev_list;
+ dev_list = link;
+ client_reg.dev_info = &dev_info;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+ ret = pcmcia_register_client(&link->handle, &client_reg);
+ if (ret != 0) {
+ cs_error(link->handle, RegisterClient, ret);
+ avmcs_detach(link);
+ goto err;
+ }
+ return link;
err_kfree:
kfree(link);
err:
- return -EINVAL;
+ return NULL;
} /* avmcs_attach */
/*======================================================================
@@ -158,13 +185,33 @@ static int avmcs_attach(struct pcmcia_device *p_dev)
======================================================================*/
-static void avmcs_detach(struct pcmcia_device *p_dev)
+static void avmcs_detach(dev_link_t *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
+ dev_link_t **linkp;
- if (link->state & DEV_CONFIG)
- avmcs_release(link);
+ /* Locate device structure */
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link) break;
+ if (*linkp == NULL)
+ return;
+
+ /*
+ If the device is currently configured and active, we won't
+ actually delete it yet. Instead, it is marked so that when
+ the release() function is called, that will trigger a proper
+ detach().
+ */
+ if (link->state & DEV_CONFIG) {
+ link->state |= DEV_STALE_LINK;
+ return;
+ }
+ /* Break the link with Card Services */
+ if (link->handle)
+ pcmcia_deregister_client(link->handle);
+
+ /* Unlink device structure, free pieces */
+ *linkp = link->next;
kfree(link->priv);
kfree(link);
} /* avmcs_detach */
@@ -377,30 +424,12 @@ static void avmcs_release(dev_link_t *link)
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
+
+ if (link->state & DEV_STALE_LINK)
+ avmcs_detach(link);
+
} /* avmcs_release */
-static int avmcs_suspend(struct pcmcia_device *dev)
-{
- dev_link_t *link = dev_to_instance(dev);
-
- link->state |= DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
-
- return 0;
-}
-
-static int avmcs_resume(struct pcmcia_device *dev)
-{
- dev_link_t *link = dev_to_instance(dev);
-
- link->state &= ~DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_request_configuration(link->handle, &link->conf);
-
- return 0;
-}
-
/*======================================================================
The card status event handler. Mostly, this schedules other
@@ -415,6 +444,38 @@ static int avmcs_resume(struct pcmcia_device *dev)
======================================================================*/
+static int avmcs_event(event_t event, int priority,
+ event_callback_args_t *args)
+{
+ dev_link_t *link = args->client_data;
+
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG)
+ avmcs_release(link);
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ avmcs_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ if (link->state & DEV_CONFIG)
+ pcmcia_release_configuration(link->handle);
+ break;
+ case CS_EVENT_PM_RESUME:
+ link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
+ if (link->state & DEV_CONFIG)
+ pcmcia_request_configuration(link->handle, &link->conf);
+ break;
+ }
+ return 0;
+} /* avmcs_event */
static struct pcmcia_device_id avmcs_ids[] = {
PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335),
@@ -429,11 +490,10 @@ static struct pcmcia_driver avmcs_driver = {
.drv = {
.name = "avm_cs",
},
- .probe = avmcs_attach,
- .remove = avmcs_detach,
+ .attach = avmcs_attach,
+ .event = avmcs_event,
+ .detach = avmcs_detach,
.id_table = avmcs_ids,
- .suspend= avmcs_suspend,
- .resume = avmcs_resume,
};
static int __init avmcs_init(void)
@@ -444,6 +504,7 @@ static int __init avmcs_init(void)
static void __exit avmcs_exit(void)
{
pcmcia_unregister_driver(&avmcs_driver);
+ BUG_ON(dev_list != NULL);
}
module_init(avmcs_init);
diff --git a/trunk/drivers/isdn/hisax/avma1_cs.c b/trunk/drivers/isdn/hisax/avma1_cs.c
index 969da40c4248..5f5a5ae740d2 100644
--- a/trunk/drivers/isdn/hisax/avma1_cs.c
+++ b/trunk/drivers/isdn/hisax/avma1_cs.c
@@ -69,6 +69,8 @@ module_param(isdnprot, int, 0);
static void avma1cs_config(dev_link_t *link);
static void avma1cs_release(dev_link_t *link);
+static int avma1cs_event(event_t event, int priority,
+ event_callback_args_t *args);
/*
The attach() and detach() entry points are used to create and destroy
@@ -76,8 +78,16 @@ static void avma1cs_release(dev_link_t *link);
needed to manage one actual PCMCIA card.
*/
-static void avma1cs_detach(struct pcmcia_device *p_dev);
+static dev_link_t *avma1cs_attach(void);
+static void avma1cs_detach(dev_link_t *);
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static dev_info_t dev_info = "avma1_cs";
/*
A linked list of "instances" of the skeleton device. Each actual
@@ -89,7 +99,15 @@ static void avma1cs_detach(struct pcmcia_device *p_dev);
device numbers are used to derive the corresponding array index.
*/
+static dev_link_t *dev_list = NULL;
+
/*
+ A dev_link_t structure has fields for most things that are needed
+ to keep track of a socket, but there will usually be some device
+ specific information that also needs to be kept track of. The
+ 'priv' pointer in a dev_link_t structure can be used to point to
+ a device-specific private data structure, like this.
+
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
@@ -116,24 +134,26 @@ typedef struct local_info_t {
======================================================================*/
-static int avma1cs_attach(struct pcmcia_device *p_dev)
+static dev_link_t *avma1cs_attach(void)
{
+ client_reg_t client_reg;
dev_link_t *link;
local_info_t *local;
-
+ int ret;
+
DEBUG(0, "avma1cs_attach()\n");
/* Initialize the dev_link_t structure */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link)
- return -ENOMEM;
+ return NULL;
memset(link, 0, sizeof(struct dev_link_t));
/* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) {
kfree(link);
- return -ENOMEM;
+ return NULL;
}
memset(local, 0, sizeof(local_info_t));
link->priv = local;
@@ -158,13 +178,20 @@ static int avma1cs_attach(struct pcmcia_device *p_dev)
link->conf.ConfigIndex = 1;
link->conf.Present = PRESENT_OPTION;
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- avma1cs_config(link);
+ /* Register with Card Services */
+ link->next = dev_list;
+ dev_list = link;
+ client_reg.dev_info = &dev_info;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+ ret = pcmcia_register_client(&link->handle, &client_reg);
+ if (ret != 0) {
+ cs_error(link->handle, RegisterClient, ret);
+ avma1cs_detach(link);
+ return NULL;
+ }
- return 0;
+ return link;
} /* avma1cs_attach */
/*======================================================================
@@ -176,17 +203,42 @@ static int avma1cs_attach(struct pcmcia_device *p_dev)
======================================================================*/
-static void avma1cs_detach(struct pcmcia_device *p_dev)
+static void avma1cs_detach(dev_link_t *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
+ dev_link_t **linkp;
DEBUG(0, "avma1cs_detach(0x%p)\n", link);
+
+ /* Locate device structure */
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link) break;
+ if (*linkp == NULL)
+ return;
- if (link->state & DEV_CONFIG)
- avma1cs_release(link);
+ /*
+ If the device is currently configured and active, we won't
+ actually delete it yet. Instead, it is marked so that when
+ the release() function is called, that will trigger a proper
+ detach().
+ */
+ if (link->state & DEV_CONFIG) {
+#ifdef PCMCIA_DEBUG
+ printk(KERN_DEBUG "avma1_cs: detach postponed, '%s' "
+ "still locked\n", link->dev->dev_name);
+#endif
+ link->state |= DEV_STALE_LINK;
+ return;
+ }
+ /* Break the link with Card Services */
+ if (link->handle)
+ pcmcia_deregister_client(link->handle);
+
+ /* Unlink device structure, free pieces */
+ *linkp = link->next;
kfree(link->priv);
kfree(link);
+
} /* avma1cs_detach */
/*======================================================================
@@ -388,30 +440,58 @@ static void avma1cs_release(dev_link_t *link)
pcmcia_release_io(link->handle, &link->io);
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
+
+ if (link->state & DEV_STALE_LINK)
+ avma1cs_detach(link);
} /* avma1cs_release */
-static int avma1cs_suspend(struct pcmcia_device *dev)
-{
- dev_link_t *link = dev_to_instance(dev);
+/*======================================================================
- link->state |= DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received. A CARD_REMOVAL event
+ also sets some flags to discourage the net drivers from trying
+ to talk to the card any more.
- return 0;
-}
+ When a CARD_REMOVAL event is received, we immediately set a flag
+ to block future accesses to this device. All the functions that
+ actually access the device should check this flag to make sure
+ the card is still present.
+
+======================================================================*/
-static int avma1cs_resume(struct pcmcia_device *dev)
+static int avma1cs_event(event_t event, int priority,
+ event_callback_args_t *args)
{
- dev_link_t *link = dev_to_instance(dev);
+ dev_link_t *link = args->client_data;
- link->state &= ~DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
+ DEBUG(1, "avma1cs_event(0x%06x)\n", event);
+
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ if (link->state & DEV_CONFIG)
+ avma1cs_release(link);
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ avma1cs_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ if (link->state & DEV_CONFIG)
+ pcmcia_release_configuration(link->handle);
+ break;
+ case CS_EVENT_PM_RESUME:
+ link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
+ if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
-
- return 0;
-}
-
+ break;
+ }
+ return 0;
+} /* avma1cs_event */
static struct pcmcia_device_id avma1cs_ids[] = {
PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb),
@@ -425,11 +505,10 @@ static struct pcmcia_driver avma1cs_driver = {
.drv = {
.name = "avma1_cs",
},
- .probe = avma1cs_attach,
- .remove = avma1cs_detach,
+ .attach = avma1cs_attach,
+ .event = avma1cs_event,
+ .detach = avma1cs_detach,
.id_table = avma1cs_ids,
- .suspend = avma1cs_suspend,
- .resume = avma1cs_resume,
};
/*====================================================================*/
@@ -442,6 +521,7 @@ static int __init init_avma1_cs(void)
static void __exit exit_avma1_cs(void)
{
pcmcia_unregister_driver(&avma1cs_driver);
+ BUG_ON(dev_list != NULL);
}
module_init(init_avma1_cs);
diff --git a/trunk/drivers/isdn/hisax/elsa_cs.c b/trunk/drivers/isdn/hisax/elsa_cs.c
index 062fb8f0739f..6fc6868de0b0 100644
--- a/trunk/drivers/isdn/hisax/elsa_cs.c
+++ b/trunk/drivers/isdn/hisax/elsa_cs.c
@@ -96,6 +96,8 @@ module_param(protocol, int, 0);
static void elsa_cs_config(dev_link_t *link);
static void elsa_cs_release(dev_link_t *link);
+static int elsa_cs_event(event_t event, int priority,
+ event_callback_args_t *args);
/*
The attach() and detach() entry points are used to create and destroy
@@ -103,9 +105,39 @@ static void elsa_cs_release(dev_link_t *link);
needed to manage one actual PCMCIA card.
*/
-static void elsa_cs_detach(struct pcmcia_device *p_dev);
+static dev_link_t *elsa_cs_attach(void);
+static void elsa_cs_detach(dev_link_t *);
/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static dev_info_t dev_info = "elsa_cs";
+
+/*
+ A linked list of "instances" of the elsa_cs device. Each actual
+ PCMCIA card corresponds to one device instance, and is described
+ by one dev_link_t structure (defined in ds.h).
+
+ You may not want to use a linked list for this -- for example, the
+ memory card driver uses an array of dev_link_t pointers, where minor
+ device numbers are used to derive the corresponding array index.
+*/
+
+static dev_link_t *dev_list = NULL;
+
+/*
+ A dev_link_t structure has fields for most things that are needed
+ to keep track of a socket, but there will usually be some device
+ specific information that also needs to be kept track of. The
+ 'priv' pointer in a dev_link_t structure can be used to point to
+ a device-specific private data structure, like this.
+
+ To simplify the data structure handling, we actually include the
+ dev_link_t structure in the device's private data structure.
+
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
@@ -139,16 +171,18 @@ typedef struct local_info_t {
======================================================================*/
-static int elsa_cs_attach(struct pcmcia_device *p_dev)
+static dev_link_t *elsa_cs_attach(void)
{
+ client_reg_t client_reg;
dev_link_t *link;
local_info_t *local;
+ int ret;
DEBUG(0, "elsa_cs_attach()\n");
/* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
- if (!local) return -ENOMEM;
+ if (!local) return NULL;
memset(local, 0, sizeof(local_info_t));
local->cardnr = -1;
link = &local->link; link->priv = local;
@@ -173,13 +207,20 @@ static int elsa_cs_attach(struct pcmcia_device *p_dev)
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- elsa_cs_config(link);
+ /* Register with Card Services */
+ link->next = dev_list;
+ dev_list = link;
+ client_reg.dev_info = &dev_info;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+ ret = pcmcia_register_client(&link->handle, &client_reg);
+ if (ret != CS_SUCCESS) {
+ cs_error(link->handle, RegisterClient, ret);
+ elsa_cs_detach(link);
+ return NULL;
+ }
- return 0;
+ return link;
} /* elsa_cs_attach */
/*======================================================================
@@ -191,18 +232,32 @@ static int elsa_cs_attach(struct pcmcia_device *p_dev)
======================================================================*/
-static void elsa_cs_detach(struct pcmcia_device *p_dev)
+static void elsa_cs_detach(dev_link_t *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
+ dev_link_t **linkp;
local_info_t *info = link->priv;
+ int ret;
DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
- if (link->state & DEV_CONFIG) {
- info->busy = 1;
- elsa_cs_release(link);
+ /* Locate device structure */
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link) break;
+ if (*linkp == NULL)
+ return;
+
+ if (link->state & DEV_CONFIG)
+ elsa_cs_release(link);
+
+ /* Break the link with Card Services */
+ if (link->handle) {
+ ret = pcmcia_deregister_client(link->handle);
+ if (ret != CS_SUCCESS)
+ cs_error(link->handle, DeregisterClient, ret);
}
+ /* Unlink device structure and free it */
+ *linkp = link->next;
kfree(info);
} /* elsa_cs_detach */
@@ -392,31 +447,60 @@ static void elsa_cs_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
} /* elsa_cs_release */
-static int elsa_suspend(struct pcmcia_device *p_dev)
-{
- dev_link_t *link = dev_to_instance(p_dev);
- local_info_t *dev = link->priv;
+/*======================================================================
- link->state |= DEV_SUSPEND;
- dev->busy = 1;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received. A CARD_REMOVAL event
+ also sets some flags to discourage the net drivers from trying
+ to talk to the card any more.
- return 0;
-}
+ When a CARD_REMOVAL event is received, we immediately set a flag
+ to block future accesses to this device. All the functions that
+ actually access the device should check this flag to make sure
+ the card is still present.
+
+======================================================================*/
-static int elsa_resume(struct pcmcia_device *p_dev)
+static int elsa_cs_event(event_t event, int priority,
+ event_callback_args_t *args)
{
- dev_link_t *link = dev_to_instance(p_dev);
- local_info_t *dev = link->priv;
+ dev_link_t *link = args->client_data;
+ local_info_t *dev = link->priv;
- link->state &= ~DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_request_configuration(link->handle, &link->conf);
- dev->busy = 0;
+ DEBUG(1, "elsa_cs_event(%d)\n", event);
- return 0;
-}
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG) {
+ ((local_info_t*)link->priv)->busy = 1;
+ elsa_cs_release(link);
+ }
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ elsa_cs_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ /* Mark the device as stopped, to block IO until later */
+ dev->busy = 1;
+ if (link->state & DEV_CONFIG)
+ pcmcia_release_configuration(link->handle);
+ break;
+ case CS_EVENT_PM_RESUME:
+ link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
+ if (link->state & DEV_CONFIG)
+ pcmcia_request_configuration(link->handle, &link->conf);
+ dev->busy = 0;
+ break;
+ }
+ return 0;
+} /* elsa_cs_event */
static struct pcmcia_device_id elsa_ids[] = {
PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257),
@@ -430,11 +514,10 @@ static struct pcmcia_driver elsa_cs_driver = {
.drv = {
.name = "elsa_cs",
},
- .probe = elsa_cs_attach,
- .remove = elsa_cs_detach,
+ .attach = elsa_cs_attach,
+ .event = elsa_cs_event,
+ .detach = elsa_cs_detach,
.id_table = elsa_ids,
- .suspend = elsa_suspend,
- .resume = elsa_resume,
};
static int __init init_elsa_cs(void)
@@ -445,6 +528,7 @@ static int __init init_elsa_cs(void)
static void __exit exit_elsa_cs(void)
{
pcmcia_unregister_driver(&elsa_cs_driver);
+ BUG_ON(dev_list != NULL);
}
module_init(init_elsa_cs);
diff --git a/trunk/drivers/isdn/hisax/hfc_usb.c b/trunk/drivers/isdn/hisax/hfc_usb.c
index ca5b4a3b683e..f8457ef48826 100644
--- a/trunk/drivers/isdn/hisax/hfc_usb.c
+++ b/trunk/drivers/isdn/hisax/hfc_usb.c
@@ -1715,6 +1715,7 @@ hfc_usb_disconnect(struct usb_interface
/* our driver information structure */
/************************************/
static struct usb_driver hfc_drv = {
+ .owner = THIS_MODULE,
.name = "hfc_usb",
.id_table = hfcusb_idtab,
.probe = hfc_usb_probe,
diff --git a/trunk/drivers/isdn/hisax/sedlbauer_cs.c b/trunk/drivers/isdn/hisax/sedlbauer_cs.c
index 6f5213a18a8d..dc334aab433e 100644
--- a/trunk/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/trunk/drivers/isdn/hisax/sedlbauer_cs.c
@@ -97,6 +97,8 @@ module_param(protocol, int, 0);
static void sedlbauer_config(dev_link_t *link);
static void sedlbauer_release(dev_link_t *link);
+static int sedlbauer_event(event_t event, int priority,
+ event_callback_args_t *args);
/*
The attach() and detach() entry points are used to create and destroy
@@ -104,7 +106,8 @@ static void sedlbauer_release(dev_link_t *link);
needed to manage one actual PCMCIA card.
*/
-static void sedlbauer_detach(struct pcmcia_device *p_dev);
+static dev_link_t *sedlbauer_attach(void);
+static void sedlbauer_detach(dev_link_t *);
/*
You'll also need to prototype all the functions that will actually
@@ -114,6 +117,35 @@ static void sedlbauer_detach(struct pcmcia_device *p_dev);
*/
/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static dev_info_t dev_info = "sedlbauer_cs";
+
+/*
+ A linked list of "instances" of the sedlbauer device. Each actual
+ PCMCIA card corresponds to one device instance, and is described
+ by one dev_link_t structure (defined in ds.h).
+
+ You may not want to use a linked list for this -- for example, the
+ memory card driver uses an array of dev_link_t pointers, where minor
+ device numbers are used to derive the corresponding array index.
+*/
+
+static dev_link_t *dev_list = NULL;
+
+/*
+ A dev_link_t structure has fields for most things that are needed
+ to keep track of a socket, but there will usually be some device
+ specific information that also needs to be kept track of. The
+ 'priv' pointer in a dev_link_t structure can be used to point to
+ a device-specific private data structure, like this.
+
+ To simplify the data structure handling, we actually include the
+ dev_link_t structure in the device's private data structure.
+
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
@@ -148,16 +180,18 @@ typedef struct local_info_t {
======================================================================*/
-static int sedlbauer_attach(struct pcmcia_device *p_dev)
+static dev_link_t *sedlbauer_attach(void)
{
local_info_t *local;
dev_link_t *link;
+ client_reg_t client_reg;
+ int ret;
DEBUG(0, "sedlbauer_attach()\n");
/* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
- if (!local) return -ENOMEM;
+ if (!local) return NULL;
memset(local, 0, sizeof(local_info_t));
local->cardnr = -1;
link = &local->link; link->priv = local;
@@ -187,13 +221,20 @@ static int sedlbauer_attach(struct pcmcia_device *p_dev)
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- sedlbauer_config(link);
+ /* Register with Card Services */
+ link->next = dev_list;
+ dev_list = link;
+ client_reg.dev_info = &dev_info;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+ ret = pcmcia_register_client(&link->handle, &client_reg);
+ if (ret != CS_SUCCESS) {
+ cs_error(link->handle, RegisterClient, ret);
+ sedlbauer_detach(link);
+ return NULL;
+ }
- return 0;
+ return link;
} /* sedlbauer_attach */
/*======================================================================
@@ -205,17 +246,39 @@ static int sedlbauer_attach(struct pcmcia_device *p_dev)
======================================================================*/
-static void sedlbauer_detach(struct pcmcia_device *p_dev)
+static void sedlbauer_detach(dev_link_t *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
+ dev_link_t **linkp;
DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
+
+ /* Locate device structure */
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link) break;
+ if (*linkp == NULL)
+ return;
+ /*
+ If the device is currently configured and active, we won't
+ actually delete it yet. Instead, it is marked so that when
+ the release() function is called, that will trigger a proper
+ detach().
+ */
if (link->state & DEV_CONFIG) {
- ((local_info_t *)link->priv)->stop = 1;
- sedlbauer_release(link);
+#ifdef PCMCIA_DEBUG
+ printk(KERN_DEBUG "sedlbauer_cs: detach postponed, '%s' "
+ "still locked\n", link->dev->dev_name);
+#endif
+ link->state |= DEV_STALE_LINK;
+ return;
}
+ /* Break the link with Card Services */
+ if (link->handle)
+ pcmcia_deregister_client(link->handle);
+
+ /* Unlink device structure, and free it */
+ *linkp = link->next;
/* This points to the parent local_info_t struct */
kfree(link->priv);
} /* sedlbauer_detach */
@@ -484,34 +547,68 @@ static void sedlbauer_release(dev_link_t *link)
if (link->irq.AssignedIRQ)
pcmcia_release_irq(link->handle, &link->irq);
link->state &= ~DEV_CONFIG;
+
+ if (link->state & DEV_STALE_LINK)
+ sedlbauer_detach(link);
+
} /* sedlbauer_release */
-static int sedlbauer_suspend(struct pcmcia_device *p_dev)
-{
- dev_link_t *link = dev_to_instance(p_dev);
- local_info_t *dev = link->priv;
+/*======================================================================
- link->state |= DEV_SUSPEND;
- dev->stop = 1;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received.
- return 0;
-}
+ When a CARD_REMOVAL event is received, we immediately set a
+ private flag to block future accesses to this device. All the
+ functions that actually access the device should check this flag
+ to make sure the card is still present.
+
+======================================================================*/
-static int sedlbauer_resume(struct pcmcia_device *p_dev)
+static int sedlbauer_event(event_t event, int priority,
+ event_callback_args_t *args)
{
- dev_link_t *link = dev_to_instance(p_dev);
- local_info_t *dev = link->priv;
-
+ dev_link_t *link = args->client_data;
+ local_info_t *dev = link->priv;
+
+ DEBUG(1, "sedlbauer_event(0x%06x)\n", event);
+
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG) {
+ ((local_info_t *)link->priv)->stop = 1;
+ sedlbauer_release(link);
+ }
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ sedlbauer_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ /* Mark the device as stopped, to block IO until later */
+ dev->stop = 1;
+ if (link->state & DEV_CONFIG)
+ pcmcia_release_configuration(link->handle);
+ break;
+ case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG)
- pcmcia_request_configuration(link->handle, &link->conf);
+ pcmcia_request_configuration(link->handle, &link->conf);
dev->stop = 0;
-
- return 0;
-}
-
+ /*
+ In a normal driver, additional code may go here to restore
+ the device state and restart IO.
+ */
+ break;
+ }
+ return 0;
+} /* sedlbauer_event */
static struct pcmcia_device_id sedlbauer_ids[] = {
PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a),
@@ -530,11 +627,10 @@ static struct pcmcia_driver sedlbauer_driver = {
.drv = {
.name = "sedlbauer_cs",
},
- .probe = sedlbauer_attach,
- .remove = sedlbauer_detach,
+ .attach = sedlbauer_attach,
+ .event = sedlbauer_event,
+ .detach = sedlbauer_detach,
.id_table = sedlbauer_ids,
- .suspend = sedlbauer_suspend,
- .resume = sedlbauer_resume,
};
static int __init init_sedlbauer_cs(void)
@@ -545,6 +641,7 @@ static int __init init_sedlbauer_cs(void)
static void __exit exit_sedlbauer_cs(void)
{
pcmcia_unregister_driver(&sedlbauer_driver);
+ BUG_ON(dev_list != NULL);
}
module_init(init_sedlbauer_cs);
diff --git a/trunk/drivers/isdn/hisax/st5481_init.c b/trunk/drivers/isdn/hisax/st5481_init.c
index 99cb0f3d59a1..8e192a3a3490 100644
--- a/trunk/drivers/isdn/hisax/st5481_init.c
+++ b/trunk/drivers/isdn/hisax/st5481_init.c
@@ -180,6 +180,7 @@ static struct usb_device_id st5481_ids[] = {
MODULE_DEVICE_TABLE (usb, st5481_ids);
static struct usb_driver st5481_usb_driver = {
+ .owner = THIS_MODULE,
.name = "st5481_usb",
.probe = probe_st5481,
.disconnect = disconnect_st5481,
diff --git a/trunk/drivers/isdn/hisax/teles_cs.c b/trunk/drivers/isdn/hisax/teles_cs.c
index 4e5c14c7240e..0ddef1bf778b 100644
--- a/trunk/drivers/isdn/hisax/teles_cs.c
+++ b/trunk/drivers/isdn/hisax/teles_cs.c
@@ -77,6 +77,8 @@ module_param(protocol, int, 0);
static void teles_cs_config(dev_link_t *link);
static void teles_cs_release(dev_link_t *link);
+static int teles_cs_event(event_t event, int priority,
+ event_callback_args_t *args);
/*
The attach() and detach() entry points are used to create and destroy
@@ -84,7 +86,16 @@ static void teles_cs_release(dev_link_t *link);
needed to manage one actual PCMCIA card.
*/
-static void teles_detach(struct pcmcia_device *p_dev);
+static dev_link_t *teles_attach(void);
+static void teles_detach(dev_link_t *);
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static dev_info_t dev_info = "teles_cs";
/*
A linked list of "instances" of the teles_cs device. Each actual
@@ -96,7 +107,18 @@ static void teles_detach(struct pcmcia_device *p_dev);
device numbers are used to derive the corresponding array index.
*/
+static dev_link_t *dev_list = NULL;
+
/*
+ A dev_link_t structure has fields for most things that are needed
+ to keep track of a socket, but there will usually be some device
+ specific information that also needs to be kept track of. The
+ 'priv' pointer in a dev_link_t structure can be used to point to
+ a device-specific private data structure, like this.
+
+ To simplify the data structure handling, we actually include the
+ dev_link_t structure in the device's private data structure.
+
A driver needs to provide a dev_node_t structure for each device
on a card. In some cases, there is only one device per card (for
example, ethernet cards, modems). In other cases, there may be
@@ -130,16 +152,18 @@ typedef struct local_info_t {
======================================================================*/
-static int teles_attach(struct pcmcia_device *p_dev)
+static dev_link_t *teles_attach(void)
{
+ client_reg_t client_reg;
dev_link_t *link;
local_info_t *local;
+ int ret;
DEBUG(0, "teles_attach()\n");
/* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
- if (!local) return -ENOMEM;
+ if (!local) return NULL;
memset(local, 0, sizeof(local_info_t));
local->cardnr = -1;
link = &local->link; link->priv = local;
@@ -164,13 +188,20 @@ static int teles_attach(struct pcmcia_device *p_dev)
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- teles_cs_config(link);
+ /* Register with Card Services */
+ link->next = dev_list;
+ dev_list = link;
+ client_reg.dev_info = &dev_info;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+ ret = pcmcia_register_client(&link->handle, &client_reg);
+ if (ret != CS_SUCCESS) {
+ cs_error(link->handle, RegisterClient, ret);
+ teles_detach(link);
+ return NULL;
+ }
- return 0;
+ return link;
} /* teles_attach */
/*======================================================================
@@ -182,18 +213,32 @@ static int teles_attach(struct pcmcia_device *p_dev)
======================================================================*/
-static void teles_detach(struct pcmcia_device *p_dev)
+static void teles_detach(dev_link_t *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
+ dev_link_t **linkp;
local_info_t *info = link->priv;
+ int ret;
DEBUG(0, "teles_detach(0x%p)\n", link);
- if (link->state & DEV_CONFIG) {
- info->busy = 1;
- teles_cs_release(link);
+ /* Locate device structure */
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link) break;
+ if (*linkp == NULL)
+ return;
+
+ if (link->state & DEV_CONFIG)
+ teles_cs_release(link);
+
+ /* Break the link with Card Services */
+ if (link->handle) {
+ ret = pcmcia_deregister_client(link->handle);
+ if (ret != CS_SUCCESS)
+ cs_error(link->handle, DeregisterClient, ret);
}
+ /* Unlink device structure and free it */
+ *linkp = link->next;
kfree(info);
} /* teles_detach */
@@ -383,32 +428,60 @@ static void teles_cs_release(dev_link_t *link)
link->state &= ~DEV_CONFIG;
} /* teles_cs_release */
-static int teles_suspend(struct pcmcia_device *p_dev)
-{
- dev_link_t *link = dev_to_instance(p_dev);
- local_info_t *dev = link->priv;
+/*======================================================================
- link->state |= DEV_SUSPEND;
- dev->busy = 1;
- if (link->state & DEV_CONFIG)
- pcmcia_release_configuration(link->handle);
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received. A CARD_REMOVAL event
+ also sets some flags to discourage the net drivers from trying
+ to talk to the card any more.
- return 0;
-}
+ When a CARD_REMOVAL event is received, we immediately set a flag
+ to block future accesses to this device. All the functions that
+ actually access the device should check this flag to make sure
+ the card is still present.
-static int teles_resume(struct pcmcia_device *p_dev)
-{
- dev_link_t *link = dev_to_instance(p_dev);
- local_info_t *dev = link->priv;
+======================================================================*/
- link->state &= ~DEV_SUSPEND;
- if (link->state & DEV_CONFIG)
- pcmcia_request_configuration(link->handle, &link->conf);
- dev->busy = 0;
+static int teles_cs_event(event_t event, int priority,
+ event_callback_args_t *args)
+{
+ dev_link_t *link = args->client_data;
+ local_info_t *dev = link->priv;
- return 0;
-}
+ DEBUG(1, "teles_cs_event(%d)\n", event);
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG) {
+ ((local_info_t*)link->priv)->busy = 1;
+ teles_cs_release(link);
+ }
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ teles_cs_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ /* Mark the device as stopped, to block IO until later */
+ dev->busy = 1;
+ if (link->state & DEV_CONFIG)
+ pcmcia_release_configuration(link->handle);
+ break;
+ case CS_EVENT_PM_RESUME:
+ link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
+ if (link->state & DEV_CONFIG)
+ pcmcia_request_configuration(link->handle, &link->conf);
+ dev->busy = 0;
+ break;
+ }
+ return 0;
+} /* teles_cs_event */
static struct pcmcia_device_id teles_ids[] = {
PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119),
@@ -421,11 +494,10 @@ static struct pcmcia_driver teles_cs_driver = {
.drv = {
.name = "teles_cs",
},
- .probe = teles_attach,
- .remove = teles_detach,
+ .attach = teles_attach,
+ .event = teles_cs_event,
+ .detach = teles_detach,
.id_table = teles_ids,
- .suspend = teles_suspend,
- .resume = teles_resume,
};
static int __init init_teles_cs(void)
@@ -436,6 +508,7 @@ static int __init init_teles_cs(void)
static void __exit exit_teles_cs(void)
{
pcmcia_unregister_driver(&teles_cs_driver);
+ BUG_ON(dev_list != NULL);
}
module_init(init_teles_cs);
diff --git a/trunk/drivers/macintosh/macio_asic.c b/trunk/drivers/macintosh/macio_asic.c
index 228e1852a836..c34c96d18907 100644
--- a/trunk/drivers/macintosh/macio_asic.c
+++ b/trunk/drivers/macintosh/macio_asic.c
@@ -128,7 +128,7 @@ static int macio_device_resume(struct device * dev)
return 0;
}
-static int macio_uevent(struct device *dev, char **envp, int num_envp,
+static int macio_hotplug (struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
struct macio_dev * macio_dev;
@@ -203,7 +203,7 @@ extern struct device_attribute macio_dev_attrs[];
struct bus_type macio_bus_type = {
.name = "macio",
.match = macio_bus_match,
- .uevent = macio_uevent,
+ .hotplug = macio_hotplug,
.suspend = macio_device_suspend,
.resume = macio_device_resume,
.dev_attrs = macio_dev_attrs,
diff --git a/trunk/drivers/md/.gitignore b/trunk/drivers/md/.gitignore
deleted file mode 100644
index a7afec6b19c6..000000000000
--- a/trunk/drivers/md/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-mktables
-raid6altivec*.c
-raid6int*.c
-raid6tables.c
diff --git a/trunk/drivers/md/dm-table.c b/trunk/drivers/md/dm-table.c
index a6f2dc66c3db..a6d3baa46f61 100644
--- a/trunk/drivers/md/dm-table.c
+++ b/trunk/drivers/md/dm-table.c
@@ -638,7 +638,7 @@ int dm_split_args(int *argc, char ***argvp, char *input)
static void check_for_valid_limits(struct io_restrictions *rs)
{
if (!rs->max_sectors)
- rs->max_sectors = SAFE_MAX_SECTORS;
+ rs->max_sectors = MAX_SECTORS;
if (!rs->max_phys_segments)
rs->max_phys_segments = MAX_PHYS_SEGMENTS;
if (!rs->max_hw_segments)
diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-usb.c b/trunk/drivers/media/dvb/b2c2/flexcop-usb.c
index a6c91db40ad6..0a78ba3737a5 100644
--- a/trunk/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/trunk/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -544,6 +544,7 @@ static struct usb_device_id flexcop_usb_table [] = {
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver flexcop_usb_driver = {
+ .owner = THIS_MODULE,
.name = "b2c2_flexcop_usb",
.probe = flexcop_usb_probe,
.disconnect = flexcop_usb_disconnect,
diff --git a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c
index b996fb59b7e4..336fc284fa52 100644
--- a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -986,6 +986,7 @@ static const struct usb_device_id cinergyt2_table [] __devinitdata = {
MODULE_DEVICE_TABLE(usb, cinergyt2_table);
static struct usb_driver cinergyt2_driver = {
+ .owner = THIS_MODULE,
.name = "cinergyT2",
.probe = cinergyt2_probe,
.disconnect = cinergyt2_disconnect,
diff --git a/trunk/drivers/media/dvb/dvb-usb/a800.c b/trunk/drivers/media/dvb/dvb-usb/a800.c
index ce44aa6bbb83..8c7beffb045f 100644
--- a/trunk/drivers/media/dvb/dvb-usb/a800.c
+++ b/trunk/drivers/media/dvb/dvb-usb/a800.c
@@ -144,6 +144,7 @@ static struct dvb_usb_properties a800_properties = {
};
static struct usb_driver a800_driver = {
+ .owner = THIS_MODULE,
.name = "dvb_usb_a800",
.probe = a800_probe,
.disconnect = dvb_usb_device_exit,
diff --git a/trunk/drivers/media/dvb/dvb-usb/cxusb.c b/trunk/drivers/media/dvb/dvb-usb/cxusb.c
index d05fab01cccd..3fe383f4bb4c 100644
--- a/trunk/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/trunk/drivers/media/dvb/dvb-usb/cxusb.c
@@ -241,6 +241,7 @@ static struct dvb_usb_properties cxusb_properties = {
};
static struct usb_driver cxusb_driver = {
+ .owner = THIS_MODULE,
.name = "dvb_usb_cxusb",
.probe = cxusb_probe,
.disconnect = dvb_usb_device_exit,
diff --git a/trunk/drivers/media/dvb/dvb-usb/dibusb-mb.c b/trunk/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 52ac3e5adf5d..aa271a2496d5 100644
--- a/trunk/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/trunk/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -373,6 +373,7 @@ static struct dvb_usb_properties artec_t1_usb2_properties = {
};
static struct usb_driver dibusb_driver = {
+ .owner = THIS_MODULE,
.name = "dvb_usb_dibusb_mb",
.probe = dibusb_probe,
.disconnect = dvb_usb_device_exit,
diff --git a/trunk/drivers/media/dvb/dvb-usb/dibusb-mc.c b/trunk/drivers/media/dvb/dvb-usb/dibusb-mc.c
index 55802fba3c29..6a0912eab396 100644
--- a/trunk/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/trunk/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -82,6 +82,7 @@ static struct dvb_usb_properties dibusb_mc_properties = {
};
static struct usb_driver dibusb_mc_driver = {
+ .owner = THIS_MODULE,
.name = "dvb_usb_dibusb_mc",
.probe = dibusb_mc_probe,
.disconnect = dvb_usb_device_exit,
diff --git a/trunk/drivers/media/dvb/dvb-usb/digitv.c b/trunk/drivers/media/dvb/dvb-usb/digitv.c
index 450417a9e64b..f98e306a5759 100644
--- a/trunk/drivers/media/dvb/dvb-usb/digitv.c
+++ b/trunk/drivers/media/dvb/dvb-usb/digitv.c
@@ -233,6 +233,7 @@ static struct dvb_usb_properties digitv_properties = {
};
static struct usb_driver digitv_driver = {
+ .owner = THIS_MODULE,
.name = "dvb_usb_digitv",
.probe = digitv_probe,
.disconnect = dvb_usb_device_exit,
diff --git a/trunk/drivers/media/dvb/dvb-usb/dtt200u.c b/trunk/drivers/media/dvb/dvb-usb/dtt200u.c
index 6e2bac873445..b595476332cd 100644
--- a/trunk/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/trunk/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -198,6 +198,7 @@ static struct dvb_usb_properties wt220u_properties = {
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver dtt200u_usb_driver = {
+ .owner = THIS_MODULE,
.name = "dvb_usb_dtt200u",
.probe = dtt200u_usb_probe,
.disconnect = dvb_usb_device_exit,
diff --git a/trunk/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/trunk/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index fac48fc7a4ac..1841a66427bf 100644
--- a/trunk/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/trunk/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -202,6 +202,7 @@ static struct dvb_usb_properties nova_t_properties = {
};
static struct usb_driver nova_t_driver = {
+ .owner = THIS_MODULE,
.name = "dvb_usb_nova_t_usb2",
.probe = nova_t_probe,
.disconnect = dvb_usb_device_exit,
diff --git a/trunk/drivers/media/dvb/dvb-usb/umt-010.c b/trunk/drivers/media/dvb/dvb-usb/umt-010.c
index 14f1911c79bb..6fd67657c269 100644
--- a/trunk/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/trunk/drivers/media/dvb/dvb-usb/umt-010.c
@@ -128,6 +128,7 @@ static struct dvb_usb_properties umt_properties = {
};
static struct usb_driver umt_driver = {
+ .owner = THIS_MODULE,
.name = "dvb_usb_umt_010",
.probe = umt_probe,
.disconnect = dvb_usb_device_exit,
diff --git a/trunk/drivers/media/dvb/dvb-usb/vp702x.c b/trunk/drivers/media/dvb/dvb-usb/vp702x.c
index afa00fdb5ec0..de13c04e8e64 100644
--- a/trunk/drivers/media/dvb/dvb-usb/vp702x.c
+++ b/trunk/drivers/media/dvb/dvb-usb/vp702x.c
@@ -256,6 +256,7 @@ static struct dvb_usb_properties vp702x_properties = {
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver vp702x_usb_driver = {
+ .owner = THIS_MODULE,
.name = "dvb-usb-vp702x",
.probe = vp702x_usb_probe,
.disconnect = dvb_usb_device_exit,
diff --git a/trunk/drivers/media/dvb/dvb-usb/vp7045.c b/trunk/drivers/media/dvb/dvb-usb/vp7045.c
index 3835235b68df..75765e3a569c 100644
--- a/trunk/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/trunk/drivers/media/dvb/dvb-usb/vp7045.c
@@ -253,6 +253,7 @@ static struct dvb_usb_properties vp7045_properties = {
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver vp7045_usb_driver = {
+ .owner = THIS_MODULE,
.name = "dvb_usb_vp7045",
.probe = vp7045_usb_probe,
.disconnect = dvb_usb_device_exit,
diff --git a/trunk/drivers/media/video/cpia_usb.c b/trunk/drivers/media/video/cpia_usb.c
index 1439cb752874..9774e94d1e7d 100644
--- a/trunk/drivers/media/video/cpia_usb.c
+++ b/trunk/drivers/media/video/cpia_usb.c
@@ -582,6 +582,7 @@ MODULE_LICENSE("GPL");
static struct usb_driver cpia_driver = {
+ .owner = THIS_MODULE,
.name = "cpia",
.probe = cpia_probe,
.disconnect = cpia_disconnect,
diff --git a/trunk/drivers/media/video/em28xx/em28xx-video.c b/trunk/drivers/media/video/em28xx/em28xx-video.c
index 3a56120397ae..06d76879bde2 100644
--- a/trunk/drivers/media/video/em28xx/em28xx-video.c
+++ b/trunk/drivers/media/video/em28xx/em28xx-video.c
@@ -1884,6 +1884,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
}
static struct usb_driver em28xx_usb_driver = {
+ .owner = THIS_MODULE,
.name = "em28xx",
.probe = em28xx_usb_probe,
.disconnect = em28xx_usb_disconnect,
diff --git a/trunk/drivers/message/fusion/mptbase.c b/trunk/drivers/message/fusion/mptbase.c
index 537836068c49..4262a22adc22 100644
--- a/trunk/drivers/message/fusion/mptbase.c
+++ b/trunk/drivers/message/fusion/mptbase.c
@@ -313,13 +313,13 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa)
u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
if (ioc->bus_type == FC)
mpt_fc_log_info(ioc, log_info);
- else if (ioc->bus_type == SPI)
+ else if (ioc->bus_type == SCSI)
mpt_sp_log_info(ioc, log_info);
else if (ioc->bus_type == SAS)
mpt_sas_log_info(ioc, log_info);
}
if (ioc_stat & MPI_IOCSTATUS_MASK) {
- if (ioc->bus_type == SPI &&
+ if (ioc->bus_type == SCSI &&
cb_idx != mpt_stm_index &&
cb_idx != mpt_lan_index)
mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
@@ -1376,7 +1376,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
ioc->prod_name = "LSI53C1030";
- ioc->bus_type = SPI;
+ ioc->bus_type = SCSI;
/* 1030 Chip Fix. Disable Split transactions
* for PCIX. Set MOST bits to zero if Rev < C0( = 8).
*/
@@ -1389,7 +1389,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
ioc->prod_name = "LSI53C1035";
- ioc->bus_type = SPI;
+ ioc->bus_type = SCSI;
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
ioc->prod_name = "LSISAS1064";
@@ -3042,7 +3042,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
/* Clear the internal flash bad bit - autoincrementing register,
* so must do two writes.
*/
- if (ioc->bus_type == SPI) {
+ if (ioc->bus_type == SCSI) {
/*
* 1030 and 1035 H/W errata, workaround to access
* the ClearFlashBadSignatureBit
@@ -3152,7 +3152,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
int cnt,cntdn;
dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
- if (ioc->bus_type == SPI) {
+ if (ioc->bus_type == SCSI) {
/* Always issue a Msg Unit Reset first. This will clear some
* SCSI bus hang conditions.
*/
@@ -3580,7 +3580,7 @@ initChainBuffers(MPT_ADAPTER *ioc)
dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
ioc->name, numSGE, num_sge, num_chain));
- if (ioc->bus_type == SPI)
+ if (ioc->bus_type == SCSI)
num_chain *= MPT_SCSI_CAN_QUEUE;
else
num_chain *= MPT_FC_CAN_QUEUE;
diff --git a/trunk/drivers/message/fusion/mptbase.h b/trunk/drivers/message/fusion/mptbase.h
index 6c48d1f54ac9..bac8eb4186d2 100644
--- a/trunk/drivers/message/fusion/mptbase.h
+++ b/trunk/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
#endif
-#define MPT_LINUX_VERSION_COMMON "3.03.05"
-#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.05"
+#define MPT_LINUX_VERSION_COMMON "3.03.04"
+#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.04"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
@@ -321,7 +321,7 @@ typedef struct _SYSIF_REGS
* Dynamic Multi-Pathing specific stuff...
*/
-/* VirtTarget negoFlags field */
+/* VirtDevice negoFlags field */
#define MPT_TARGET_NO_NEGO_WIDE 0x01
#define MPT_TARGET_NO_NEGO_SYNC 0x02
#define MPT_TARGET_NO_NEGO_QAS 0x04
@@ -330,7 +330,8 @@ typedef struct _SYSIF_REGS
/*
* VirtDevice - FC LUN device or SCSI target device
*/
-typedef struct _VirtTarget {
+typedef struct _VirtDevice {
+ struct scsi_device *device;
u8 tflags;
u8 ioc_id;
u8 target_id;
@@ -341,18 +342,21 @@ typedef struct _VirtTarget {
u8 negoFlags; /* bit field, see above */
u8 raidVolume; /* set, if RAID Volume */
u8 type; /* byte 0 of Inquiry data */
+ u8 cflags; /* controller flags */
+ u8 rsvd1raid;
+ u16 fc_phys_lun;
+ u16 fc_xlat_lun;
u32 num_luns;
u32 luns[8]; /* Max LUNs is 256 */
+ u8 pad[4];
u8 inq_data[8];
-} VirtTarget;
-
-typedef struct _VirtDevice {
- VirtTarget *vtarget;
- u8 ioc_id;
- u8 bus_id;
- u8 target_id;
- u8 configured_lun;
- u32 lun;
+ /* IEEE Registered Extended Identifier
+ obtained via INQUIRY VPD page 0x83 */
+ /* NOTE: Do not separate uniq_prepad and uniq_data
+ as they are treateed as a single entity in the code */
+ u8 uniq_prepad[8];
+ u8 uniq_data[20];
+ u8 pad2[4];
} VirtDevice;
/*
@@ -899,7 +903,7 @@ typedef struct _MPT_LOCAL_REPLY {
typedef enum {
FC,
- SPI,
+ SCSI,
SAS
} BUS_TYPE;
@@ -908,7 +912,7 @@ typedef struct _MPT_SCSI_HOST {
int port;
u32 pad0;
struct scsi_cmnd **ScsiLookup;
- VirtTarget **Targets;
+ VirtDevice **Targets;
MPT_LOCAL_REPLY *pLocal; /* used for internal commands */
struct timer_list timer;
/* Pool of memory for holding SCpnts before doing
diff --git a/trunk/drivers/message/fusion/mptctl.c b/trunk/drivers/message/fusion/mptctl.c
index 959d2c5951b8..602138f8544d 100644
--- a/trunk/drivers/message/fusion/mptctl.c
+++ b/trunk/drivers/message/fusion/mptctl.c
@@ -1245,7 +1245,7 @@ mptctl_gettargetinfo (unsigned long arg)
MPT_ADAPTER *ioc;
struct Scsi_Host *sh;
MPT_SCSI_HOST *hd;
- VirtTarget *vdev;
+ VirtDevice *vdev;
char *pmem;
int *pdata;
IOCPage2_t *pIoc2;
@@ -1822,7 +1822,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
case MPI_FUNCTION_SCSI_IO_REQUEST:
if (ioc->sh) {
SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
- VirtTarget *pTarget = NULL;
+ VirtDevice *pTarget = NULL;
MPT_SCSI_HOST *hd = NULL;
int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
int scsidir = 0;
diff --git a/trunk/drivers/message/fusion/mptfc.c b/trunk/drivers/message/fusion/mptfc.c
index ba61e1828858..a628be9bbbad 100644
--- a/trunk/drivers/message/fusion/mptfc.c
+++ b/trunk/drivers/message/fusion/mptfc.c
@@ -84,16 +84,13 @@ static int mptfcTaskCtx = -1;
static int mptfcInternalCtx = -1; /* Used only for internal commands */
static struct scsi_host_template mptfc_driver_template = {
- .module = THIS_MODULE,
.proc_name = "mptfc",
.proc_info = mptscsih_proc_info,
.name = "MPT FC Host",
.info = mptscsih_info,
.queuecommand = mptscsih_qcmd,
- .target_alloc = mptscsih_target_alloc,
.slave_alloc = mptscsih_slave_alloc,
.slave_configure = mptscsih_slave_configure,
- .target_destroy = mptscsih_target_destroy,
.slave_destroy = mptscsih_slave_destroy,
.change_queue_depth = mptscsih_change_queue_depth,
.eh_abort_handler = mptscsih_abort,
@@ -170,15 +167,13 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Skipping because it's not operational!\n",
ioc->name);
- error = -ENODEV;
- goto out_mptfc_probe;
+ return -ENODEV;
}
if (!ioc->active) {
printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
ioc->name);
- error = -ENODEV;
- goto out_mptfc_probe;
+ return -ENODEV;
}
/* Sanity check - ensure at least 1 port is INITIATOR capable
@@ -203,8 +198,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Unable to register controller with SCSI subsystem\n",
ioc->name);
- error = -1;
- goto out_mptfc_probe;
+ return -1;
}
spin_lock_irqsave(&ioc->FreeQlock, flags);
@@ -272,7 +266,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL) {
error = -ENOMEM;
- goto out_mptfc_probe;
+ goto mptfc_probe_failed;
}
memset(mem, 0, sz);
@@ -290,14 +284,14 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL) {
error = -ENOMEM;
- goto out_mptfc_probe;
+ goto mptfc_probe_failed;
}
memset(mem, 0, sz);
- hd->Targets = (VirtTarget **) mem;
+ hd->Targets = (VirtDevice **) mem;
dprintk((KERN_INFO
- " vdev @ %p, sz=%d\n", hd->Targets, sz));
+ " Targets @ %p, sz=%d\n", hd->Targets, sz));
/* Clear the TM flags
*/
@@ -336,13 +330,13 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if(error) {
dprintk((KERN_ERR MYNAM
"scsi_add_host failed\n"));
- goto out_mptfc_probe;
+ goto mptfc_probe_failed;
}
scsi_scan_host(sh);
return 0;
-out_mptfc_probe:
+mptfc_probe_failed:
mptscsih_remove(pdev);
return error;
diff --git a/trunk/drivers/message/fusion/mptsas.c b/trunk/drivers/message/fusion/mptsas.c
index 17e9757e728b..e0a8bb8ba7d8 100644
--- a/trunk/drivers/message/fusion/mptsas.c
+++ b/trunk/drivers/message/fusion/mptsas.c
@@ -228,35 +228,31 @@ static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
* implement ->target_alloc.
*/
static int
-mptsas_slave_alloc(struct scsi_device *sdev)
+mptsas_slave_alloc(struct scsi_device *device)
{
- struct Scsi_Host *host = sdev->host;
+ struct Scsi_Host *host = device->host;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
struct sas_rphy *rphy;
struct mptsas_portinfo *p;
- VirtTarget *vtarget;
VirtDevice *vdev;
- struct scsi_target *starget;
+ uint target = device->id;
int i;
+ if ((vdev = hd->Targets[target]) != NULL)
+ goto out;
+
vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
if (!vdev) {
printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
hd->ioc->name, sizeof(VirtDevice));
return -ENOMEM;
}
+
memset(vdev, 0, sizeof(VirtDevice));
+ vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
vdev->ioc_id = hd->ioc->id;
- sdev->hostdata = vdev;
- starget = scsi_target(sdev);
- vtarget = starget->hostdata;
- vdev->vtarget = vtarget;
- if (vtarget->num_luns == 0) {
- vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
- hd->Targets[sdev->id] = vtarget;
- }
- rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
+ rphy = dev_to_rphy(device->sdev_target->dev.parent);
list_for_each_entry(p, &hd->ioc->sas_topology, list) {
for (i = 0; i < p->num_phys; i++) {
if (p->phy_info[i].attached.sas_address ==
@@ -264,7 +260,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
vdev->target_id =
p->phy_info[i].attached.target;
vdev->bus_id = p->phy_info[i].attached.bus;
- vdev->lun = sdev->lun;
+ hd->Targets[device->id] = vdev;
goto out;
}
}
@@ -275,24 +271,19 @@ mptsas_slave_alloc(struct scsi_device *sdev)
return -ENODEV;
out:
- vtarget->ioc_id = vdev->ioc_id;
- vtarget->target_id = vdev->target_id;
- vtarget->bus_id = vdev->bus_id;
- vtarget->num_luns++;
+ vdev->num_luns++;
+ device->hostdata = vdev;
return 0;
}
static struct scsi_host_template mptsas_driver_template = {
- .module = THIS_MODULE,
.proc_name = "mptsas",
.proc_info = mptscsih_proc_info,
.name = "MPT SPI Host",
.info = mptscsih_info,
.queuecommand = mptscsih_qcmd,
- .target_alloc = mptscsih_target_alloc,
.slave_alloc = mptsas_slave_alloc,
.slave_configure = mptscsih_slave_configure,
- .target_destroy = mptscsih_target_destroy,
.slave_destroy = mptscsih_slave_destroy,
.change_queue_depth = mptscsih_change_queue_depth,
.eh_abort_handler = mptscsih_abort,
@@ -995,6 +986,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
goto out_free_port_info;
list_add_tail(&port_info->list, &ioc->sas_topology);
+
for (i = 0; i < port_info->num_phys; i++) {
mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
(MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
@@ -1141,15 +1133,13 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Skipping because it's not operational!\n",
ioc->name);
- error = -ENODEV;
- goto out_mptsas_probe;
+ return -ENODEV;
}
if (!ioc->active) {
printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
ioc->name);
- error = -ENODEV;
- goto out_mptsas_probe;
+ return -ENODEV;
}
/* Sanity check - ensure at least 1 port is INITIATOR capable
@@ -1173,8 +1163,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Unable to register controller with SCSI subsystem\n",
ioc->name);
- error = -1;
- goto out_mptsas_probe;
+ return -1;
}
spin_lock_irqsave(&ioc->FreeQlock, flags);
@@ -1248,7 +1237,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL) {
error = -ENOMEM;
- goto out_mptsas_probe;
+ goto mptsas_probe_failed;
}
memset(mem, 0, sz);
@@ -1266,14 +1255,14 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL) {
error = -ENOMEM;
- goto out_mptsas_probe;
+ goto mptsas_probe_failed;
}
memset(mem, 0, sz);
- hd->Targets = (VirtTarget **) mem;
+ hd->Targets = (VirtDevice **) mem;
dprintk((KERN_INFO
- " vtarget @ %p, sz=%d\n", hd->Targets, sz));
+ " Targets @ %p, sz=%d\n", hd->Targets, sz));
/* Clear the TM flags
*/
@@ -1319,14 +1308,14 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (error) {
dprintk((KERN_ERR MYNAM
"scsi_add_host failed\n"));
- goto out_mptsas_probe;
+ goto mptsas_probe_failed;
}
mptsas_scan_sas_topology(ioc);
return 0;
-out_mptsas_probe:
+mptsas_probe_failed:
mptscsih_remove(pdev);
return error;
diff --git a/trunk/drivers/message/fusion/mptscsih.c b/trunk/drivers/message/fusion/mptscsih.c
index 93a16fa3c4ba..b7b9846ff3fd 100644
--- a/trunk/drivers/message/fusion/mptscsih.c
+++ b/trunk/drivers/message/fusion/mptscsih.c
@@ -150,29 +150,28 @@ static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 tar
int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
-static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen);
-static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, char byte56);
+static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
+static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
+static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
-static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
+static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
-static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
-static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget);
-static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
+static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
static struct work_struct mptscsih_persistTask;
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
static void mptscsih_domainValidation(void *hd);
+static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
-static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
#endif
void mptscsih_remove(struct pci_dev *);
@@ -628,7 +627,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
"IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
"resid=%d bufflen=%d xfer_cnt=%d\n",
- ioc->id, sc->device->id, sc->device->lun,
+ ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
status, scsi_state, scsi_status, sc->resid,
sc->request_bufflen, xfer_cnt));
@@ -642,7 +641,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
pScsiReply->ResponseInfo) {
printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
"FCP_ResponseInfo=%08xh\n",
- ioc->id, sc->device->id, sc->device->lun,
+ ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
le32_to_cpu(pScsiReply->ResponseInfo));
}
@@ -678,8 +677,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
sc->result = DID_RESET << 16;
/* GEM Workaround. */
- if (ioc->bus_type == SPI)
- mptscsih_no_negotiate(hd, sc);
+ if (ioc->bus_type == SCSI)
+ mptscsih_no_negotiate(hd, sc->device->id);
break;
case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
@@ -893,15 +892,16 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
* when a lun is disable by mid-layer.
* Do NOT access the referenced scsi_cmnd structure or
* members. Will cause either a paging or NULL ptr error.
- * @hd: Pointer to a SCSI HOST structure
- * @vdevice: per device private data
+ * @hd: Pointer to a SCSI HOST structure
+ * @target: target id
+ * @lun: lun
*
* Returns: None.
*
* Called from slave_destroy.
*/
static void
-mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
+mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
{
SCSIIORequest_t *mf = NULL;
int ii;
@@ -909,7 +909,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
struct scsi_cmnd *sc;
dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
- vdevice->target_id, vdevice->lun, max));
+ target, lun, max));
for (ii=0; ii < max; ii++) {
if ((sc = hd->ScsiLookup[ii]) != NULL) {
@@ -919,7 +919,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
- if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
+ if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
continue;
/* Cleanup
@@ -993,10 +993,8 @@ mptscsih_remove(struct pci_dev *pdev)
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
struct Scsi_Host *host = ioc->sh;
MPT_SCSI_HOST *hd;
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
int count;
unsigned long flags;
-#endif
int sz1;
if(!host) {
@@ -1077,6 +1075,11 @@ mptscsih_shutdown(struct pci_dev *pdev)
hd = (MPT_SCSI_HOST *)host->hostdata;
+ /* Flush the cache of this adapter
+ */
+ if(hd != NULL)
+ mptscsih_synchronize_cache(hd, 0);
+
}
#ifdef CONFIG_PM
@@ -1283,7 +1286,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
MPT_SCSI_HOST *hd;
MPT_FRAME_HDR *mf;
SCSIIORequest_t *pScsiReq;
- VirtDevice *vdev = SCpnt->device->hostdata;
+ VirtDevice *pTarget = SCpnt->device->hostdata;
int lun;
u32 datalen;
u32 scsictl;
@@ -1338,8 +1341,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Default to untagged. Once a target structure has been allocated,
* use the Inquiry data to determine if device supports tagged.
*/
- if (vdev
- && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
+ if (pTarget
+ && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
&& (SCpnt->device->tagged_supported)) {
scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
} else {
@@ -1348,8 +1351,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Use the above information to set up the message frame
*/
- pScsiReq->TargetID = (u8) vdev->target_id;
- pScsiReq->Bus = vdev->bus_id;
+ pScsiReq->TargetID = (u8) pTarget->target_id;
+ pScsiReq->Bus = pTarget->bus_id;
pScsiReq->ChainOffset = 0;
pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
pScsiReq->CDBLength = SCpnt->cmd_len;
@@ -1400,8 +1403,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
SCpnt->host_scribble = NULL;
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
- if (hd->ioc->bus_type == SPI) {
- int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id];
+ if (hd->ioc->bus_type == SCSI) {
+ int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id];
int issueCmd = 1;
if (dvStatus || hd->ioc->spi_data.forceDv) {
@@ -1434,7 +1437,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Set the DV flags.
*/
if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
- mptscsih_set_dvflags(hd, SCpnt);
+ mptscsih_set_dvflags(hd, pScsiReq);
if (!issueCmd)
goto fail;
@@ -1738,7 +1741,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
u32 ctx2abort;
int scpnt_idx;
int retval;
- VirtDevice *vdev;
/* If we can't locate our host adapter structure, return FAILED status.
*/
@@ -1788,9 +1790,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
hd->abortSCpnt = SCpnt;
- vdev = SCpnt->device->hostdata;
retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
- vdev->bus_id, vdev->target_id, vdev->lun,
+ SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
ctx2abort, 2 /* 2 second timeout */);
printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
@@ -1821,7 +1822,6 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
int retval;
- VirtDevice *vdev;
/* If we can't locate our host adapter structure, return FAILED status.
*/
@@ -1839,9 +1839,8 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
hd->ioc->name, SCpnt);
scsi_print_command(SCpnt);
- vdev = SCpnt->device->hostdata;
retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
- vdev->bus_id, vdev->target_id,
+ SCpnt->device->channel, SCpnt->device->id,
0, 0, 5 /* 5 second timeout */);
printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
@@ -1872,7 +1871,6 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
int retval;
- VirtDevice *vdev;
/* If we can't locate our host adapter structure, return FAILED status.
*/
@@ -1890,9 +1888,8 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
if (hd->timeouts < -1)
hd->timeouts++;
- vdev = SCpnt->device->hostdata;
retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
- vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */);
+ SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */);
printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
hd->ioc->name,
@@ -2151,39 +2148,26 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
return 0;
}
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * OS entry point to allow host driver to alloc memory
- * for each scsi target. Called once per device the bus scan.
- * Return non-zero if allocation fails.
- */
-int
-mptscsih_target_alloc(struct scsi_target *starget)
-{
- VirtTarget *vtarget;
-
- vtarget = kmalloc(sizeof(VirtTarget), GFP_KERNEL);
- if (!vtarget)
- return -ENOMEM;
- memset(vtarget, 0, sizeof(VirtTarget));
- starget->hostdata = vtarget;
- return 0;
-}
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* OS entry point to allow host driver to alloc memory
* for each scsi device. Called once per device the bus scan.
* Return non-zero if allocation fails.
+ * Init memory once per id (not LUN).
*/
int
-mptscsih_slave_alloc(struct scsi_device *sdev)
+mptscsih_slave_alloc(struct scsi_device *device)
{
- struct Scsi_Host *host = sdev->host;
+ struct Scsi_Host *host = device->host;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
- VirtTarget *vtarget;
VirtDevice *vdev;
- struct scsi_target *starget;
+ uint target = device->id;
+
+ if (hd == NULL)
+ return -ENODEV;
+
+ if ((vdev = hd->Targets[target]) != NULL)
+ goto out;
vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
if (!vdev) {
@@ -2193,46 +2177,26 @@ mptscsih_slave_alloc(struct scsi_device *sdev)
}
memset(vdev, 0, sizeof(VirtDevice));
+ vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
vdev->ioc_id = hd->ioc->id;
- vdev->target_id = sdev->id;
- vdev->bus_id = sdev->channel;
- vdev->lun = sdev->lun;
- sdev->hostdata = vdev;
-
- starget = scsi_target(sdev);
- vtarget = starget->hostdata;
- vdev->vtarget = vtarget;
-
- if (vtarget->num_luns == 0) {
- hd->Targets[sdev->id] = vtarget;
- vtarget->ioc_id = hd->ioc->id;
- vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
- vtarget->target_id = sdev->id;
- vtarget->bus_id = sdev->channel;
- if (hd->ioc->bus_type == SPI) {
- if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
- vtarget->raidVolume = 1;
- ddvtprintk((KERN_INFO
- "RAID Volume @ id %d\n", sdev->id));
- }
- } else {
- vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
+ vdev->target_id = device->id;
+ vdev->bus_id = device->channel;
+ vdev->raidVolume = 0;
+ hd->Targets[device->id] = vdev;
+ if (hd->ioc->bus_type == SCSI) {
+ if (hd->ioc->raid_data.isRaid & (1 << device->id)) {
+ vdev->raidVolume = 1;
+ ddvtprintk((KERN_INFO
+ "RAID Volume @ id %d\n", device->id));
}
+ } else {
+ vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
}
- vtarget->num_luns++;
- return 0;
-}
-/*
- * OS entry point to allow for host driver to free allocated memory
- * Called if no device present or device being unloaded
- */
-void
-mptscsih_target_destroy(struct scsi_target *starget)
-{
- if (starget->hostdata)
- kfree(starget->hostdata);
- starget->hostdata = NULL;
+ out:
+ vdev->num_luns++;
+ device->hostdata = vdev;
+ return 0;
}
/*
@@ -2240,40 +2204,40 @@ mptscsih_target_destroy(struct scsi_target *starget)
* Called if no device present or device being unloaded
*/
void
-mptscsih_slave_destroy(struct scsi_device *sdev)
+mptscsih_slave_destroy(struct scsi_device *device)
{
- struct Scsi_Host *host = sdev->host;
+ struct Scsi_Host *host = device->host;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
- VirtTarget *vtarget;
- VirtDevice *vdevice;
- struct scsi_target *starget;
-
- starget = scsi_target(sdev);
- vtarget = starget->hostdata;
- vdevice = sdev->hostdata;
-
- mptscsih_search_running_cmds(hd, vdevice);
- vtarget->luns[0] &= ~(1 << vdevice->lun);
- vtarget->num_luns--;
- if (vtarget->num_luns == 0) {
- mptscsih_negotiate_to_asyn_narrow(hd, vtarget);
- if (hd->ioc->bus_type == SPI) {
- if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
- hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
- } else {
- hd->ioc->spi_data.dvStatus[vtarget->target_id] =
- MPT_SCSICFG_NEGOTIATE;
- if (!hd->negoNvram) {
- hd->ioc->spi_data.dvStatus[vtarget->target_id] |=
- MPT_SCSICFG_DV_NOT_DONE;
- }
+ VirtDevice *vdev;
+ uint target = device->id;
+ uint lun = device->lun;
+
+ if (hd == NULL)
+ return;
+
+ mptscsih_search_running_cmds(hd, target, lun);
+
+ vdev = hd->Targets[target];
+ vdev->luns[0] &= ~(1 << lun);
+ if (--vdev->num_luns)
+ return;
+
+ kfree(hd->Targets[target]);
+ hd->Targets[target] = NULL;
+
+ if (hd->ioc->bus_type == SCSI) {
+ if (mptscsih_is_phys_disk(hd->ioc, target)) {
+ hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
+ } else {
+ hd->ioc->spi_data.dvStatus[target] =
+ MPT_SCSICFG_NEGOTIATE;
+
+ if (!hd->negoNvram) {
+ hd->ioc->spi_data.dvStatus[target] |=
+ MPT_SCSICFG_DV_NOT_DONE;
}
}
- hd->Targets[sdev->id] = NULL;
}
- mptscsih_synchronize_cache(hd, vdevice);
- kfree(vdevice);
- sdev->hostdata = NULL;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2287,21 +2251,22 @@ mptscsih_slave_destroy(struct scsi_device *sdev)
int
mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
{
- MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
- VirtTarget *vtarget;
- struct scsi_target *starget;
- int max_depth;
- int tagged;
-
- starget = scsi_target(sdev);
- vtarget = starget->hostdata;
-
- if (hd->ioc->bus_type == SPI) {
- if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
- if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
+ MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
+ VirtDevice *pTarget;
+ int max_depth;
+ int tagged;
+
+ if (hd == NULL)
+ return 0;
+ if (!(pTarget = hd->Targets[sdev->id]))
+ return 0;
+
+ if (hd->ioc->bus_type == SCSI) {
+ if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
+ if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
max_depth = 1;
- else if (((vtarget->inq_data[0] & 0x1f) == 0x00) &&
- (vtarget->minSyncFactor <= MPT_ULTRA160 ))
+ else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
+ (pTarget->minSyncFactor <= MPT_ULTRA160 ))
max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
else
max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
@@ -2330,58 +2295,64 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
* Return non-zero if fails.
*/
int
-mptscsih_slave_configure(struct scsi_device *sdev)
+mptscsih_slave_configure(struct scsi_device *device)
{
- struct Scsi_Host *sh = sdev->host;
- VirtTarget *vtarget;
- VirtDevice *vdevice;
- struct scsi_target *starget;
+ struct Scsi_Host *sh = device->host;
+ VirtDevice *pTarget;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
- int indexed_lun, lun_index;
- starget = scsi_target(sdev);
- vtarget = starget->hostdata;
- vdevice = sdev->hostdata;
+ if ((hd == NULL) || (hd->Targets == NULL)) {
+ return 0;
+ }
dsprintk((MYIOC_s_INFO_FMT
"device @ %p, id=%d, LUN=%d, channel=%d\n",
- hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
- if (hd->ioc->bus_type == SPI)
- dsprintk((MYIOC_s_INFO_FMT
- "sdtr %d wdtr %d ppr %d inq length=%d\n",
- hd->ioc->name, sdev->sdtr, sdev->wdtr,
- sdev->ppr, sdev->inquiry_len));
-
- if (sdev->id > sh->max_id) {
+ hd->ioc->name, device, device->id, device->lun, device->channel));
+ dsprintk((MYIOC_s_INFO_FMT
+ "sdtr %d wdtr %d ppr %d inq length=%d\n",
+ hd->ioc->name, device->sdtr, device->wdtr,
+ device->ppr, device->inquiry_len));
+
+ if (device->id > sh->max_id) {
/* error case, should never happen */
- scsi_adjust_queue_depth(sdev, 0, 1);
+ scsi_adjust_queue_depth(device, 0, 1);
+ goto slave_configure_exit;
+ }
+
+ pTarget = hd->Targets[device->id];
+
+ if (pTarget == NULL) {
+ /* Driver doesn't know about this device.
+ * Kernel may generate a "Dummy Lun 0" which
+ * may become a real Lun if a
+ * "scsi add-single-device" command is executed
+ * while the driver is active (hot-plug a
+ * device). LSI Raid controllers need
+ * queue_depth set to DEV_HIGH for this reason.
+ */
+ scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
+ MPT_SCSI_CMD_PER_DEV_HIGH);
goto slave_configure_exit;
}
- vdevice->configured_lun=1;
- lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
- indexed_lun = (vdevice->lun % 32);
- vtarget->luns[lun_index] |= (1 << indexed_lun);
- mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry,
- sdev->inquiry_len );
- mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
+ mptscsih_initTarget(hd, device->channel, device->id, device->lun,
+ device->inquiry, device->inquiry_len );
+ mptscsih_change_queue_depth(device, MPT_SCSI_CMD_PER_DEV_HIGH);
dsprintk((MYIOC_s_INFO_FMT
"Queue depth=%d, tflags=%x\n",
- hd->ioc->name, sdev->queue_depth, vtarget->tflags));
+ hd->ioc->name, device->queue_depth, pTarget->tflags));
- if (hd->ioc->bus_type == SPI)
- dsprintk((MYIOC_s_INFO_FMT
- "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
- hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
- vtarget->minSyncFactor));
+ dsprintk((MYIOC_s_INFO_FMT
+ "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
+ hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
slave_configure_exit:
dsprintk((MYIOC_s_INFO_FMT
"tagged %d, simple %d, ordered %d\n",
- hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
- sdev->ordered_tags));
+ hd->ioc->name,device->tagged_supported, device->simple_tags,
+ device->ordered_tags));
return 0;
}
@@ -2399,14 +2370,16 @@ mptscsih_slave_configure(struct scsi_device *sdev)
static void
mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
{
- VirtDevice *vdev;
+ VirtDevice *target;
SCSIIORequest_t *pReq;
u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
+ int index;
/* Get target structure
*/
pReq = (SCSIIORequest_t *) mf;
- vdev = sc->device->hostdata;
+ index = (int) pReq->TargetID;
+ target = hd->Targets[index];
if (sense_count) {
u8 *sense_data;
@@ -2420,7 +2393,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
/* Log SMART data (asc = 0x5D, non-IM case only) if required.
*/
if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
- if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
+ if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
int idx;
MPT_ADAPTER *ioc = hd->ioc;
@@ -2430,7 +2403,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
- (sc->device->channel << 8) || sc->device->id;
+ (pReq->Bus << 8) || pReq->TargetID;
ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
@@ -2530,9 +2503,9 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
/* 2. Chain Buffer initialization
*/
- /* 4. Renegotiate to all devices, if SPI
+ /* 4. Renegotiate to all devices, if SCSI
*/
- if (ioc->bus_type == SPI) {
+ if (ioc->bus_type == SCSI) {
dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
}
@@ -2561,7 +2534,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
/* 7. Set flag to force DV and re-read IOC Page 3
*/
- if (ioc->bus_type == SPI) {
+ if (ioc->bus_type == SCSI) {
ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
ddvtprintk(("Set reload IOC Pg3 Flag\n"));
}
@@ -2603,7 +2576,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
break;
case MPI_EVENT_IOC_BUS_RESET: /* 04 */
case MPI_EVENT_EXT_BUS_RESET: /* 05 */
- if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
+ if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
hd->soft_resets++;
break;
case MPI_EVENT_LOGOUT: /* 09 */
@@ -2624,11 +2597,11 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
case MPI_EVENT_INTEGRATED_RAID: /* 0B */
{
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
pMpiEventDataRaid_t pRaidEventData =
(pMpiEventDataRaid_t) pEvReply->Data;
+#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
/* Domain Validation Needed */
- if (ioc->bus_type == SPI &&
+ if (ioc->bus_type == SCSI &&
pRaidEventData->ReasonCode ==
MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
@@ -2659,7 +2632,8 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
/*
* mptscsih_initTarget - Target, LUN alloc/free functionality.
* @hd: Pointer to MPT_SCSI_HOST structure
- * @vtarget: per target private data
+ * @bus_id: Bus number (?)
+ * @target_id: SCSI target id
* @lun: SCSI LUN id
* @data: Pointer to data
* @dlen: Number of INQUIRY bytes
@@ -2672,14 +2646,15 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
*
*/
static void
-mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen)
+mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
{
+ int indexed_lun, lun_index;
+ VirtDevice *vdev;
SpiCfgData *pSpi;
char data_56;
- int inq_len;
dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
- hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
+ hd->ioc->name, bus_id, target_id, lun, hd));
/*
* If the peripheral qualifier filter is enabled then if the target reports a 0x1
@@ -2699,68 +2674,75 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data,
if (data[0] & 0xe0)
return;
- if (vtarget == NULL)
- return;
-
- if (data)
- vtarget->type = data[0];
-
- if (hd->ioc->bus_type != SPI)
+ if ((vdev = hd->Targets[target_id]) == NULL) {
return;
+ }
- if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
- /* Treat all Processors as SAF-TE if
- * command line option is set */
- vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
- mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
- }else if ((data[0] == TYPE_PROCESSOR) &&
- !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
- if ( dlen > 49 ) {
- vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
- if ( data[44] == 'S' &&
- data[45] == 'A' &&
- data[46] == 'F' &&
- data[47] == '-' &&
- data[48] == 'T' &&
- data[49] == 'E' ) {
- vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
- mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
+ lun_index = (lun >> 5); /* 32 luns per lun_index */
+ indexed_lun = (lun % 32);
+ vdev->luns[lun_index] |= (1 << indexed_lun);
+
+ if (hd->ioc->bus_type == SCSI) {
+ if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
+ /* Treat all Processors as SAF-TE if
+ * command line option is set */
+ vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+ mptscsih_writeIOCPage4(hd, target_id, bus_id);
+ }else if ((data[0] == TYPE_PROCESSOR) &&
+ !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
+ if ( dlen > 49 ) {
+ vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
+ if ( data[44] == 'S' &&
+ data[45] == 'A' &&
+ data[46] == 'F' &&
+ data[47] == '-' &&
+ data[48] == 'T' &&
+ data[49] == 'E' ) {
+ vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+ mptscsih_writeIOCPage4(hd, target_id, bus_id);
+ }
}
}
- }
- if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
- inq_len = dlen < 8 ? dlen : 8;
- memcpy (vtarget->inq_data, data, inq_len);
- /* If have not done DV, set the DV flag.
- */
- pSpi = &hd->ioc->spi_data;
- if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
- if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE)
- pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV;
- }
- vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
+ if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
+ if ( dlen > 8 ) {
+ memcpy (vdev->inq_data, data, 8);
+ } else {
+ memcpy (vdev->inq_data, data, dlen);
+ }
- data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
- if (dlen > 56) {
- if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
- /* Update the target capabilities
+ /* If have not done DV, set the DV flag.
*/
- data_56 = data[56];
- vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
+ pSpi = &hd->ioc->spi_data;
+ if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
+ if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
+ pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
}
- }
- mptscsih_setTargetNegoParms(hd, vtarget, data_56);
- } else {
- /* Initial Inquiry may not request enough data bytes to
- * obtain byte 57. DV will; if target doesn't return
- * at least 57 bytes, data[56] will be zero. */
- if (dlen > 56) {
- if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
- /* Update the target capabilities
- */
- data_56 = data[56];
- vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
- mptscsih_setTargetNegoParms(hd, vtarget, data_56);
+
+ vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
+
+
+ data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
+ if (dlen > 56) {
+ if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
+ /* Update the target capabilities
+ */
+ data_56 = data[56];
+ vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
+ }
+ }
+ mptscsih_setTargetNegoParms(hd, vdev, data_56);
+ } else {
+ /* Initial Inquiry may not request enough data bytes to
+ * obtain byte 57. DV will; if target doesn't return
+ * at least 57 bytes, data[56] will be zero. */
+ if (dlen > 56) {
+ if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
+ /* Update the target capabilities
+ */
+ data_56 = data[56];
+ vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
+ mptscsih_setTargetNegoParms(hd, vdev, data_56);
+ }
}
}
}
@@ -2773,12 +2755,12 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data,
*
*/
static void
-mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
+mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
{
SpiCfgData *pspi_data = &hd->ioc->spi_data;
int id = (int) target->target_id;
int nvram;
- VirtTarget *vtarget;
+ VirtDevice *vdev;
int ii;
u8 width = MPT_NARROW;
u8 factor = MPT_ASYNC;
@@ -2923,9 +2905,9 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
for (ii = 0; ii < id; ii++) {
- if ( (vtarget = hd->Targets[ii]) ) {
- vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
- mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags);
+ if ( (vdev = hd->Targets[ii]) ) {
+ vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
+ mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
}
}
}
@@ -2943,18 +2925,106 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
}
}
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
+ * Else set the NEED_DV flag after Read Capacity Issued (disks)
+ * or Mode Sense (cdroms).
+ *
+ * Tapes, initTarget will set this flag on completion of Inquiry command.
+ * Called only if DV_NOT_DONE flag is set
+ */
+static void
+mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
+{
+ MPT_ADAPTER *ioc = hd->ioc;
+ u8 cmd;
+ SpiCfgData *pSpi;
+
+ ddvtprintk((MYIOC_s_NOTE_FMT
+ " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
+ hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
+
+ if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
+ return;
+
+ cmd = pReq->CDB[0];
+
+ if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
+ pSpi = &ioc->spi_data;
+ if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) {
+ /* Set NEED_DV for all hidden disks
+ */
+ Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
+ int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
+
+ while (numPDisk) {
+ pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
+ ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
+ pPDisk++;
+ numPDisk--;
+ }
+ }
+ pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
+ ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
+ }
+}
+
+/* mptscsih_raid_set_dv_flags()
+ *
+ * New or replaced disk. Set DV flag and schedule DV.
+ */
+static void
+mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
+{
+ MPT_ADAPTER *ioc = hd->ioc;
+ SpiCfgData *pSpi = &ioc->spi_data;
+ Ioc3PhysDisk_t *pPDisk;
+ int numPDisk;
+
+ if (hd->negoNvram != 0)
+ return;
+
+ ddvtprintk(("DV requested for phys disk id %d\n", id));
+ if (ioc->raid_data.pIocPg3) {
+ pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
+ numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
+ while (numPDisk) {
+ if (id == pPDisk->PhysDiskNum) {
+ pSpi->dvStatus[pPDisk->PhysDiskID] =
+ (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
+ pSpi->forceDv = MPT_SCSICFG_NEED_DV;
+ ddvtprintk(("NEED_DV set for phys disk id %d\n",
+ pPDisk->PhysDiskID));
+ break;
+ }
+ pPDisk++;
+ numPDisk--;
+ }
+
+ if (numPDisk == 0) {
+ /* The physical disk that needs DV was not found
+ * in the stored IOC Page 3. The driver must reload
+ * this page. DV routine will set the NEED_DV flag for
+ * all phys disks that have DV_NOT_DONE set.
+ */
+ pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
+ ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
+ }
+ }
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* If no Target, bus reset on 1st I/O. Set the flag to
* prevent any future negotiations to this device.
*/
static void
-mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
+mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
{
- VirtDevice *vdev;
- if ((vdev = sc->device->hostdata) != NULL)
- hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO;
+ if ((hd->Targets) && (hd->Targets[target_id] == NULL))
+ hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
+
return;
}
@@ -3030,7 +3100,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
MPT_ADAPTER *ioc = hd->ioc;
Config_t *pReq;
SCSIDevicePage1_t *pData;
- VirtTarget *vtarget=NULL;
+ VirtDevice *pTarget=NULL;
MPT_FRAME_HDR *mf;
dma_addr_t dataDma;
u16 req_idx;
@@ -3110,11 +3180,11 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
/* If id is not a raid volume, get the updated
* transmission settings from the target structure.
*/
- if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) {
- width = vtarget->maxWidth;
- factor = vtarget->minSyncFactor;
- offset = vtarget->maxOffset;
- negoFlags = vtarget->negoFlags;
+ if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
+ width = pTarget->maxWidth;
+ factor = pTarget->minSyncFactor;
+ offset = pTarget->maxOffset;
+ negoFlags = pTarget->negoFlags;
}
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
@@ -3834,139 +3904,149 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mptscsih_negotiate_to_asyn_narrow - Restore devices to default state
- * @hd: Pointer to a SCSI HOST structure
- * @vtarget: per device private data
+ * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
+ * @hd: Pointer to MPT_SCSI_HOST structure
+ * @portnum: IOC port number
*
* Uses the ISR, but with special processing.
* MUST be single-threaded.
*
+ * Return: 0 on completion
*/
-static void
-mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
+static int
+mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
{
MPT_ADAPTER *ioc= hd->ioc;
- SCSIDevicePage1_t *pcfg1Data;
+ VirtDevice *pTarget;
+ SCSIDevicePage1_t *pcfg1Data = NULL;
+ INTERNAL_CMD iocmd;
CONFIGPARMS cfg;
- dma_addr_t cfg1_dma_addr;
- ConfigPageHeader_t header;
- int id;
- int requested, configuration, data,i;
+ dma_addr_t cfg1_dma_addr = -1;
+ ConfigPageHeader_t header1;
+ int bus = 0;
+ int id = 0;
+ int lun;
+ int indexed_lun, lun_index;
+ int hostId = ioc->pfacts[portnum].PortSCSIID;
+ int max_id;
+ int requested, configuration, data;
+ int doConfig = 0;
u8 flags, factor;
- if (ioc->bus_type != SPI)
- return;
+ max_id = ioc->sh->max_id - 1;
- if (!ioc->spi_data.sdp1length)
- return;
+ /* Following parameters will not change
+ * in this routine.
+ */
+ iocmd.cmd = SYNCHRONIZE_CACHE;
+ iocmd.flags = 0;
+ iocmd.physDiskNum = -1;
+ iocmd.data = NULL;
+ iocmd.data_dma = -1;
+ iocmd.size = 0;
+ iocmd.rsvd = iocmd.rsvd2 = 0;
- pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
- ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
+ /* No SCSI hosts
+ */
+ if (hd->Targets == NULL)
+ return 0;
- if (pcfg1Data == NULL)
- return;
+ /* Skip the host
+ */
+ if (id == hostId)
+ id++;
- header.PageVersion = ioc->spi_data.sdp1version;
- header.PageLength = ioc->spi_data.sdp1length;
- header.PageNumber = 1;
- header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
- cfg.cfghdr.hdr = &header;
- cfg.physAddr = cfg1_dma_addr;
- cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
- cfg.dir = 1;
- cfg.timeout = 0;
+ /* Write SDP1 for all SCSI devices
+ * Alloc memory and set up config buffer
+ */
+ if (ioc->bus_type == SCSI) {
+ if (ioc->spi_data.sdp1length > 0) {
+ pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
+ ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
+
+ if (pcfg1Data != NULL) {
+ doConfig = 1;
+ header1.PageVersion = ioc->spi_data.sdp1version;
+ header1.PageLength = ioc->spi_data.sdp1length;
+ header1.PageNumber = 1;
+ header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
+ cfg.cfghdr.hdr = &header1;
+ cfg.physAddr = cfg1_dma_addr;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+ cfg.dir = 1;
+ cfg.timeout = 0;
+ }
+ }
+ }
- if (vtarget->raidVolume && ioc->raid_data.pIocPg3) {
- for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
- id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID;
- flags = hd->ioc->spi_data.noQas;
- if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
- data = hd->ioc->spi_data.nvram[id];
- if (data & MPT_NVRAM_WIDE_DISABLE)
- flags |= MPT_TARGET_NO_NEGO_WIDE;
- factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
- if ((factor == 0) || (factor == MPT_ASYNC))
- flags |= MPT_TARGET_NO_NEGO_SYNC;
+ /* loop through all devices on this port
+ */
+ while (bus < MPT_MAX_BUS) {
+ iocmd.bus = bus;
+ iocmd.id = id;
+ pTarget = hd->Targets[(int)id];
+
+ if (doConfig) {
+
+ /* Set the negotiation flags */
+ if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
+ flags = pTarget->negoFlags;
+ } else {
+ flags = hd->ioc->spi_data.noQas;
+ if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
+ data = hd->ioc->spi_data.nvram[id];
+
+ if (data & MPT_NVRAM_WIDE_DISABLE)
+ flags |= MPT_TARGET_NO_NEGO_WIDE;
+
+ factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
+ if ((factor == 0) || (factor == MPT_ASYNC))
+ flags |= MPT_TARGET_NO_NEGO_SYNC;
+ }
}
+
+ /* Force to async, narrow */
mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
- &configuration, flags);
+ &configuration, flags);
dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
"offset=0 negoFlags=%x request=%x config=%x\n",
id, flags, requested, configuration));
pcfg1Data->RequestedParameters = cpu_to_le32(requested);
pcfg1Data->Reserved = 0;
pcfg1Data->Configuration = cpu_to_le32(configuration);
- cfg.pageAddr = (vtarget->bus_id<<8) | id;
+ cfg.pageAddr = (bus<<8) | id;
mpt_config(hd->ioc, &cfg);
}
- } else {
- flags = vtarget->negoFlags;
- mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
- &configuration, flags);
- dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
- "offset=0 negoFlags=%x request=%x config=%x\n",
- vtarget->target_id, flags, requested, configuration));
- pcfg1Data->RequestedParameters = cpu_to_le32(requested);
- pcfg1Data->Reserved = 0;
- pcfg1Data->Configuration = cpu_to_le32(configuration);
- cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id;
- mpt_config(hd->ioc, &cfg);
- }
-
- if (pcfg1Data)
- pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr);
-}
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
- * @hd: Pointer to a SCSI HOST structure
- * @vtarget: per device private data
- * @lun: lun
- *
- * Uses the ISR, but with special processing.
- * MUST be single-threaded.
- *
- */
-static void
-mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
-{
- INTERNAL_CMD iocmd;
-
- /* Following parameters will not change
- * in this routine.
- */
- iocmd.cmd = SYNCHRONIZE_CACHE;
- iocmd.flags = 0;
- iocmd.physDiskNum = -1;
- iocmd.data = NULL;
- iocmd.data_dma = -1;
- iocmd.size = 0;
- iocmd.rsvd = iocmd.rsvd2 = 0;
- iocmd.bus = vdevice->bus_id;
- iocmd.id = vdevice->target_id;
- iocmd.lun = (u8)vdevice->lun;
+ /* If target Ptr NULL or if this target is NOT a disk, skip.
+ */
+ if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){
+ for (lun=0; lun <= MPT_LAST_LUN; lun++) {
+ /* If LUN present, issue the command
+ */
+ lun_index = (lun >> 5); /* 32 luns per lun_index */
+ indexed_lun = (lun % 32);
+ if (pTarget->luns[lun_index] & (1<vtarget->type & TYPE_DISK) &&
- (vdevice->configured_lun))
- mptscsih_do_cmd(hd, &iocmd);
-}
+ /* get next relevant device */
+ id++;
-/* Search IOC page 3 to determine if this is hidden physical disk
- */
-/* Search IOC page 3 to determine if this is hidden physical disk
- */
-static int
-mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
-{
- int i;
+ if (id == hostId)
+ id++;
- if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
- return 0;
+ if (id > max_id) {
+ id = 0;
+ bus++;
+ }
+ }
- for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
- if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
- return 1;
+ if (pcfg1Data) {
+ pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
}
return 0;
@@ -4021,8 +4101,8 @@ mptscsih_domainValidation(void *arg)
msleep(250);
- /* DV only to SPI adapters */
- if (ioc->bus_type != SPI)
+ /* DV only to SCSI adapters */
+ if (ioc->bus_type != SCSI)
continue;
/* Make sure everything looks ok */
@@ -4125,12 +4205,32 @@ mptscsih_domainValidation(void *arg)
return;
}
+/* Search IOC page 3 to determine if this is hidden physical disk
+ */
+/* Search IOC page 3 to determine if this is hidden physical disk
+ */
+static int
+mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
+{
+ int i;
+
+ if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
+ return 0;
+
+ for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
+ if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
+ return 1;
+ }
+
+ return 0;
+}
+
/* Write SDP1 if no QAS has been enabled
*/
static void
mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
{
- VirtTarget *vtarget;
+ VirtDevice *pTarget;
int ii;
if (hd->Targets == NULL)
@@ -4143,11 +4243,11 @@ mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
continue;
- vtarget = hd->Targets[ii];
+ pTarget = hd->Targets[ii];
- if ((vtarget != NULL) && (!vtarget->raidVolume)) {
- if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
- vtarget->negoFlags |= hd->ioc->spi_data.noQas;
+ if ((pTarget != NULL) && (!pTarget->raidVolume)) {
+ if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
+ pTarget->negoFlags |= hd->ioc->spi_data.noQas;
dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
mptscsih_writeSDP1(hd, 0, ii, 0);
}
@@ -4187,7 +4287,7 @@ static int
mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
{
MPT_ADAPTER *ioc = hd->ioc;
- VirtTarget *vtarget;
+ VirtDevice *pTarget;
SCSIDevicePage1_t *pcfg1Data;
SCSIDevicePage0_t *pcfg0Data;
u8 *pbuf1;
@@ -4258,12 +4358,12 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
iocmd.physDiskNum = -1;
iocmd.rsvd = iocmd.rsvd2 = 0;
- vtarget = hd->Targets[id];
+ pTarget = hd->Targets[id];
/* Use tagged commands if possible.
*/
- if (vtarget) {
- if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
+ if (pTarget) {
+ if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
else {
if (hd->ioc->facts.FWVersion.Word < 0x01000600)
@@ -4479,7 +4579,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* Reset the size for disks
*/
inq0 = (*pbuf1) & 0x1F;
- if ((inq0 == 0) && vtarget && !vtarget->raidVolume) {
+ if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
sz = 0x40;
iocmd.size = sz;
}
@@ -4489,7 +4589,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
*/
if (inq0 == TYPE_PROCESSOR) {
mptscsih_initTarget(hd,
- vtarget,
+ bus,
+ id,
lun,
pbuf1,
sz);
@@ -4503,22 +4604,22 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
goto target_done;
if (sz == 0x40) {
- if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A)
- && (vtarget->minSyncFactor > 0x09)) {
+ if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
+ && (pTarget->minSyncFactor > 0x09)) {
if ((pbuf1[56] & 0x04) == 0)
;
else if ((pbuf1[56] & 0x01) == 1) {
- vtarget->minSyncFactor =
+ pTarget->minSyncFactor =
nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
} else {
- vtarget->minSyncFactor =
+ pTarget->minSyncFactor =
nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
}
- dv.max.factor = vtarget->minSyncFactor;
+ dv.max.factor = pTarget->minSyncFactor;
if ((pbuf1[56] & 0x02) == 0) {
- vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
+ pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
ddvprintk((MYIOC_s_NOTE_FMT
"DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
@@ -4601,7 +4702,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
"DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
mptscsih_initTarget(hd,
- vtarget,
+ bus,
+ id,
lun,
pbuf1,
sz);
@@ -5102,7 +5204,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
static void
mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
{
- VirtTarget *vtarget;
+ VirtDevice *pTarget;
SCSIDevicePage0_t *pPage0;
SCSIDevicePage1_t *pPage1;
int val = 0, data, configuration;
@@ -5122,11 +5224,11 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
* already throttled back.
*/
negoFlags = hd->ioc->spi_data.noQas;
- if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) {
- width = vtarget->maxWidth;
- offset = vtarget->maxOffset;
- factor = vtarget->minSyncFactor;
- negoFlags |= vtarget->negoFlags;
+ if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
+ width = pTarget->maxWidth;
+ offset = pTarget->maxOffset;
+ factor = pTarget->minSyncFactor;
+ negoFlags |= pTarget->negoFlags;
} else {
if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
data = hd->ioc->spi_data.nvram[id];
@@ -5328,11 +5430,11 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
* or overwrite nvram (phys disks only).
*/
- if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) {
- vtarget->maxWidth = dv->now.width;
- vtarget->maxOffset = dv->now.offset;
- vtarget->minSyncFactor = dv->now.factor;
- vtarget->negoFlags = dv->now.flags;
+ if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
+ pTarget->maxWidth = dv->now.width;
+ pTarget->maxOffset = dv->now.offset;
+ pTarget->minSyncFactor = dv->now.factor;
+ pTarget->negoFlags = dv->now.flags;
} else {
/* Preserv all flags, use
* read-modify-write algorithm
@@ -5486,94 +5588,6 @@ mptscsih_fillbuf(char *buffer, int size, int index, int width)
break;
}
}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
- * Else set the NEED_DV flag after Read Capacity Issued (disks)
- * or Mode Sense (cdroms).
- *
- * Tapes, initTarget will set this flag on completion of Inquiry command.
- * Called only if DV_NOT_DONE flag is set
- */
-static void
-mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
-{
- MPT_ADAPTER *ioc = hd->ioc;
- u8 cmd;
- SpiCfgData *pSpi;
-
- ddvtprintk((MYIOC_s_NOTE_FMT
- " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
- hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0]));
-
- if ((sc->device->lun != 0) || (hd->negoNvram != 0))
- return;
-
- cmd = sc->cmnd[0];
-
- if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
- pSpi = &ioc->spi_data;
- if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) {
- /* Set NEED_DV for all hidden disks
- */
- Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
- int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
-
- while (numPDisk) {
- pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
- ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
- pPDisk++;
- numPDisk--;
- }
- }
- pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV;
- ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id));
- }
-}
-
-/* mptscsih_raid_set_dv_flags()
- *
- * New or replaced disk. Set DV flag and schedule DV.
- */
-static void
-mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
-{
- MPT_ADAPTER *ioc = hd->ioc;
- SpiCfgData *pSpi = &ioc->spi_data;
- Ioc3PhysDisk_t *pPDisk;
- int numPDisk;
-
- if (hd->negoNvram != 0)
- return;
-
- ddvtprintk(("DV requested for phys disk id %d\n", id));
- if (ioc->raid_data.pIocPg3) {
- pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
- numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
- while (numPDisk) {
- if (id == pPDisk->PhysDiskNum) {
- pSpi->dvStatus[pPDisk->PhysDiskID] =
- (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
- pSpi->forceDv = MPT_SCSICFG_NEED_DV;
- ddvtprintk(("NEED_DV set for phys disk id %d\n",
- pPDisk->PhysDiskID));
- break;
- }
- pPDisk++;
- numPDisk--;
- }
-
- if (numPDisk == 0) {
- /* The physical disk that needs DV was not found
- * in the stored IOC Page 3. The driver must reload
- * this page. DV routine will set the NEED_DV flag for
- * all phys disks that have DV_NOT_DONE set.
- */
- pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
- ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
- }
- }
-}
#endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
EXPORT_SYMBOL(mptscsih_remove);
@@ -5585,9 +5599,7 @@ EXPORT_SYMBOL(mptscsih_resume);
EXPORT_SYMBOL(mptscsih_proc_info);
EXPORT_SYMBOL(mptscsih_info);
EXPORT_SYMBOL(mptscsih_qcmd);
-EXPORT_SYMBOL(mptscsih_target_alloc);
EXPORT_SYMBOL(mptscsih_slave_alloc);
-EXPORT_SYMBOL(mptscsih_target_destroy);
EXPORT_SYMBOL(mptscsih_slave_destroy);
EXPORT_SYMBOL(mptscsih_slave_configure);
EXPORT_SYMBOL(mptscsih_abort);
diff --git a/trunk/drivers/message/fusion/mptscsih.h b/trunk/drivers/message/fusion/mptscsih.h
index d3cba12f4bd9..971fda4b8b57 100644
--- a/trunk/drivers/message/fusion/mptscsih.h
+++ b/trunk/drivers/message/fusion/mptscsih.h
@@ -91,9 +91,7 @@ extern int mptscsih_resume(struct pci_dev *pdev);
extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func);
extern const char * mptscsih_info(struct Scsi_Host *SChost);
extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *));
-extern int mptscsih_target_alloc(struct scsi_target *starget);
extern int mptscsih_slave_alloc(struct scsi_device *device);
-extern void mptscsih_target_destroy(struct scsi_target *starget);
extern void mptscsih_slave_destroy(struct scsi_device *device);
extern int mptscsih_slave_configure(struct scsi_device *device);
extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
diff --git a/trunk/drivers/message/fusion/mptspi.c b/trunk/drivers/message/fusion/mptspi.c
index ce332a6085e5..5c0e307d1d5d 100644
--- a/trunk/drivers/message/fusion/mptspi.c
+++ b/trunk/drivers/message/fusion/mptspi.c
@@ -103,16 +103,13 @@ static int mptspiTaskCtx = -1;
static int mptspiInternalCtx = -1; /* Used only for internal commands */
static struct scsi_host_template mptspi_driver_template = {
- .module = THIS_MODULE,
.proc_name = "mptspi",
.proc_info = mptscsih_proc_info,
.name = "MPT SPI Host",
.info = mptscsih_info,
.queuecommand = mptscsih_qcmd,
- .target_alloc = mptscsih_target_alloc,
.slave_alloc = mptscsih_slave_alloc,
.slave_configure = mptscsih_slave_configure,
- .target_destroy = mptscsih_target_destroy,
.slave_destroy = mptscsih_slave_destroy,
.change_queue_depth = mptscsih_change_queue_depth,
.eh_abort_handler = mptscsih_abort,
@@ -180,15 +177,13 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Skipping because it's not operational!\n",
ioc->name);
- error = -ENODEV;
- goto out_mptspi_probe;
+ return -ENODEV;
}
if (!ioc->active) {
printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
ioc->name);
- error = -ENODEV;
- goto out_mptspi_probe;
+ return -ENODEV;
}
/* Sanity check - ensure at least 1 port is INITIATOR capable
@@ -213,8 +208,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Unable to register controller with SCSI subsystem\n",
ioc->name);
- error = -1;
- goto out_mptspi_probe;
+ return -1;
}
spin_lock_irqsave(&ioc->FreeQlock, flags);
@@ -292,7 +286,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL) {
error = -ENOMEM;
- goto out_mptspi_probe;
+ goto mptspi_probe_failed;
}
memset(mem, 0, sz);
@@ -310,14 +304,14 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mem = kmalloc(sz, GFP_ATOMIC);
if (mem == NULL) {
error = -ENOMEM;
- goto out_mptspi_probe;
+ goto mptspi_probe_failed;
}
memset(mem, 0, sz);
- hd->Targets = (VirtTarget **) mem;
+ hd->Targets = (VirtDevice **) mem;
dprintk((KERN_INFO
- " vdev @ %p, sz=%d\n", hd->Targets, sz));
+ " Targets @ %p, sz=%d\n", hd->Targets, sz));
/* Clear the TM flags
*/
@@ -391,13 +385,13 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if(error) {
dprintk((KERN_ERR MYNAM
"scsi_add_host failed\n"));
- goto out_mptspi_probe;
+ goto mptspi_probe_failed;
}
scsi_scan_host(sh);
return 0;
-out_mptspi_probe:
+mptspi_probe_failed:
mptscsih_remove(pdev);
return error;
diff --git a/trunk/drivers/mmc/mmc_sysfs.c b/trunk/drivers/mmc/mmc_sysfs.c
index ec701667abfc..3f4a66ca9555 100644
--- a/trunk/drivers/mmc/mmc_sysfs.c
+++ b/trunk/drivers/mmc/mmc_sysfs.c
@@ -80,7 +80,7 @@ static int mmc_bus_match(struct device *dev, struct device_driver *drv)
}
static int
-mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
+mmc_bus_hotplug(struct device *dev, char **envp, int num_envp, char *buf,
int buf_size)
{
struct mmc_card *card = dev_to_mmc_card(dev);
@@ -140,7 +140,7 @@ static struct bus_type mmc_bus_type = {
.name = "mmc",
.dev_attrs = mmc_dev_attrs,
.match = mmc_bus_match,
- .uevent = mmc_bus_uevent,
+ .hotplug = mmc_bus_hotplug,
.suspend = mmc_bus_suspend,
.resume = mmc_bus_resume,
};
diff --git a/trunk/drivers/mtd/maps/pcmciamtd.c b/trunk/drivers/mtd/maps/pcmciamtd.c
index f0f8916da7ad..af24216a0626 100644
--- a/trunk/drivers/mtd/maps/pcmciamtd.c
+++ b/trunk/drivers/mtd/maps/pcmciamtd.c
@@ -66,6 +66,9 @@ struct pcmciamtd_dev {
};
+static dev_info_t dev_info = "pcmciamtd";
+static dev_link_t *dev_list;
+
/* Module parameters */
/* 2 = do 16-bit transfers, 1 = do 8-bit transfers */
@@ -688,21 +691,55 @@ static void pcmciamtd_config(dev_link_t *link)
}
-static int pcmciamtd_suspend(struct pcmcia_device *dev)
-{
- DEBUG(2, "EVENT_PM_RESUME");
-
- /* get_lock(link); */
-
- return 0;
-}
+/* The card status event handler. Mostly, this schedules other
+ * stuff to run after an event is received. A CARD_REMOVAL event
+ * also sets some flags to discourage the driver from trying
+ * to talk to the card any more.
+ */
-static int pcmciamtd_resume(struct pcmcia_device *dev)
+static int pcmciamtd_event(event_t event, int priority,
+ event_callback_args_t *args)
{
- DEBUG(2, "EVENT_PM_SUSPEND");
-
- /* free_lock(link); */
-
+ dev_link_t *link = args->client_data;
+
+ DEBUG(1, "event=0x%06x", event);
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ DEBUG(2, "EVENT_CARD_REMOVAL");
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG) {
+ struct pcmciamtd_dev *dev = link->priv;
+ if(dev->mtd_info) {
+ del_mtd_device(dev->mtd_info);
+ info("mtd%d: Removed", dev->mtd_info->index);
+ }
+ pcmciamtd_release(link);
+ }
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ DEBUG(2, "EVENT_CARD_INSERTION");
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ pcmciamtd_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ DEBUG(2, "EVENT_PM_SUSPEND");
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ DEBUG(2, "EVENT_RESET_PHYSICAL");
+ /* get_lock(link); */
+ break;
+ case CS_EVENT_PM_RESUME:
+ DEBUG(2, "EVENT_PM_RESUME");
+ link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
+ DEBUG(2, "EVENT_CARD_RESET");
+ /* free_lock(link); */
+ break;
+ default:
+ DEBUG(2, "Unknown event %d", event);
+ }
return 0;
}
@@ -713,21 +750,23 @@ static int pcmciamtd_resume(struct pcmcia_device *dev)
* when the device is released.
*/
-static void pcmciamtd_detach(struct pcmcia_device *p_dev)
+static void pcmciamtd_detach(dev_link_t *link)
{
- dev_link_t *link = dev_to_instance(p_dev);
-
DEBUG(3, "link=0x%p", link);
if(link->state & DEV_CONFIG) {
- struct pcmciamtd_dev *dev = link->priv;
- if(dev->mtd_info) {
- del_mtd_device(dev->mtd_info);
- info("mtd%d: Removed", dev->mtd_info->index);
- }
-
pcmciamtd_release(link);
}
+
+ if (link->handle) {
+ int ret;
+ DEBUG(2, "Deregistering with card services");
+ ret = pcmcia_deregister_client(link->handle);
+ if (ret != CS_SUCCESS)
+ cs_error(link->handle, DeregisterClient, ret);
+ }
+
+ link->state |= DEV_STALE_LINK;
}
@@ -736,14 +775,16 @@ static void pcmciamtd_detach(struct pcmcia_device *p_dev)
* with Card Services.
*/
-static int pcmciamtd_attach(struct pcmcia_device *p_dev)
+static dev_link_t *pcmciamtd_attach(void)
{
struct pcmciamtd_dev *dev;
dev_link_t *link;
+ client_reg_t client_reg;
+ int ret;
/* Create new memory card device */
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev) return -ENOMEM;
+ if (!dev) return NULL;
DEBUG(1, "dev=0x%p", dev);
memset(dev, 0, sizeof(*dev));
@@ -753,14 +794,22 @@ static int pcmciamtd_attach(struct pcmcia_device *p_dev)
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY;
- link->next = NULL;
- link->handle = p_dev;
- p_dev->instance = link;
-
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- pcmciamtd_config(link);
-
- return 0;
+ link->next = dev_list;
+ dev_list = link;
+
+ /* Register with Card Services */
+ client_reg.dev_info = &dev_info;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+ DEBUG(2, "Calling RegisterClient");
+ ret = pcmcia_register_client(&link->handle, &client_reg);
+ if (ret != 0) {
+ cs_error(link->handle, RegisterClient, ret);
+ pcmciamtd_detach(link);
+ return NULL;
+ }
+ DEBUG(2, "link = %p", link);
+ return link;
}
static struct pcmcia_device_id pcmciamtd_ids[] = {
@@ -794,12 +843,11 @@ static struct pcmcia_driver pcmciamtd_driver = {
.drv = {
.name = "pcmciamtd"
},
- .probe = pcmciamtd_attach,
- .remove = pcmciamtd_detach,
+ .attach = pcmciamtd_attach,
+ .event = pcmciamtd_event,
+ .detach = pcmciamtd_detach,
.owner = THIS_MODULE,
.id_table = pcmciamtd_ids,
- .suspend = pcmciamtd_suspend,
- .resume = pcmciamtd_resume,
};
@@ -827,6 +875,7 @@ static void __exit exit_pcmciamtd(void)
{
DEBUG(1, DRIVER_DESC " unloading");
pcmcia_unregister_driver(&pcmciamtd_driver);
+ BUG_ON(dev_list != NULL);
}
module_init(init_pcmciamtd);
diff --git a/trunk/drivers/net/8139too.c b/trunk/drivers/net/8139too.c
index d2102a27d307..30bee11c48bd 100644
--- a/trunk/drivers/net/8139too.c
+++ b/trunk/drivers/net/8139too.c
@@ -586,16 +586,16 @@ struct rtl8139_private {
dma_addr_t tx_bufs_dma;
signed char phys[4]; /* MII device addresses. */
char twistie, twist_row, twist_col; /* Twister tune state. */
- unsigned int default_port : 4; /* Last dev->if_port value. */
- unsigned int have_thread : 1;
+ unsigned int default_port:4; /* Last dev->if_port value. */
spinlock_t lock;
spinlock_t rx_lock;
chip_t chipset;
+ pid_t thr_pid;
+ wait_queue_head_t thr_wait;
+ struct completion thr_exited;
u32 rx_config;
struct rtl_extra_stats xstats;
-
- struct work_struct thread;
-
+ int time_to_die;
struct mii_if_info mii;
unsigned int regs_len;
unsigned long fifo_copy_timeout;
@@ -620,7 +620,7 @@ static int rtl8139_open (struct net_device *dev);
static int mdio_read (struct net_device *dev, int phy_id, int location);
static void mdio_write (struct net_device *dev, int phy_id, int location,
int val);
-static void rtl8139_start_thread(struct rtl8139_private *tp);
+static void rtl8139_start_thread(struct net_device *dev);
static void rtl8139_tx_timeout (struct net_device *dev);
static void rtl8139_init_ring (struct net_device *dev);
static int rtl8139_start_xmit (struct sk_buff *skb,
@@ -637,7 +637,6 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
static void rtl8139_set_rx_mode (struct net_device *dev);
static void __set_rx_mode (struct net_device *dev);
static void rtl8139_hw_start (struct net_device *dev);
-static void rtl8139_thread (void *_data);
static struct ethtool_ops rtl8139_ethtool_ops;
/* write MMIO register, with flush */
@@ -1008,7 +1007,8 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
(debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
spin_lock_init (&tp->lock);
spin_lock_init (&tp->rx_lock);
- INIT_WORK(&tp->thread, rtl8139_thread, dev);
+ init_waitqueue_head (&tp->thr_wait);
+ init_completion (&tp->thr_exited);
tp->mii.dev = dev;
tp->mii.mdio_read = mdio_read;
tp->mii.mdio_write = mdio_write;
@@ -1345,7 +1345,7 @@ static int rtl8139_open (struct net_device *dev)
dev->irq, RTL_R8 (MediaStatus),
tp->mii.full_duplex ? "full" : "half");
- rtl8139_start_thread(tp);
+ rtl8139_start_thread(dev);
return 0;
}
@@ -1594,43 +1594,55 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
RTL_R8 (Config1));
}
-static void rtl8139_thread (void *_data)
+static int rtl8139_thread (void *data)
{
- struct net_device *dev = _data;
+ struct net_device *dev = data;
struct rtl8139_private *tp = netdev_priv(dev);
- unsigned long thr_delay;
+ unsigned long timeout;
+
+ daemonize("%s", dev->name);
+ allow_signal(SIGTERM);
+
+ while (1) {
+ timeout = next_tick;
+ do {
+ timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
+ /* make swsusp happy with our thread */
+ try_to_freeze();
+ } while (!signal_pending (current) && (timeout > 0));
+
+ if (signal_pending (current)) {
+ flush_signals(current);
+ }
- if (rtnl_shlock_nowait() == 0) {
+ if (tp->time_to_die)
+ break;
+
+ if (rtnl_lock_interruptible ())
+ break;
rtl8139_thread_iter (dev, tp, tp->mmio_addr);
rtnl_unlock ();
-
- thr_delay = next_tick;
- } else {
- /* unlikely race. mitigate with fast poll. */
- thr_delay = HZ / 2;
}
- schedule_delayed_work(&tp->thread, thr_delay);
+ complete_and_exit (&tp->thr_exited, 0);
}
-static void rtl8139_start_thread(struct rtl8139_private *tp)
+static void rtl8139_start_thread(struct net_device *dev)
{
+ struct rtl8139_private *tp = netdev_priv(dev);
+
+ tp->thr_pid = -1;
tp->twistie = 0;
+ tp->time_to_die = 0;
if (tp->chipset == CH_8139_K)
tp->twistie = 1;
else if (tp->drv_flags & HAS_LNK_CHNG)
return;
- tp->have_thread = 1;
-
- schedule_delayed_work(&tp->thread, next_tick);
-}
-
-static void rtl8139_stop_thread(struct rtl8139_private *tp)
-{
- if (tp->have_thread) {
- cancel_rearming_delayed_work(&tp->thread);
- tp->have_thread = 0;
+ tp->thr_pid = kernel_thread(rtl8139_thread, dev, CLONE_FS|CLONE_FILES);
+ if (tp->thr_pid < 0) {
+ printk (KERN_WARNING "%s: unable to start kernel thread\n",
+ dev->name);
}
}
@@ -2212,12 +2224,22 @@ static int rtl8139_close (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
+ int ret = 0;
unsigned long flags;
netif_stop_queue (dev);
- rtl8139_stop_thread(tp);
-
+ if (tp->thr_pid >= 0) {
+ tp->time_to_die = 1;
+ wmb();
+ ret = kill_proc (tp->thr_pid, SIGTERM, 1);
+ if (ret) {
+ printk (KERN_ERR "%s: unable to signal thread\n", dev->name);
+ return ret;
+ }
+ wait_for_completion (&tp->thr_exited);
+ }
+
if (netif_msg_ifdown(tp))
printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
dev->name, RTL_R16 (IntrStatus));
diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig
index e2fa29b612cd..ebd7313d7fc1 100644
--- a/trunk/drivers/net/Kconfig
+++ b/trunk/drivers/net/Kconfig
@@ -1901,8 +1901,6 @@ config E1000_NAPI
If in doubt, say N.
-source "drivers/net/ixp2000/Kconfig"
-
config MYRI_SBUS
tristate "MyriCOM Gigabit Ethernet support"
depends on SBUS
@@ -2010,18 +2008,7 @@ config SKGE
It does not support the link failover and network management
features that "portable" vendor supplied sk98lin driver does.
-
-
-config SKY2
- tristate "SysKonnect Yukon2 support (EXPERIMENTAL)"
- depends on PCI && EXPERIMENTAL
- select CRC32
- ---help---
- This driver support the Marvell Yukon 2 Gigabit Ethernet adapter.
-
- To compile this driver as a module, choose M here: the module
- will be called sky2. This is recommended.
-
+
config SK98LIN
tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
depends on PCI
@@ -2133,7 +2120,7 @@ config BNX2
config SPIDER_NET
tristate "Spider Gigabit Ethernet driver"
- depends on PCI && PPC_CELL
+ depends on PCI && PPC_BPA
help
This driver supports the Gigabit Ethernet chips present on the
Cell Processor-Based Blades from IBM.
diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile
index b74a7cb5bae6..4cffd34442aa 100644
--- a/trunk/drivers/net/Makefile
+++ b/trunk/drivers/net/Makefile
@@ -13,10 +13,7 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/
obj-$(CONFIG_BONDING) += bonding/
obj-$(CONFIG_GIANFAR) += gianfar_driver.o
-gianfar_driver-objs := gianfar.o \
- gianfar_ethtool.o \
- gianfar_mii.o \
- gianfar_sysfs.o
+gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_mii.o
#
# link order important here
@@ -62,7 +59,6 @@ spidernet-y += spider_net.o spider_net_ethtool.o sungem_phy.o
obj-$(CONFIG_SPIDER_NET) += spidernet.o
obj-$(CONFIG_TC35815) += tc35815.o
obj-$(CONFIG_SKGE) += skge.o
-obj-$(CONFIG_SKY2) += sky2.o
obj-$(CONFIG_SK98LIN) += sk98lin/
obj-$(CONFIG_SKFP) += skfp/
obj-$(CONFIG_VIA_RHINE) += via-rhine.o
@@ -206,7 +202,6 @@ obj-$(CONFIG_NET_TULIP) += tulip/
obj-$(CONFIG_HAMRADIO) += hamradio/
obj-$(CONFIG_IRDA) += irda/
obj-$(CONFIG_ETRAX_ETHERNET) += cris/
-obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
obj-$(CONFIG_NETCONSOLE) += netconsole.o
diff --git a/trunk/drivers/net/bonding/Makefile b/trunk/drivers/net/bonding/Makefile
index 5cdae2bc055a..cf50384b469e 100644
--- a/trunk/drivers/net/bonding/Makefile
+++ b/trunk/drivers/net/bonding/Makefile
@@ -4,5 +4,5 @@
obj-$(CONFIG_BONDING) += bonding.o
-bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o
+bonding-objs := bond_main.o bond_3ad.o bond_alb.o
diff --git a/trunk/drivers/net/bonding/bond_3ad.c b/trunk/drivers/net/bonding/bond_3ad.c
index f3f5825469d6..d2f34d5a8083 100644
--- a/trunk/drivers/net/bonding/bond_3ad.c
+++ b/trunk/drivers/net/bonding/bond_3ad.c
@@ -18,6 +18,38 @@
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
+ *
+ * Changes:
+ *
+ * 2003/05/01 - Tsippy Mendelson and
+ * Amir Noam
+ * - Added support for lacp_rate module param.
+ *
+ * 2003/05/01 - Shmulik Hen
+ * - Based on discussion on mailing list, changed locking scheme
+ * to use lock/unlock or lock_bh/unlock_bh appropriately instead
+ * of lock_irqsave/unlock_irqrestore. The new scheme helps exposing
+ * hidden bugs and solves system hangs that occurred due to the fact
+ * that holding lock_irqsave doesn't prevent softirqs from running.
+ * This also increases total throughput since interrupts are not
+ * blocked on each transmitted packets or monitor timeout.
+ *
+ * 2003/05/01 - Shmulik Hen
+ * - Renamed bond_3ad_link_status_changed() to
+ * bond_3ad_handle_link_change() for compatibility with TLB.
+ *
+ * 2003/05/20 - Amir Noam
+ * - Fix long fail over time when releasing last slave of an active
+ * aggregator - send LACPDU on unbind of slave to tell partner this
+ * port is no longer aggregatable.
+ *
+ * 2003/06/25 - Tsippy Mendelson
+ * - Send LACPDU as highest priority packet to further fix the above
+ * problem on very high Tx traffic load where packets may get dropped
+ * by the slave.
+ *
+ * 2003/12/01 - Shmulik Hen
+ * - Code cleanup and style changes
*/
//#define BONDING_DEBUG 1
@@ -1166,10 +1198,10 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
// detect loopback situation
if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) {
// INFO_RECEIVED_LOOPBACK_FRAMES
- printk(KERN_ERR DRV_NAME ": %s: An illegal loopback occurred on "
- "adapter (%s). Check the configuration to verify that all "
- "Adapters are connected to 802.3ad compliant switch ports\n",
- port->slave->dev->master->name, port->slave->dev->name);
+ printk(KERN_ERR DRV_NAME ": An illegal loopback occurred on adapter (%s)\n",
+ port->slave->dev->name);
+ printk(KERN_ERR "Check the configuration to verify that all Adapters "
+ "are connected to 802.3ad compliant switch ports\n");
__release_rx_machine_lock(port);
return;
}
@@ -1346,9 +1378,8 @@ static void ad_port_selection_logic(struct port *port)
}
}
if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
- printk(KERN_WARNING DRV_NAME ": %s: Warning: Port %d (on %s) was "
+ printk(KERN_WARNING DRV_NAME ": Warning: Port %d (on %s) was "
"related to aggregator %d but was not on its port list\n",
- port->slave->dev->master->name,
port->actor_port_number, port->slave->dev->name,
port->aggregator->aggregator_identifier);
}
@@ -1419,8 +1450,7 @@ static void ad_port_selection_logic(struct port *port)
dprintk("Port %d joined LAG %d(new LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
} else {
- printk(KERN_ERR DRV_NAME ": %s: Port %d (on %s) did not find a suitable aggregator\n",
- port->slave->dev->master->name,
+ printk(KERN_ERR DRV_NAME ": Port %d (on %s) did not find a suitable aggregator\n",
port->actor_port_number, port->slave->dev->name);
}
}
@@ -1552,9 +1582,8 @@ static void ad_agg_selection_logic(struct aggregator *aggregator)
// check if any partner replys
if (best_aggregator->is_individual) {
- printk(KERN_WARNING DRV_NAME ": %s: Warning: No 802.3ad response from "
- "the link partner for any adapters in the bond\n",
- best_aggregator->slave->dev->master->name);
+ printk(KERN_WARNING DRV_NAME ": Warning: No 802.3ad response from the link partner "
+ "for any adapters in the bond\n");
}
// check if there are more than one aggregator
@@ -1886,8 +1915,7 @@ int bond_3ad_bind_slave(struct slave *slave)
struct aggregator *aggregator;
if (bond == NULL) {
- printk(KERN_ERR DRV_NAME ": %s: The slave %s is not attached to its bond\n",
- slave->dev->master->name, slave->dev->name);
+ printk(KERN_ERR "The slave %s is not attached to its bond\n", slave->dev->name);
return -1;
}
@@ -1962,9 +1990,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
// if slave is null, the whole port is not initialized
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": Warning: %s: Trying to "
- "unbind an uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ printk(KERN_WARNING DRV_NAME ": Trying to unbind an uninitialized port on %s\n", slave->dev->name);
return;
}
@@ -1995,8 +2021,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
dprintk("Some port(s) related to LAG %d - replaceing with LAG %d\n", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier);
if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
- printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
- aggregator->slave->dev->master->name);
+ printk(KERN_INFO DRV_NAME ": Removing an active aggregator\n");
// select new active aggregator
select_new_active_agg = 1;
}
@@ -2026,17 +2051,15 @@ void bond_3ad_unbind_slave(struct slave *slave)
ad_agg_selection_logic(__get_first_agg(port));
}
} else {
- printk(KERN_WARNING DRV_NAME ": %s: Warning: unbinding aggregator, "
- "and could not find a new aggregator for its ports\n",
- slave->dev->master->name);
+ printk(KERN_WARNING DRV_NAME ": Warning: unbinding aggregator, "
+ "and could not find a new aggregator for its ports\n");
}
} else { // in case that the only port related to this aggregator is the one we want to remove
select_new_active_agg = aggregator->is_active;
// clear the aggregator
ad_clear_agg(aggregator);
if (select_new_active_agg) {
- printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
- slave->dev->master->name);
+ printk(KERN_INFO "Removing an active aggregator\n");
// select new active aggregator
ad_agg_selection_logic(__get_first_agg(port));
}
@@ -2062,8 +2085,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
// clear the aggregator
ad_clear_agg(temp_aggregator);
if (select_new_active_agg) {
- printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
- slave->dev->master->name);
+ printk(KERN_INFO "Removing an active aggregator\n");
// select new active aggregator
ad_agg_selection_logic(__get_first_agg(port));
}
@@ -2109,8 +2131,7 @@ void bond_3ad_state_machine_handler(struct bonding *bond)
// select the active aggregator for the bond
if ((port = __get_first_port(bond))) {
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": %s: Warning: bond's first port is "
- "uninitialized\n", bond->dev->name);
+ printk(KERN_WARNING DRV_NAME ": Warning: bond's first port is uninitialized\n");
goto re_arm;
}
@@ -2122,8 +2143,7 @@ void bond_3ad_state_machine_handler(struct bonding *bond)
// for each port run the state machines
for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": %s: Warning: Found an uninitialized "
- "port\n", bond->dev->name);
+ printk(KERN_WARNING DRV_NAME ": Warning: Found an uninitialized port\n");
goto re_arm;
}
@@ -2164,8 +2184,7 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
port = &(SLAVE_AD_INFO(slave).port);
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": %s: Warning: port of slave %s is "
- "uninitialized\n", slave->dev->name, slave->dev->master->name);
+ printk(KERN_WARNING DRV_NAME ": Warning: port of slave %s is uninitialized\n", slave->dev->name);
return;
}
@@ -2211,9 +2230,8 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
// if slave is null, the whole port is not initialized
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": Warning: %s: speed "
- "changed for uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ printk(KERN_WARNING DRV_NAME ": Warning: speed changed for uninitialized port on %s\n",
+ slave->dev->name);
return;
}
@@ -2239,9 +2257,8 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
// if slave is null, the whole port is not initialized
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": %s: Warning: duplex changed "
- "for uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ printk(KERN_WARNING DRV_NAME ": Warning: duplex changed for uninitialized port on %s\n",
+ slave->dev->name);
return;
}
@@ -2268,9 +2285,8 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
// if slave is null, the whole port is not initialized
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": Warning: %s: link status changed for "
- "uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ printk(KERN_WARNING DRV_NAME ": Warning: link status changed for uninitialized port on %s\n",
+ slave->dev->name);
return;
}
@@ -2347,8 +2363,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
}
if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
- printk(KERN_DEBUG DRV_NAME ": %s: Error: "
- "bond_3ad_get_active_agg_info failed\n", dev->name);
+ printk(KERN_DEBUG "ERROR: bond_3ad_get_active_agg_info failed\n");
goto out;
}
@@ -2357,9 +2372,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
if (slaves_in_agg == 0) {
/*the aggregator is empty*/
- printk(KERN_DEBUG DRV_NAME ": %s: Error: active "
- "aggregator is empty\n",
- dev->name);
+ printk(KERN_DEBUG "ERROR: active aggregator is empty\n");
goto out;
}
@@ -2377,8 +2390,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
}
if (slave_agg_no >= 0) {
- printk(KERN_ERR DRV_NAME ": %s: Error: Couldn't find a slave to tx on "
- "for aggregator ID %d\n", dev->name, agg_id);
+ printk(KERN_ERR DRV_NAME ": Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id);
goto out;
}
diff --git a/trunk/drivers/net/bonding/bond_3ad.h b/trunk/drivers/net/bonding/bond_3ad.h
index 5ee2cef5b037..673a30af5660 100644
--- a/trunk/drivers/net/bonding/bond_3ad.h
+++ b/trunk/drivers/net/bonding/bond_3ad.h
@@ -18,6 +18,19 @@
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
+ *
+ * Changes:
+ *
+ * 2003/05/01 - Tsippy Mendelson and
+ * Amir Noam
+ * - Added support for lacp_rate module param.
+ *
+ * 2003/05/01 - Shmulik Hen
+ * - Renamed bond_3ad_link_status_changed() to
+ * bond_3ad_handle_link_change() for compatibility with TLB.
+ *
+ * 2003/12/01 - Shmulik Hen
+ * - Code cleanup and style changes
*/
#ifndef __BOND_3AD_H__
diff --git a/trunk/drivers/net/bonding/bond_alb.c b/trunk/drivers/net/bonding/bond_alb.c
index 854ddfb90da1..f8fce3961197 100644
--- a/trunk/drivers/net/bonding/bond_alb.c
+++ b/trunk/drivers/net/bonding/bond_alb.c
@@ -18,6 +18,25 @@
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
+ *
+ * Changes:
+ *
+ * 2003/06/25 - Shmulik Hen
+ * - Fixed signed/unsigned calculation errors that caused load sharing
+ * to collapse to one slave under very heavy UDP Tx stress.
+ *
+ * 2003/08/06 - Amir Noam
+ * - Add support for setting bond's MAC address with special
+ * handling required for ALB/TLB.
+ *
+ * 2003/12/01 - Shmulik Hen
+ * - Code cleanup and style changes
+ *
+ * 2003/12/30 - Amir Noam
+ * - Fixed: Cannot remove and re-enslave the original active slave.
+ *
+ * 2004/01/14 - Shmulik Hen
+ * - Add capability to tag self generated packets in ALB/TLB modes.
*/
//#define BONDING_DEBUG 1
@@ -179,21 +198,20 @@ static int tlb_initialize(struct bonding *bond)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
int size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info);
- struct tlb_client_info *new_hashtbl;
int i;
spin_lock_init(&(bond_info->tx_hashtbl_lock));
- new_hashtbl = kmalloc(size, GFP_KERNEL);
- if (!new_hashtbl) {
+ _lock_tx_hashtbl(bond);
+
+ bond_info->tx_hashtbl = kmalloc(size, GFP_KERNEL);
+ if (!bond_info->tx_hashtbl) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: Failed to allocate TLB hash table\n",
+ ": Error: %s: Failed to allocate TLB hash table\n",
bond->dev->name);
+ _unlock_tx_hashtbl(bond);
return -1;
}
- _lock_tx_hashtbl(bond);
-
- bond_info->tx_hashtbl = new_hashtbl;
memset(bond_info->tx_hashtbl, 0, size);
@@ -495,8 +513,7 @@ static void rlb_update_client(struct rlb_client_info *client_info)
client_info->mac_dst);
if (!skb) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: failed to create an ARP packet\n",
- client_info->slave->dev->master->name);
+ ": Error: failed to create an ARP packet\n");
continue;
}
@@ -506,8 +523,7 @@ static void rlb_update_client(struct rlb_client_info *client_info)
skb = vlan_put_tag(skb, client_info->vlan_id);
if (!skb) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: failed to insert VLAN tag\n",
- client_info->slave->dev->master->name);
+ ": Error: failed to insert VLAN tag\n");
continue;
}
}
@@ -590,9 +606,8 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip)
if (!client_info->slave) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: found a client with no channel in "
- "the client's hash table\n",
- bond->dev->name);
+ ": Error: found a client with no channel in "
+ "the client's hash table\n");
continue;
}
/*update all clients using this src_ip, that are not assigned
@@ -782,22 +797,21 @@ static int rlb_initialize(struct bonding *bond)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type);
- struct rlb_client_info *new_hashtbl;
int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
int i;
spin_lock_init(&(bond_info->rx_hashtbl_lock));
- new_hashtbl = kmalloc(size, GFP_KERNEL);
- if (!new_hashtbl) {
+ _lock_rx_hashtbl(bond);
+
+ bond_info->rx_hashtbl = kmalloc(size, GFP_KERNEL);
+ if (!bond_info->rx_hashtbl) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: Failed to allocate RLB hash table\n",
+ ": Error: %s: Failed to allocate RLB hash table\n",
bond->dev->name);
+ _unlock_rx_hashtbl(bond);
return -1;
}
- _lock_rx_hashtbl(bond);
-
- bond_info->rx_hashtbl = new_hashtbl;
bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
@@ -913,8 +927,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
skb = vlan_put_tag(skb, vlan->vlan_id);
if (!skb) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: failed to insert VLAN tag\n",
- bond->dev->name);
+ ": Error: failed to insert VLAN tag\n");
continue;
}
}
@@ -943,11 +956,11 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
s_addr.sa_family = dev->type;
if (dev_set_mac_address(dev, &s_addr)) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: dev_set_mac_address of dev %s failed! ALB "
+ ": Error: dev_set_mac_address of dev %s failed! ALB "
"mode requires that the base driver support setting "
"the hw address also when the network device's "
"interface is open\n",
- dev->master->name, dev->name);
+ dev->name);
return -EOPNOTSUPP;
}
return 0;
@@ -1140,16 +1153,16 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
bond->alb_info.rlb_enabled);
printk(KERN_WARNING DRV_NAME
- ": %s: Warning: the hw address of slave %s is in use by "
+ ": Warning: the hw address of slave %s is in use by "
"the bond; giving it the hw address of %s\n",
- bond->dev->name, slave->dev->name, free_mac_slave->dev->name);
+ slave->dev->name, free_mac_slave->dev->name);
} else if (has_bond_addr) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: the hw address of slave %s is in use by the "
+ ": Error: the hw address of slave %s is in use by the "
"bond; couldn't find a slave with a free hw address to "
"give it (this should not have happened)\n",
- bond->dev->name, slave->dev->name);
+ slave->dev->name);
return -EFAULT;
}
@@ -1237,8 +1250,6 @@ int bond_alb_initialize(struct bonding *bond, int rlb_enabled)
tlb_deinitialize(bond);
return res;
}
- } else {
- bond->alb_info.rlb_enabled = 0;
}
return 0;
@@ -1398,7 +1409,7 @@ void bond_alb_monitor(struct bonding *bond)
read_lock(&bond->curr_slave_lock);
bond_for_each_slave(bond, slave, i) {
- alb_send_learning_packets(slave, slave->dev->dev_addr);
+ alb_send_learning_packets(slave,slave->dev->dev_addr);
}
read_unlock(&bond->curr_slave_lock);
diff --git a/trunk/drivers/net/bonding/bond_alb.h b/trunk/drivers/net/bonding/bond_alb.h
index 28f2a2fd1b5a..e4091cd8d654 100644
--- a/trunk/drivers/net/bonding/bond_alb.h
+++ b/trunk/drivers/net/bonding/bond_alb.h
@@ -18,6 +18,15 @@
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
+ *
+ * Changes:
+ *
+ * 2003/08/06 - Amir Noam
+ * - Add support for setting bond's MAC address with special
+ * handling required for ALB/TLB.
+ *
+ * 2003/12/01 - Shmulik Hen
+ * - Code cleanup and style changes
*/
#ifndef __BOND_ALB_H__
diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c
index 2582d98ef5c3..94cec3cf2a13 100644
--- a/trunk/drivers/net/bonding/bond_main.c
+++ b/trunk/drivers/net/bonding/bond_main.c
@@ -29,6 +29,466 @@
* b: if a hw mac address already is there, eth0's hw mac address
* will then be set from bond0.
*
+ * v0.1 - first working version.
+ * v0.2 - changed stats to be calculated by summing slaves stats.
+ *
+ * Changes:
+ * Arnaldo Carvalho de Melo
+ * - fix leaks on failure at bond_init
+ *
+ * 2000/09/30 - Willy Tarreau
+ * - added trivial code to release a slave device.
+ * - fixed security bug (CAP_NET_ADMIN not checked)
+ * - implemented MII link monitoring to disable dead links :
+ * All MII capable slaves are checked every milliseconds
+ * (100 ms seems good). This value can be changed by passing it to
+ * insmod. A value of zero disables the monitoring (default).
+ * - fixed an infinite loop in bond_xmit_roundrobin() when there's no
+ * good slave.
+ * - made the code hopefully SMP safe
+ *
+ * 2000/10/03 - Willy Tarreau
+ * - optimized slave lists based on relevant suggestions from Thomas Davis
+ * - implemented active-backup method to obtain HA with two switches:
+ * stay as long as possible on the same active interface, while we
+ * also monitor the backup one (MII link status) because we want to know
+ * if we are able to switch at any time. ( pass "mode=1" to insmod )
+ * - lots of stress testings because we need it to be more robust than the
+ * wires ! :->
+ *
+ * 2000/10/09 - Willy Tarreau
+ * - added up and down delays after link state change.
+ * - optimized the slaves chaining so that when we run forward, we never
+ * repass through the bond itself, but we can find it by searching
+ * backwards. Renders the deletion more difficult, but accelerates the
+ * scan.
+ * - smarter enslaving and releasing.
+ * - finer and more robust SMP locking
+ *
+ * 2000/10/17 - Willy Tarreau
+ * - fixed two potential SMP race conditions
+ *
+ * 2000/10/18 - Willy Tarreau
+ * - small fixes to the monitoring FSM in case of zero delays
+ * 2000/11/01 - Willy Tarreau
+ * - fixed first slave not automatically used in trunk mode.
+ * 2000/11/10 : spelling of "EtherChannel" corrected.
+ * 2000/11/13 : fixed a race condition in case of concurrent accesses to ioctl().
+ * 2000/12/16 : fixed improper usage of rtnl_exlock_nowait().
+ *
+ * 2001/1/3 - Chad N. Tindel
+ * - The bonding driver now simulates MII status monitoring, just like
+ * a normal network device. It will show that the link is down iff
+ * every slave in the bond shows that their links are down. If at least
+ * one slave is up, the bond's MII status will appear as up.
+ *
+ * 2001/2/7 - Chad N. Tindel
+ * - Applications can now query the bond from user space to get
+ * information which may be useful. They do this by calling
+ * the BOND_INFO_QUERY ioctl. Once the app knows how many slaves
+ * are in the bond, it can call the BOND_SLAVE_INFO_QUERY ioctl to
+ * get slave specific information (# link failures, etc). See
+ * for more details. The structs of interest
+ * are ifbond and ifslave.
+ *
+ * 2001/4/5 - Chad N. Tindel
+ * - Ported to 2.4 Kernel
+ *
+ * 2001/5/2 - Jeffrey E. Mast
+ * - When a device is detached from a bond, the slave device is no longer
+ * left thinking that is has a master.
+ *
+ * 2001/5/16 - Jeffrey E. Mast
+ * - memset did not appropriately initialized the bond rw_locks. Used
+ * rwlock_init to initialize to unlocked state to prevent deadlock when
+ * first attempting a lock
+ * - Called SET_MODULE_OWNER for bond device
+ *
+ * 2001/5/17 - Tim Anderson
+ * - 2 paths for releasing for slave release; 1 through ioctl
+ * and 2) through close. Both paths need to release the same way.
+ * - the free slave in bond release is changing slave status before
+ * the free. The netdev_set_master() is intended to change slave state
+ * so it should not be done as part of the release process.
+ * - Simple rule for slave state at release: only the active in A/B and
+ * only one in the trunked case.
+ *
+ * 2001/6/01 - Tim Anderson
+ * - Now call dev_close when releasing a slave so it doesn't screw up
+ * out routing table.
+ *
+ * 2001/6/01 - Chad N. Tindel
+ * - Added /proc support for getting bond and slave information.
+ * Information is in /proc/net//info.
+ * - Changed the locking when calling bond_close to prevent deadlock.
+ *
+ * 2001/8/05 - Janice Girouard
+ * - correct problem where refcnt of slave is not incremented in bond_ioctl
+ * so the system hangs when halting.
+ * - correct locking problem when unable to malloc in bond_enslave.
+ * - adding bond_xmit_xor logic.
+ * - adding multiple bond device support.
+ *
+ * 2001/8/13 - Erik Habbinga
+ * - correct locking problem with rtnl_exlock_nowait
+ *
+ * 2001/8/23 - Janice Girouard
+ * - bzero initial dev_bonds, to correct oops
+ * - convert SIOCDEVPRIVATE to new MII ioctl calls
+ *
+ * 2001/9/13 - Takao Indoh
+ * - Add the BOND_CHANGE_ACTIVE ioctl implementation
+ *
+ * 2001/9/14 - Mark Huth
+ * - Change MII_LINK_READY to not check for end of auto-negotiation,
+ * but only for an up link.
+ *
+ * 2001/9/20 - Chad N. Tindel
+ * - Add the device field to bonding_t. Previously the net_device
+ * corresponding to a bond wasn't available from the bonding_t
+ * structure.
+ *
+ * 2001/9/25 - Janice Girouard
+ * - add arp_monitor for active backup mode
+ *
+ * 2001/10/23 - Takao Indoh
+ * - Various memory leak fixes
+ *
+ * 2001/11/5 - Mark Huth
+ * - Don't take rtnl lock in bond_mii_monitor as it deadlocks under
+ * certain hotswap conditions.
+ * Note: this same change may be required in bond_arp_monitor ???
+ * - Remove possibility of calling bond_sethwaddr with NULL slave_dev ptr
+ * - Handle hot swap ethernet interface deregistration events to remove
+ * kernel oops following hot swap of enslaved interface
+ *
+ * 2002/1/2 - Chad N. Tindel
+ * - Restore original slave flags at release time.
+ *
+ * 2002/02/18 - Erik Habbinga
+ * - bond_release(): calling kfree on our_slave after call to
+ * bond_restore_slave_flags, not before
+ * - bond_enslave(): saving slave flags into original_flags before
+ * call to netdev_set_master, so the IFF_SLAVE flag doesn't end
+ * up in original_flags
+ *
+ * 2002/04/05 - Mark Smith and
+ * Steve Mead
+ * - Port Gleb Natapov's multicast support patchs from 2.4.12
+ * to 2.4.18 adding support for multicast.
+ *
+ * 2002/06/10 - Tony Cureington
+ * - corrected uninitialized pointer (ifr.ifr_data) in bond_check_dev_link;
+ * actually changed function to use MIIPHY, then MIIREG, and finally
+ * ETHTOOL to determine the link status
+ * - fixed bad ifr_data pointer assignments in bond_ioctl
+ * - corrected mode 1 being reported as active-backup in bond_get_info;
+ * also added text to distinguish type of load balancing (rr or xor)
+ * - change arp_ip_target module param from "1-12s" (array of 12 ptrs)
+ * to "s" (a single ptr)
+ *
+ * 2002/08/30 - Jay Vosburgh
+ * - Removed acquisition of xmit_lock in set_multicast_list; caused
+ * deadlock on SMP (lock is held by caller).
+ * - Revamped SIOCGMIIPHY, SIOCGMIIREG portion of bond_check_dev_link().
+ *
+ * 2002/09/18 - Jay Vosburgh
+ * - Fixed up bond_check_dev_link() (and callers): removed some magic
+ * numbers, banished local MII_ defines, wrapped ioctl calls to
+ * prevent EFAULT errors
+ *
+ * 2002/9/30 - Jay Vosburgh
+ * - make sure the ip target matches the arp_target before saving the
+ * hw address.
+ *
+ * 2002/9/30 - Dan Eisner
+ * - make sure my_ip is set before taking down the link, since
+ * not all switches respond if the source ip is not set.
+ *
+ * 2002/10/8 - Janice Girouard
+ * - read in the local ip address when enslaving a device
+ * - add primary support
+ * - make sure 2*arp_interval has passed when a new device
+ * is brought on-line before taking it down.
+ *
+ * 2002/09/11 - Philippe De Muyter
+ * - Added bond_xmit_broadcast logic.
+ * - Added bond_mode() support function.
+ *
+ * 2002/10/26 - Laurent Deniel
+ * - allow to register multicast addresses only on active slave
+ * (useful in active-backup mode)
+ * - add multicast module parameter
+ * - fix deletion of multicast groups after unloading module
+ *
+ * 2002/11/06 - Kameshwara Rayaprolu
+ * - Changes to prevent panic from closing the device twice; if we close
+ * the device in bond_release, we must set the original_flags to down
+ * so it won't be closed again by the network layer.
+ *
+ * 2002/11/07 - Tony Cureington
+ * - Fix arp_target_hw_addr memory leak
+ * - Created activebackup_arp_monitor function to handle arp monitoring
+ * in active backup mode - the bond_arp_monitor had several problems...
+ * such as allowing slaves to tx arps sequentially without any delay
+ * for a response
+ * - Renamed bond_arp_monitor to loadbalance_arp_monitor and re-wrote
+ * this function to just handle arp monitoring in load-balancing mode;
+ * it is a lot more compact now
+ * - Changes to ensure one and only one slave transmits in active-backup
+ * mode
+ * - Robustesize parameters; warn users about bad combinations of
+ * parameters; also if miimon is specified and a network driver does
+ * not support MII or ETHTOOL, inform the user of this
+ * - Changes to support link_failure_count when in arp monitoring mode
+ * - Fix up/down delay reported in /proc
+ * - Added version; log version; make version available from "modinfo -d"
+ * - Fixed problem in bond_check_dev_link - if the first IOCTL (SIOCGMIIPH)
+ * failed, the ETHTOOL ioctl never got a chance
+ *
+ * 2002/11/16 - Laurent Deniel
+ * - fix multicast handling in activebackup_arp_monitor
+ * - remove one unnecessary and confusing curr_active_slave == slave test
+ * in activebackup_arp_monitor
+ *
+ * 2002/11/17 - Laurent Deniel
+ * - fix bond_slave_info_query when slave_id = num_slaves
+ *
+ * 2002/11/19 - Janice Girouard
+ * - correct ifr_data reference. Update ifr_data reference
+ * to mii_ioctl_data struct values to avoid confusion.
+ *
+ * 2002/11/22 - Bert Barbe
+ * - Add support for multiple arp_ip_target
+ *
+ * 2002/12/13 - Jay Vosburgh
+ * - Changed to allow text strings for mode and multicast, e.g.,
+ * insmod bonding mode=active-backup. The numbers still work.
+ * One change: an invalid choice will cause module load failure,
+ * rather than the previous behavior of just picking one.
+ * - Minor cleanups; got rid of dup ctype stuff, atoi function
+ *
+ * 2003/02/07 - Jay Vosburgh
+ * - Added use_carrier module parameter that causes miimon to
+ * use netif_carrier_ok() test instead of MII/ETHTOOL ioctls.
+ * - Minor cleanups; consolidated ioctl calls to one function.
+ *
+ * 2003/02/07 - Tony Cureington
+ * - Fix bond_mii_monitor() logic error that could result in
+ * bonding round-robin mode ignoring links after failover/recovery
+ *
+ * 2003/03/17 - Jay Vosburgh
+ * - kmalloc fix (GFP_KERNEL to GFP_ATOMIC) reported by
+ * Shmulik dot Hen at intel.com.
+ * - Based on discussion on mailing list, changed use of
+ * update_slave_cnt(), created wrapper functions for adding/removing
+ * slaves, changed bond_xmit_xor() to check slave_cnt instead of
+ * checking slave and slave->dev (which only worked by accident).
+ * - Misc code cleanup: get arp_send() prototype from header file,
+ * add max_bonds to bonding.txt.
+ *
+ * 2003/03/18 - Tsippy Mendelson and
+ * Shmulik Hen
+ * - Make sure only bond_attach_slave() and bond_detach_slave() can
+ * manipulate the slave list, including slave_cnt, even when in
+ * bond_release_all().
+ * - Fixed hang in bond_release() with traffic running:
+ * netdev_set_master() must not be called from within the bond lock.
+ *
+ * 2003/03/18 - Tsippy Mendelson and
+ * Shmulik Hen
+ * - Fixed hang in bond_enslave() with traffic running:
+ * netdev_set_master() must not be called from within the bond lock.
+ *
+ * 2003/03/18 - Amir Noam
+ * - Added support for getting slave's speed and duplex via ethtool.
+ * Needed for 802.3ad and other future modes.
+ *
+ * 2003/03/18 - Tsippy Mendelson and
+ * Shmulik Hen
+ * - Enable support of modes that need to use the unique mac address of
+ * each slave.
+ * * bond_enslave(): Moved setting the slave's mac address, and
+ * openning it, from the application to the driver. This breaks
+ * backward comaptibility with old versions of ifenslave that open
+ * the slave before enalsving it !!!.
+ * * bond_release(): The driver also takes care of closing the slave
+ * and restoring its original mac address.
+ * - Removed the code that restores all base driver's flags.
+ * Flags are automatically restored once all undo stages are done
+ * properly.
+ * - Block possibility of enslaving before the master is up. This
+ * prevents putting the system in an unstable state.
+ *
+ * 2003/03/18 - Amir Noam ,
+ * Tsippy Mendelson and
+ * Shmulik Hen
+ * - Added support for IEEE 802.3ad Dynamic link aggregation mode.
+ *
+ * 2003/05/01 - Amir Noam
+ * - Added ABI version control to restore compatibility between
+ * new/old ifenslave and new/old bonding.
+ *
+ * 2003/05/01 - Shmulik Hen
+ * - Fixed bug in bond_release_all(): save old value of curr_active_slave
+ * before setting it to NULL.
+ * - Changed driver versioning scheme to include version number instead
+ * of release date (that is already in another field). There are 3
+ * fields X.Y.Z where:
+ * X - Major version - big behavior changes
+ * Y - Minor version - addition of features
+ * Z - Extra version - minor changes and bug fixes
+ * The current version is 1.0.0 as a base line.
+ *
+ * 2003/05/01 - Tsippy Mendelson and
+ * Amir Noam
+ * - Added support for lacp_rate module param.
+ * - Code beautification and style changes (mainly in comments).
+ * new version - 1.0.1
+ *
+ * 2003/05/01 - Shmulik Hen
+ * - Based on discussion on mailing list, changed locking scheme
+ * to use lock/unlock or lock_bh/unlock_bh appropriately instead
+ * of lock_irqsave/unlock_irqrestore. The new scheme helps exposing
+ * hidden bugs and solves system hangs that occurred due to the fact
+ * that holding lock_irqsave doesn't prevent softirqs from running.
+ * This also increases total throughput since interrupts are not
+ * blocked on each transmitted packets or monitor timeout.
+ * new version - 2.0.0
+ *
+ * 2003/05/01 - Shmulik Hen
+ * - Added support for Transmit load balancing mode.
+ * - Concentrate all assignments of curr_active_slave to a single point
+ * so specific modes can take actions when the primary adapter is
+ * changed.
+ * - Take the updelay parameter into consideration during bond_enslave
+ * since some adapters loose their link during setting the device.
+ * - Renamed bond_3ad_link_status_changed() to
+ * bond_3ad_handle_link_change() for compatibility with TLB.
+ * new version - 2.1.0
+ *
+ * 2003/05/01 - Tsippy Mendelson
+ * - Added support for Adaptive load balancing mode which is
+ * equivalent to Transmit load balancing + Receive load balancing.
+ * new version - 2.2.0
+ *
+ * 2003/05/15 - Jay Vosburgh
+ * - Applied fix to activebackup_arp_monitor posted to bonding-devel
+ * by Tony Cureington . Fixes ARP
+ * monitor endless failover bug. Version to 2.2.10
+ *
+ * 2003/05/20 - Amir Noam
+ * - Fixed bug in ABI version control - Don't commit to a specific
+ * ABI version if receiving unsupported ioctl commands.
+ *
+ * 2003/05/22 - Jay Vosburgh
+ * - Fix ifenslave -c causing bond to loose existing routes;
+ * added bond_set_mac_address() that doesn't require the
+ * bond to be down.
+ * - In conjunction with fix for ifenslave -c, in
+ * bond_change_active(), changing to the already active slave
+ * is no longer an error (it successfully does nothing).
+ *
+ * 2003/06/30 - Amir Noam
+ * - Fixed bond_change_active() for ALB/TLB modes.
+ * Version to 2.2.14.
+ *
+ * 2003/07/29 - Amir Noam
+ * - Fixed ARP monitoring bug.
+ * Version to 2.2.15.
+ *
+ * 2003/07/31 - Willy Tarreau
+ * - Fixed kernel panic when using ARP monitoring without
+ * setting bond's IP address.
+ * Version to 2.2.16.
+ *
+ * 2003/08/06 - Amir Noam
+ * - Back port from 2.6: use alloc_netdev(); fix /proc handling;
+ * made stats a part of bond struct so no need to allocate
+ * and free it separately; use standard list operations instead
+ * of pre-allocated array of bonds.
+ * Version to 2.3.0.
+ *
+ * 2003/08/07 - Jay Vosburgh ,
+ * Amir Noam and
+ * Shmulik Hen
+ * - Propagating master's settings: Distinguish between modes that
+ * use a primary slave from those that don't, and propagate settings
+ * accordingly; Consolidate change_active opeartions and add
+ * reselect_active and find_best opeartions; Decouple promiscuous
+ * handling from the multicast mode setting; Add support for changing
+ * HW address and MTU with proper unwind; Consolidate procfs code,
+ * add CHANGENAME handler; Enhance netdev notification handling.
+ * Version to 2.4.0.
+ *
+ * 2003/09/15 - Stephen Hemminger ,
+ * Amir Noam
+ * - Convert /proc to seq_file interface.
+ * Change /proc/net/bondX/info to /proc/net/bonding/bondX.
+ * Set version to 2.4.1.
+ *
+ * 2003/11/20 - Amir Noam
+ * - Fix /proc creation/destruction.
+ *
+ * 2003/12/01 - Shmulik Hen
+ * - Massive cleanup - Set version to 2.5.0
+ * Code changes:
+ * o Consolidate format of prints and debug prints.
+ * o Remove bonding_t/slave_t typedefs and consolidate all casts.
+ * o Remove dead code and unnecessary checks.
+ * o Consolidate starting/stopping timers.
+ * o Consolidate handling of primary module param throughout the code.
+ * o Removed multicast module param support - all settings are done
+ * according to mode.
+ * o Slave list iteration - bond is no longer part of the list,
+ * added cyclic list iteration macros.
+ * o Consolidate error handling in all xmit functions.
+ * Style changes:
+ * o Consolidate function naming and declarations.
+ * o Consolidate function params and local variables names.
+ * o Consolidate return values.
+ * o Consolidate curly braces.
+ * o Consolidate conditionals format.
+ * o Change struct member names and types.
+ * o Chomp trailing spaces, remove empty lines, fix indentations.
+ * o Re-organize code according to context.
+ *
+ * 2003/12/30 - Amir Noam
+ * - Fixed: Cannot remove and re-enslave the original active slave.
+ * - Fixed: Releasing the original active slave causes mac address
+ * duplication.
+ * - Add support for slaves that use ethtool_ops.
+ * Set version to 2.5.3.
+ *
+ * 2004/01/05 - Amir Noam
+ * - Save bonding parameters per bond instead of using the global values.
+ * Set version to 2.5.4.
+ *
+ * 2004/01/14 - Shmulik Hen
+ * - Enhance VLAN support:
+ * * Add support for VLAN hardware acceleration capable slaves.
+ * * Add capability to tag self generated packets in ALB/TLB modes.
+ * Set version to 2.6.0.
+ * 2004/10/29 - Mitch Williams
+ * - Fixed bug when unloading module while using 802.3ad. If
+ * spinlock debugging is turned on, this causes a stack dump.
+ * Solution is to move call to dev_remove_pack outside of the
+ * spinlock.
+ * Set version to 2.6.1.
+ * 2005/06/05 - Jay Vosburgh
+ * - Support for generating gratuitous ARPs in active-backup mode.
+ * Includes support for VLAN tagging all bonding-generated ARPs
+ * as needed. Set version to 2.6.2.
+ * 2005/06/08 - Jason Gabler
+ * - alternate hashing policy support for mode 2
+ * * Added kernel parameter "xmit_hash_policy" to allow the selection
+ * of different hashing policies for mode 2. The original mode 2
+ * policy is the default, now found in xmit_hash_policy_layer2().
+ * * Added xmit_hash_policy_layer34()
+ * - Modified by Jay Vosburgh to also support mode 4.
+ * Set version to 2.6.3.
+ * 2005/09/26 - Jay Vosburgh
+ * - Removed backwards compatibility for old ifenslaves. Version 2.6.4.
*/
//#define BONDING_DEBUG 1
@@ -97,7 +557,6 @@ static char *lacp_rate = NULL;
static char *xmit_hash_policy = NULL;
static int arp_interval = BOND_LINK_ARP_INTERV;
static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
-struct bond_params bonding_defaults;
module_param(max_bonds, int, 0);
MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
@@ -106,24 +565,17 @@ MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
module_param(updelay, int, 0);
MODULE_PARM_DESC(updelay, "Delay before considering link up, in milliseconds");
module_param(downdelay, int, 0);
-MODULE_PARM_DESC(downdelay, "Delay before considering link down, "
- "in milliseconds");
+MODULE_PARM_DESC(downdelay, "Delay before considering link down, in milliseconds");
module_param(use_carrier, int, 0);
-MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; "
- "0 for off, 1 for on (default)");
+MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 0 for off, 1 for on (default)");
module_param(mode, charp, 0);
-MODULE_PARM_DESC(mode, "Mode of operation : 0 for balance-rr, "
- "1 for active-backup, 2 for balance-xor, "
- "3 for broadcast, 4 for 802.3ad, 5 for balance-tlb, "
- "6 for balance-alb");
+MODULE_PARM_DESC(mode, "Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor");
module_param(primary, charp, 0);
MODULE_PARM_DESC(primary, "Primary network device to use");
module_param(lacp_rate, charp, 0);
-MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
- "(slow/fast)");
+MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)");
module_param(xmit_hash_policy, charp, 0);
-MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method: 0 for layer 2 (default)"
- ", 1 for layer 3+4");
+MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method : 0 for layer 2 (default), 1 for layer 3+4");
module_param(arp_interval, int, 0);
MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
module_param_array(arp_ip_target, charp, NULL, 0);
@@ -134,27 +586,30 @@ MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
static const char *version =
DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
-LIST_HEAD(bond_dev_list);
+static LIST_HEAD(bond_dev_list);
#ifdef CONFIG_PROC_FS
static struct proc_dir_entry *bond_proc_dir = NULL;
#endif
-extern struct rw_semaphore bonding_rwsem;
static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ;
static int arp_ip_count = 0;
static int bond_mode = BOND_MODE_ROUNDROBIN;
static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2;
static int lacp_fast = 0;
+struct bond_parm_tbl {
+ char *modename;
+ int mode;
+};
-struct bond_parm_tbl bond_lacp_tbl[] = {
+static struct bond_parm_tbl bond_lacp_tbl[] = {
{ "slow", AD_LACP_SLOW},
{ "fast", AD_LACP_FAST},
{ NULL, -1},
};
-struct bond_parm_tbl bond_mode_tbl[] = {
+static struct bond_parm_tbl bond_mode_tbl[] = {
{ "balance-rr", BOND_MODE_ROUNDROBIN},
{ "active-backup", BOND_MODE_ACTIVEBACKUP},
{ "balance-xor", BOND_MODE_XOR},
@@ -165,7 +620,7 @@ struct bond_parm_tbl bond_mode_tbl[] = {
{ NULL, -1},
};
-struct bond_parm_tbl xmit_hashtype_tbl[] = {
+static struct bond_parm_tbl xmit_hashtype_tbl[] = {
{ "layer2", BOND_XMIT_POLICY_LAYER2},
{ "layer3+4", BOND_XMIT_POLICY_LAYER34},
{ NULL, -1},
@@ -173,11 +628,12 @@ struct bond_parm_tbl xmit_hashtype_tbl[] = {
/*-------------------------- Forward declarations ---------------------------*/
+static inline void bond_set_mode_ops(struct bonding *bond, int mode);
static void bond_send_gratuitous_arp(struct bonding *bond);
/*---------------------------- General routines -----------------------------*/
-const char *bond_mode_name(int mode)
+static const char *bond_mode_name(int mode)
{
switch (mode) {
case BOND_MODE_ROUNDROBIN :
@@ -454,7 +910,7 @@ static void bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid)
res = bond_add_vlan(bond, vid);
if (res) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: Failed to add vlan id %d\n",
+ ": %s: Failed to add vlan id %d\n",
bond_dev->name, vid);
}
}
@@ -488,7 +944,7 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
res = bond_del_vlan(bond, vid);
if (res) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: Failed to remove vlan id %d\n",
+ ": %s: Failed to remove vlan id %d\n",
bond_dev->name, vid);
}
}
@@ -993,7 +1449,7 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
*
* Warning: Caller must hold curr_slave_lock for writing.
*/
-void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
+static void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
{
struct slave *old_active = bond->curr_active_slave;
@@ -1067,7 +1523,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
*
* Warning: Caller must hold curr_slave_lock for writing.
*/
-void bond_select_active_slave(struct bonding *bond)
+static void bond_select_active_slave(struct bonding *bond)
{
struct slave *best_slave;
@@ -1135,7 +1591,7 @@ static void bond_detach_slave(struct bonding *bond, struct slave *slave)
/*---------------------------------- IOCTL ----------------------------------*/
-int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
+static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
{
dprintk("bond_dev=%p\n", bond_dev);
dprintk("slave_dev=%p\n", slave_dev);
@@ -1175,7 +1631,7 @@ static int bond_compute_features(struct bonding *bond)
}
/* enslave device to bond device */
-int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
+static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
{
struct bonding *bond = bond_dev->priv;
struct slave *new_slave = NULL;
@@ -1188,8 +1644,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
slave_dev->do_ioctl == NULL) {
printk(KERN_WARNING DRV_NAME
- ": %s: Warning: no link monitoring support for %s\n",
- bond_dev->name, slave_dev->name);
+ ": Warning : no link monitoring support for %s\n",
+ slave_dev->name);
}
/* bond must be initialized by bond_open() before enslaving */
@@ -1210,17 +1666,17 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
dprintk("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
if (!list_empty(&bond->vlan_list)) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: cannot enslave VLAN "
+ ": Error: cannot enslave VLAN "
"challenged slave %s on VLAN enabled "
- "bond %s\n", bond_dev->name, slave_dev->name,
+ "bond %s\n", slave_dev->name,
bond_dev->name);
return -EPERM;
} else {
printk(KERN_WARNING DRV_NAME
- ": %s: Warning: enslaved VLAN challenged "
+ ": Warning: enslaved VLAN challenged "
"slave %s. Adding VLANs will be blocked as "
"long as %s is part of bond %s\n",
- bond_dev->name, slave_dev->name, slave_dev->name,
+ slave_dev->name, slave_dev->name,
bond_dev->name);
bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
}
@@ -1250,11 +1706,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (slave_dev->set_mac_address == NULL) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: The slave device you specified does "
- "not support setting the MAC address. "
- "Your kernel likely does not support slave "
- "devices.\n", bond_dev->name);
- res = -EOPNOTSUPP;
+ ": Error: The slave device you specified does "
+ "not support setting the MAC address.\n");
+ printk(KERN_ERR
+ "Your kernel likely does not support slave devices.\n");
+
+ res = -EOPNOTSUPP;
goto err_undo_flags;
}
@@ -1370,21 +1827,21 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
* the messages for netif_carrier.
*/
printk(KERN_WARNING DRV_NAME
- ": %s: Warning: MII and ETHTOOL support not "
+ ": Warning: MII and ETHTOOL support not "
"available for interface %s, and "
"arp_interval/arp_ip_target module parameters "
"not specified, thus bonding will not detect "
"link failures! see bonding.txt for details.\n",
- bond_dev->name, slave_dev->name);
+ slave_dev->name);
} else if (link_reporting == -1) {
/* unable get link status using mii/ethtool */
printk(KERN_WARNING DRV_NAME
- ": %s: Warning: can't get link status from "
+ ": Warning: can't get link status from "
"interface %s; the network driver associated "
"with this interface does not support MII or "
"ETHTOOL link status reporting, thus miimon "
"has no effect on this interface.\n",
- bond_dev->name, slave_dev->name);
+ slave_dev->name);
}
}
@@ -1411,15 +1868,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (bond_update_speed_duplex(new_slave) &&
(new_slave->link != BOND_LINK_DOWN)) {
printk(KERN_WARNING DRV_NAME
- ": %s: Warning: failed to get speed and duplex from %s, "
+ ": Warning: failed to get speed and duplex from %s, "
"assumed to be 100Mb/sec and Full.\n",
- bond_dev->name, new_slave->dev->name);
+ new_slave->dev->name);
if (bond->params.mode == BOND_MODE_8023AD) {
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: Operation of 802.3ad mode requires ETHTOOL "
+ printk(KERN_WARNING
+ "Operation of 802.3ad mode requires ETHTOOL "
"support in base driver for proper aggregator "
- "selection.\n", bond_dev->name);
+ "selection.\n");
}
}
@@ -1501,10 +1958,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
write_unlock_bh(&bond->lock);
- res = bond_create_slave_symlinks(bond_dev, slave_dev);
- if (res)
- goto err_unset_master;
-
printk(KERN_INFO DRV_NAME
": %s: enslaving %s as a%s interface with a%s link.\n",
bond_dev->name, slave_dev->name,
@@ -1546,7 +1999,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
* for Bonded connections:
* The first up interface should be left on and all others downed.
*/
-int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
+static int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
{
struct bonding *bond = bond_dev->priv;
struct slave *slave, *oldcurrent;
@@ -1557,7 +2010,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
if (!(slave_dev->flags & IFF_SLAVE) ||
(slave_dev->master != bond_dev)) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: cannot release %s.\n",
+ ": Error: %s: cannot release %s.\n",
bond_dev->name, slave_dev->name);
return -EINVAL;
}
@@ -1578,12 +2031,11 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
ETH_ALEN);
if (!mac_addr_differ && (bond->slave_cnt > 1)) {
printk(KERN_WARNING DRV_NAME
- ": %s: Warning: the permanent HWaddr of %s "
+ ": Warning: the permanent HWaddr of %s "
"- %02X:%02X:%02X:%02X:%02X:%02X - is "
"still in use by %s. Set the HWaddr of "
"%s to a different address to avoid "
"conflicts.\n",
- bond_dev->name,
slave_dev->name,
slave->perm_hwaddr[0],
slave->perm_hwaddr[1],
@@ -1659,28 +2111,24 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
} else {
printk(KERN_WARNING DRV_NAME
- ": %s: Warning: clearing HW address of %s while it "
+ ": Warning: clearing HW address of %s while it "
"still has VLANs.\n",
- bond_dev->name, bond_dev->name);
- printk(KERN_WARNING DRV_NAME
- ": %s: When re-adding slaves, make sure the bond's "
- "HW address matches its VLANs'.\n",
bond_dev->name);
+ printk(KERN_WARNING DRV_NAME
+ ": When re-adding slaves, make sure the bond's "
+ "HW address matches its VLANs'.\n");
}
} else if ((bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
!bond_has_challenged_slaves(bond)) {
printk(KERN_INFO DRV_NAME
- ": %s: last VLAN challenged slave %s "
+ ": last VLAN challenged slave %s "
"left bond %s. VLAN blocking is removed\n",
- bond_dev->name, slave_dev->name, bond_dev->name);
+ slave_dev->name, bond_dev->name);
bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
}
write_unlock_bh(&bond->lock);
- /* must do this from outside any spinlocks */
- bond_destroy_slave_symlinks(bond_dev, slave_dev);
-
bond_del_vlans_from_slave(bond, slave_dev);
/* If the mode USES_PRIMARY, then we should only remove its
@@ -1772,7 +2220,6 @@ static int bond_release_all(struct net_device *bond_dev)
*/
write_unlock_bh(&bond->lock);
- bond_destroy_slave_symlinks(bond_dev, slave_dev);
bond_del_vlans_from_slave(bond, slave_dev);
/* If the mode USES_PRIMARY, then we should only remove its
@@ -1827,13 +2274,12 @@ static int bond_release_all(struct net_device *bond_dev)
bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
} else {
printk(KERN_WARNING DRV_NAME
- ": %s: Warning: clearing HW address of %s while it "
+ ": Warning: clearing HW address of %s while it "
"still has VLANs.\n",
- bond_dev->name, bond_dev->name);
- printk(KERN_WARNING DRV_NAME
- ": %s: When re-adding slaves, make sure the bond's "
- "HW address matches its VLANs'.\n",
bond_dev->name);
+ printk(KERN_WARNING DRV_NAME
+ ": When re-adding slaves, make sure the bond's "
+ "HW address matches its VLANs'.\n");
}
printk(KERN_INFO DRV_NAME
@@ -1951,7 +2397,7 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
/*-------------------------------- Monitoring -------------------------------*/
/* this function is called regularly to monitor each slave's link. */
-void bond_mii_monitor(struct net_device *bond_dev)
+static void bond_mii_monitor(struct net_device *bond_dev)
{
struct bonding *bond = bond_dev->priv;
struct slave *slave, *oldcurrent;
@@ -2150,11 +2596,8 @@ void bond_mii_monitor(struct net_device *bond_dev)
break;
default:
/* Should not happen */
- printk(KERN_ERR DRV_NAME
- ": %s: Error: %s Illegal value (link=%d)\n",
- bond_dev->name,
- slave->dev->name,
- slave->link);
+ printk(KERN_ERR "bonding: Error: %s Illegal value (link=%d)\n",
+ slave->dev->name, slave->link);
goto out;
} /* end of switch (slave->link) */
@@ -2278,9 +2721,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
struct flowi fl;
struct rtable *rt;
- for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
- if (!targets[i])
- continue;
+ for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) {
dprintk("basa: target %x\n", targets[i]);
if (list_empty(&bond->vlan_list)) {
dprintk("basa: empty vlan: arp_send\n");
@@ -2384,7 +2825,7 @@ static void bond_send_gratuitous_arp(struct bonding *bond)
* arp is transmitted to generate traffic. see activebackup_arp_monitor for
* arp monitoring in active backup mode.
*/
-void bond_loadbalance_arp_mon(struct net_device *bond_dev)
+static void bond_loadbalance_arp_mon(struct net_device *bond_dev)
{
struct bonding *bond = bond_dev->priv;
struct slave *slave, *oldcurrent;
@@ -2522,7 +2963,7 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev)
* may have received.
* see loadbalance_arp_monitor for arp monitoring in load balancing mode
*/
-void bond_activebackup_arp_mon(struct net_device *bond_dev)
+static void bond_activebackup_arp_mon(struct net_device *bond_dev)
{
struct bonding *bond = bond_dev->priv;
struct slave *slave;
@@ -2808,8 +3249,6 @@ static void bond_info_show_master(struct seq_file *seq)
{
struct bonding *bond = seq->private;
struct slave *curr;
- int i;
- u32 target;
read_lock(&bond->curr_slave_lock);
curr = bond->curr_active_slave;
@@ -2818,17 +3257,10 @@ static void bond_info_show_master(struct seq_file *seq)
seq_printf(seq, "Bonding Mode: %s\n",
bond_mode_name(bond->params.mode));
- if (bond->params.mode == BOND_MODE_XOR ||
- bond->params.mode == BOND_MODE_8023AD) {
- seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
- xmit_hashtype_tbl[bond->params.xmit_policy].modename,
- bond->params.xmit_policy);
- }
-
if (USES_PRIMARY(bond->params.mode)) {
seq_printf(seq, "Primary Slave: %s\n",
- (bond->primary_slave) ?
- bond->primary_slave->dev->name : "None");
+ (bond->params.primary[0]) ?
+ bond->params.primary : "None");
seq_printf(seq, "Currently Active Slave: %s\n",
(curr) ? curr->dev->name : "None");
@@ -2841,27 +3273,6 @@ static void bond_info_show_master(struct seq_file *seq)
seq_printf(seq, "Down Delay (ms): %d\n",
bond->params.downdelay * bond->params.miimon);
-
- /* ARP information */
- if(bond->params.arp_interval > 0) {
- int printed=0;
- seq_printf(seq, "ARP Polling Interval (ms): %d\n",
- bond->params.arp_interval);
-
- seq_printf(seq, "ARP IP target/s (n.n.n.n form):");
-
- for(i = 0; (i < BOND_MAX_ARP_TARGETS) ;i++) {
- if (!bond->params.arp_targets[i])
- continue;
- if (printed)
- seq_printf(seq, ",");
- target = ntohl(bond->params.arp_targets[i]);
- seq_printf(seq, " %d.%d.%d.%d", HIPQUAD(target));
- printed = 1;
- }
- seq_printf(seq, "\n");
- }
-
if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info;
@@ -3067,10 +3478,7 @@ static int bond_event_changename(struct bonding *bond)
bond_remove_proc_entry(bond);
bond_create_proc_entry(bond);
#endif
- down_write(&(bonding_rwsem));
- bond_destroy_sysfs_entry(bond);
- bond_create_sysfs_entry(bond);
- up_write(&(bonding_rwsem));
+
return NOTIFY_DONE;
}
@@ -3547,7 +3955,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
return -EPERM;
}
- down_write(&(bonding_rwsem));
slave_dev = dev_get_by_name(ifr->ifr_slave);
dprintk("slave_dev=%p: \n", slave_dev);
@@ -3580,7 +3987,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
dev_put(slave_dev);
}
- up_write(&(bonding_rwsem));
return res;
}
@@ -3665,7 +4071,6 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
bond_for_each_slave(bond, slave, i) {
dprintk("s %p s->p %p c_m %p\n", slave,
slave->prev, slave->dev->change_mtu);
-
res = dev_set_mtu(slave->dev, new_mtu);
if (res) {
@@ -3992,9 +4397,8 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
if (!skb2) {
printk(KERN_ERR DRV_NAME
- ": %s: Error: bond_xmit_broadcast(): "
- "skb_clone() failed\n",
- bond_dev->name);
+ ": Error: bond_xmit_broadcast(): "
+ "skb_clone() failed\n");
continue;
}
@@ -4027,7 +4431,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
/*
* set bond mode specific net device operations
*/
-void bond_set_mode_ops(struct bonding *bond, int mode)
+static inline void bond_set_mode_ops(struct bonding *bond, int mode)
{
struct net_device *bond_dev = bond->dev;
@@ -4063,8 +4467,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
default:
/* Should never happen, mode already checked */
printk(KERN_ERR DRV_NAME
- ": %s: Error: Unknown bonding mode %d\n",
- bond_dev->name,
+ ": Error: Unknown bonding mode %d\n",
mode);
break;
}
@@ -4088,7 +4491,7 @@ static struct ethtool_ops bond_ethtool_ops = {
* Does not allocate but creates a /proc entry.
* Allowed to fail.
*/
-static int bond_init(struct net_device *bond_dev, struct bond_params *params)
+static int __init bond_init(struct net_device *bond_dev, struct bond_params *params)
{
struct bonding *bond = bond_dev->priv;
@@ -4162,7 +4565,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
/* De-initialize device specific data.
* Caller must hold rtnl_lock.
*/
-void bond_deinit(struct net_device *bond_dev)
+static inline void bond_deinit(struct net_device *bond_dev)
{
struct bonding *bond = bond_dev->priv;
@@ -4198,7 +4601,7 @@ static void bond_free_all(void)
* Convert string input module parms. Accept either the
* number of the mode or its string name.
*/
-int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
+static inline int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
{
int i;
@@ -4267,7 +4670,7 @@ static int bond_check_params(struct bond_params *params)
if (max_bonds < 1 || max_bonds > INT_MAX) {
printk(KERN_WARNING DRV_NAME
": Warning: max_bonds (%d) not in range %d-%d, so it "
- "was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
+ "was reset to BOND_DEFAULT_MAX_BONDS (%d)",
max_bonds, 1, INT_MAX, BOND_DEFAULT_MAX_BONDS);
max_bonds = BOND_DEFAULT_MAX_BONDS;
}
@@ -4478,96 +4881,81 @@ static int bond_check_params(struct bond_params *params)
return 0;
}
-/* Create a new bond based on the specified name and bonding parameters.
- * Caller must NOT hold rtnl_lock; we need to release it here before we
- * set up our sysfs entries.
- */
-int bond_create(char *name, struct bond_params *params, struct bonding **newbond)
-{
- struct net_device *bond_dev;
- int res;
-
- rtnl_lock();
- bond_dev = alloc_netdev(sizeof(struct bonding), name, ether_setup);
- if (!bond_dev) {
- printk(KERN_ERR DRV_NAME
- ": %s: eek! can't alloc netdev!\n",
- name);
- res = -ENOMEM;
- goto out_rtnl;
- }
-
- /* bond_init() must be called after dev_alloc_name() (for the
- * /proc files), but before register_netdevice(), because we
- * need to set function pointers.
- */
-
- res = bond_init(bond_dev, params);
- if (res < 0) {
- goto out_netdev;
- }
-
- SET_MODULE_OWNER(bond_dev);
-
- res = register_netdevice(bond_dev);
- if (res < 0) {
- goto out_bond;
- }
- if (newbond)
- *newbond = bond_dev->priv;
-
- rtnl_unlock(); /* allows sysfs registration of net device */
- res = bond_create_sysfs_entry(bond_dev->priv);
- goto done;
-out_bond:
- bond_deinit(bond_dev);
-out_netdev:
- free_netdev(bond_dev);
-out_rtnl:
- rtnl_unlock();
-done:
- return res;
-}
-
static int __init bonding_init(void)
{
+ struct bond_params params;
int i;
int res;
- char new_bond_name[8]; /* Enough room for 999 bonds at init. */
printk(KERN_INFO "%s", version);
- res = bond_check_params(&bonding_defaults);
+ res = bond_check_params(¶ms);
if (res) {
- goto out;
+ return res;
}
+ rtnl_lock();
+
#ifdef CONFIG_PROC_FS
bond_create_proc_dir();
#endif
+
for (i = 0; i < max_bonds; i++) {
- sprintf(new_bond_name, "bond%d",i);
- res = bond_create(new_bond_name,&bonding_defaults, NULL);
- if (res)
- goto err;
- }
+ struct net_device *bond_dev;
- res = bond_create_sysfs();
- if (res)
- goto err;
+ bond_dev = alloc_netdev(sizeof(struct bonding), "", ether_setup);
+ if (!bond_dev) {
+ res = -ENOMEM;
+ goto out_err;
+ }
+ res = dev_alloc_name(bond_dev, "bond%d");
+ if (res < 0) {
+ free_netdev(bond_dev);
+ goto out_err;
+ }
+
+ /* bond_init() must be called after dev_alloc_name() (for the
+ * /proc files), but before register_netdevice(), because we
+ * need to set function pointers.
+ */
+ res = bond_init(bond_dev, ¶ms);
+ if (res < 0) {
+ free_netdev(bond_dev);
+ goto out_err;
+ }
+
+ SET_MODULE_OWNER(bond_dev);
+
+ res = register_netdevice(bond_dev);
+ if (res < 0) {
+ bond_deinit(bond_dev);
+ free_netdev(bond_dev);
+ goto out_err;
+ }
+ }
+
+ rtnl_unlock();
register_netdevice_notifier(&bond_netdev_notifier);
register_inetaddr_notifier(&bond_inetaddr_notifier);
- goto out;
-err:
+ return 0;
+
+out_err:
+ /*
+ * rtnl_unlock() will run netdev_run_todo(), putting the
+ * thus-far-registered bonding devices into a state which
+ * unregigister_netdevice() will accept
+ */
+ rtnl_unlock();
rtnl_lock();
+
+ /* free and unregister all bonds that were successfully added */
bond_free_all();
- bond_destroy_sysfs();
+
rtnl_unlock();
-out:
- return res;
+ return res;
}
static void __exit bonding_exit(void)
@@ -4577,7 +4965,6 @@ static void __exit bonding_exit(void)
rtnl_lock();
bond_free_all();
- bond_destroy_sysfs();
rtnl_unlock();
}
diff --git a/trunk/drivers/net/bonding/bond_sysfs.c b/trunk/drivers/net/bonding/bond_sysfs.c
deleted file mode 100644
index 32d13da43a0b..000000000000
--- a/trunk/drivers/net/bonding/bond_sysfs.c
+++ /dev/null
@@ -1,1358 +0,0 @@
-
-/*
- * Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include